diff options
Diffstat (limited to 'mesalib/src/glsl')
79 files changed, 60476 insertions, 63581 deletions
diff --git a/mesalib/src/glsl/Makefile b/mesalib/src/glsl/Makefile index 47ac42667..b8ed5ae88 100644 --- a/mesalib/src/glsl/Makefile +++ b/mesalib/src/glsl/Makefile @@ -1,184 +1,186 @@ -#src/glsl/pp/Makefile - -TOP = ../.. - -include $(TOP)/configs/current - -LIBNAME = glsl - -LIBGLCPP_SOURCES = \ - glcpp/glcpp-lex.c \ - glcpp/glcpp-parse.c \ - glcpp/pp.c - -GLCPP_SOURCES = \ - $(LIBGLCPP_SOURCES) \ - glcpp/glcpp.c - -C_SOURCES = \ - $(LIBGLCPP_SOURCES) - -CXX_SOURCES = \ - ast_expr.cpp \ - ast_function.cpp \ - ast_to_hir.cpp \ - ast_type.cpp \ - builtin_function.cpp \ - glsl_lexer.cpp \ - glsl_parser.cpp \ - glsl_parser_extras.cpp \ - glsl_types.cpp \ - glsl_symbol_table.cpp \ - hir_field_selection.cpp \ - ir_algebraic.cpp \ - ir_basic_block.cpp \ - ir_clone.cpp \ - ir_constant_expression.cpp \ - ir_constant_folding.cpp \ - ir_constant_propagation.cpp \ - ir_constant_variable.cpp \ - ir_copy_propagation.cpp \ - ir.cpp \ - ir_dead_code.cpp \ - ir_dead_code_local.cpp \ - ir_dead_functions.cpp \ - ir_div_to_mul_rcp.cpp \ - ir_explog_to_explog2.cpp \ - ir_expression_flattening.cpp \ - ir_function_can_inline.cpp \ - ir_function.cpp \ - ir_function_inlining.cpp \ - ir_hierarchical_visitor.cpp \ - ir_hv_accept.cpp \ - ir_if_simplification.cpp \ - ir_if_to_cond_assign.cpp \ - ir_import_prototypes.cpp \ - ir_lower_jumps.cpp \ - ir_mat_op_to_vec.cpp \ - ir_mod_to_fract.cpp \ - ir_noop_swizzle.cpp \ - ir_print_visitor.cpp \ - ir_reader.cpp \ - ir_rvalue_visitor.cpp \ - ir_set_program_inouts.cpp \ - ir_structure_splitting.cpp \ - ir_sub_to_add_neg.cpp \ - ir_swizzle_swizzle.cpp \ - ir_tree_grafting.cpp \ - ir_validate.cpp \ - ir_variable.cpp \ - ir_variable_refcount.cpp \ - ir_vec_index_to_cond_assign.cpp \ - ir_vec_index_to_swizzle.cpp \ - linker.cpp \ - link_functions.cpp \ - loop_analysis.cpp \ - loop_controls.cpp \ - loop_unroll.cpp \ - lower_noise.cpp \ - lower_variable_index_to_cond_assign.cpp \ - opt_redundant_jumps.cpp \ - s_expression.cpp - -LIBS = \ - $(TOP)/src/glsl/libglsl.a \ - $(TALLOC_LIBS) - -APPS = glsl_compiler glcpp/glcpp - -GLSL2_C_SOURCES = \ - ../mesa/program/hash_table.c \ - ../mesa/program/symbol_table.c -GLSL2_CXX_SOURCES = \ - main.cpp - -GLSL2_OBJECTS = \ - $(GLSL2_C_SOURCES:.c=.o) \ - $(GLSL2_CXX_SOURCES:.cpp=.o) - -### Basic defines ### - -DEFINES += \ - $(LIBRARY_DEFINES) \ - $(API_DEFINES) - -GLCPP_OBJECTS = \ - $(GLCPP_SOURCES:.c=.o) \ - ../mesa/program/hash_table.o - -OBJECTS = \ - $(C_SOURCES:.c=.o) \ - $(CXX_SOURCES:.cpp=.o) - -INCLUDES = \ - $(TALLOC_CFLAGS) \ - -I. \ - -I../mesa \ - -I../mapi \ - -I../../include \ - $(LIBRARY_INCLUDES) - -ALL_SOURCES = \ - $(C_SOURCES) \ - $(CXX_SOURCES) \ - $(GLSL2_CXX_SOURCES) \ - $(GLSL2_C_SOURCES) - -##### TARGETS ##### - -default: depend lib$(LIBNAME).a $(APPS) - -lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/glsl/Makefile.template - $(MKLIB) -cplusplus -o $(LIBNAME) -static $(OBJECTS) - -depend: $(ALL_SOURCES) Makefile - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(ALL_SOURCES) 2> /dev/null - -# Remove .o and backup files -clean: - rm -f $(GLCPP_OBJECTS) $(GLSL2_OBJECTS) $(OBJECTS) lib$(LIBNAME).a depend depend.bak - -rm -f $(APPS) - -# Dummy target -install: - @echo -n "" - - -##### RULES ##### - -glsl_compiler: $(GLSL2_OBJECTS) libglsl.a - $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLSL2_OBJECTS) $(LIBS) -o $@ - -glcpp/glcpp: $(GLCPP_OBJECTS) libglsl.a - $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLCPP_OBJECTS) $(LIBS) -o $@ - -.cpp.o: - $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< -o $@ - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ - -glsl_lexer.cpp: glsl_lexer.lpp - flex --nounistd -o$@ $< - -glsl_parser.cpp: glsl_parser.ypp - bison -v -o "$@" -p "_mesa_glsl_" --defines=glsl_parser.h $< - -glcpp/glcpp-lex.c: glcpp/glcpp-lex.l - flex --nounistd -o$@ $< - -glcpp/glcpp-parse.c: glcpp/glcpp-parse.y - bison -v -o "$@" --defines=glcpp/glcpp-parse.h $< - -builtins: builtin_function.cpp builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py - @echo Bootstrapping the compiler... - cp builtins/tools/builtin_function.cpp . - make glsl_compiler - @echo Regenerating builtin_function.cpp... - ./builtins/tools/generate_builtins.py > builtin_function.cpp - @echo Rebuilding the real compiler... - make glsl_compiler - --include depend +#src/glsl/pp/Makefile
+
+TOP = ../..
+
+include $(TOP)/configs/current
+
+LIBNAME = glsl
+
+LIBGLCPP_SOURCES = \
+ glcpp/glcpp-lex.c \
+ glcpp/glcpp-parse.c \
+ glcpp/pp.c
+
+GLCPP_SOURCES = \
+ $(LIBGLCPP_SOURCES) \
+ glcpp/glcpp.c
+
+C_SOURCES = \
+ strtod.c \
+ $(LIBGLCPP_SOURCES)
+
+CXX_SOURCES = \
+ ast_expr.cpp \
+ ast_function.cpp \
+ ast_to_hir.cpp \
+ ast_type.cpp \
+ builtin_function.cpp \
+ glsl_lexer.cpp \
+ glsl_parser.cpp \
+ glsl_parser_extras.cpp \
+ glsl_types.cpp \
+ glsl_symbol_table.cpp \
+ hir_field_selection.cpp \
+ ir_basic_block.cpp \
+ ir_clone.cpp \
+ ir_constant_expression.cpp \
+ ir.cpp \
+ ir_expression_flattening.cpp \
+ ir_function_can_inline.cpp \
+ ir_function.cpp \
+ ir_hierarchical_visitor.cpp \
+ ir_hv_accept.cpp \
+ ir_import_prototypes.cpp \
+ ir_print_visitor.cpp \
+ ir_reader.cpp \
+ ir_rvalue_visitor.cpp \
+ ir_set_program_inouts.cpp \
+ ir_validate.cpp \
+ ir_variable.cpp \
+ ir_variable_refcount.cpp \
+ linker.cpp \
+ link_functions.cpp \
+ loop_analysis.cpp \
+ loop_controls.cpp \
+ loop_unroll.cpp \
+ lower_discard.cpp \
+ lower_if_to_cond_assign.cpp \
+ lower_instructions.cpp \
+ lower_jumps.cpp \
+ lower_mat_op_to_vec.cpp \
+ lower_noise.cpp \
+ lower_texture_projection.cpp \
+ lower_variable_index_to_cond_assign.cpp \
+ lower_vec_index_to_cond_assign.cpp \
+ lower_vec_index_to_swizzle.cpp \
+ lower_vector.cpp \
+ opt_algebraic.cpp \
+ opt_constant_folding.cpp \
+ opt_constant_propagation.cpp \
+ opt_constant_variable.cpp \
+ opt_copy_propagation.cpp \
+ opt_dead_code.cpp \
+ opt_dead_code_local.cpp \
+ opt_dead_functions.cpp \
+ opt_discard_simplification.cpp \
+ opt_function_inlining.cpp \
+ opt_if_simplification.cpp \
+ opt_noop_swizzle.cpp \
+ opt_redundant_jumps.cpp \
+ opt_structure_splitting.cpp \
+ opt_swizzle_swizzle.cpp \
+ opt_tree_grafting.cpp \
+ s_expression.cpp
+
+LIBS = \
+ $(TOP)/src/glsl/libglsl.a \
+ $(TALLOC_LIBS)
+
+APPS = glsl_compiler glcpp/glcpp
+
+GLSL2_C_SOURCES = \
+ ../mesa/program/hash_table.c \
+ ../mesa/program/symbol_table.c
+GLSL2_CXX_SOURCES = \
+ main.cpp
+
+GLSL2_OBJECTS = \
+ $(GLSL2_C_SOURCES:.c=.o) \
+ $(GLSL2_CXX_SOURCES:.cpp=.o)
+
+### Basic defines ###
+
+DEFINES += \
+ $(LIBRARY_DEFINES) \
+ $(API_DEFINES)
+
+GLCPP_OBJECTS = \
+ $(GLCPP_SOURCES:.c=.o) \
+ ../mesa/program/hash_table.o
+
+OBJECTS = \
+ $(C_SOURCES:.c=.o) \
+ $(CXX_SOURCES:.cpp=.o)
+
+INCLUDES = \
+ $(TALLOC_CFLAGS) \
+ -I. \
+ -I../mesa \
+ -I../mapi \
+ -I../../include \
+ $(LIBRARY_INCLUDES)
+
+ALL_SOURCES = \
+ $(C_SOURCES) \
+ $(CXX_SOURCES) \
+ $(GLSL2_CXX_SOURCES) \
+ $(GLSL2_C_SOURCES)
+
+##### TARGETS #####
+
+default: depend lib$(LIBNAME).a $(APPS)
+
+lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/glsl/Makefile.template
+ $(MKLIB) -cplusplus -o $(LIBNAME) -static $(OBJECTS)
+
+depend: $(ALL_SOURCES) Makefile
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(ALL_SOURCES) 2> /dev/null
+
+# Remove .o and backup files
+clean:
+ rm -f $(GLCPP_OBJECTS) $(GLSL2_OBJECTS) $(OBJECTS) lib$(LIBNAME).a depend depend.bak
+ -rm -f $(APPS)
+
+# Dummy target
+install:
+ @echo -n ""
+
+
+##### RULES #####
+
+glsl_compiler: $(GLSL2_OBJECTS) libglsl.a
+ $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLSL2_OBJECTS) $(LIBS) -o $@
+
+glcpp/glcpp: $(GLCPP_OBJECTS) libglsl.a
+ $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLCPP_OBJECTS) $(LIBS) -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< -o $@
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+glsl_lexer.cpp: glsl_lexer.lpp
+ flex --nounistd -o$@ $<
+
+glsl_parser.cpp: glsl_parser.ypp
+ bison -v -o "$@" -p "_mesa_glsl_" --defines=glsl_parser.h $<
+
+glcpp/glcpp-lex.c: glcpp/glcpp-lex.l
+ flex --nounistd -o$@ $<
+
+glcpp/glcpp-parse.c: glcpp/glcpp-parse.y
+ bison -v -o "$@" --defines=glcpp/glcpp-parse.h $<
+
+builtins: builtin_function.cpp builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py
+ @echo Bootstrapping the compiler...
+ cp builtins/tools/builtin_function.cpp .
+ make glsl_compiler
+ @echo Regenerating builtin_function.cpp...
+ $(PYTHON2) $(PYTHON_FLAGS) builtins/tools/generate_builtins.py > builtin_function.cpp
+ @echo Rebuilding the real compiler...
+ make glsl_compiler
+
+-include depend
diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript index c183e208d..03a8b4cf5 100644 --- a/mesalib/src/glsl/SConscript +++ b/mesalib/src/glsl/SConscript @@ -1,110 +1,111 @@ -import common - -Import('*') - -env = env.Clone() - -env.Prepend(CPPPATH = [ - '#src/mapi', - '#src/mesa', -]) - -if env['platform'] == 'windows': - env.Prepend(CPPPATH = ['#src/talloc']) - -sources = [ - 'glcpp/glcpp-lex.c', - 'glcpp/glcpp-parse.c', - 'glcpp/pp.c', - 'ast_expr.cpp', - 'ast_function.cpp', - 'ast_to_hir.cpp', - 'ast_type.cpp', - 'builtin_function.cpp', - 'glsl_lexer.cpp', - 'glsl_parser.cpp', - 'glsl_parser_extras.cpp', - 'glsl_types.cpp', - 'glsl_symbol_table.cpp', - 'hir_field_selection.cpp', - 'ir_algebraic.cpp', - 'ir_basic_block.cpp', - 'ir_clone.cpp', - 'ir_constant_expression.cpp', - 'ir_constant_folding.cpp', - 'ir_constant_propagation.cpp', - 'ir_constant_variable.cpp', - 'ir_copy_propagation.cpp', - 'ir.cpp', - 'ir_dead_code.cpp', - 'ir_dead_code_local.cpp', - 'ir_dead_functions.cpp', - 'ir_div_to_mul_rcp.cpp', - 'ir_explog_to_explog2.cpp', - 'ir_expression_flattening.cpp', - 'ir_function_can_inline.cpp', - 'ir_function.cpp', - 'ir_function_inlining.cpp', - 'ir_hierarchical_visitor.cpp', - 'ir_hv_accept.cpp', - 'ir_if_simplification.cpp', - 'ir_if_to_cond_assign.cpp', - 'ir_import_prototypes.cpp', - 'ir_lower_jumps.cpp', - 'ir_mat_op_to_vec.cpp', - 'ir_mod_to_fract.cpp', - 'ir_noop_swizzle.cpp', - 'ir_print_visitor.cpp', - 'ir_reader.cpp', - 'ir_rvalue_visitor.cpp', - 'ir_set_program_inouts.cpp', - 'ir_structure_splitting.cpp', - 'ir_sub_to_add_neg.cpp', - 'ir_swizzle_swizzle.cpp', - 'ir_tree_grafting.cpp', - 'ir_validate.cpp', - 'ir_variable.cpp', - 'ir_variable_refcount.cpp', - 'ir_vec_index_to_cond_assign.cpp', - 'ir_vec_index_to_swizzle.cpp', - 'linker.cpp', - 'link_functions.cpp', - 'loop_analysis.cpp', - 'loop_controls.cpp', - 'loop_unroll.cpp', - 'lower_noise.cpp', - 'lower_variable_index_to_cond_assign.cpp', - 'opt_redundant_jumps.cpp', - 's_expression.cpp', -] - -glsl = env.ConvenienceLibrary( - target = 'glsl', - source = sources, -) - -Export('glsl') - -# FIXME: We can't build the programs because there's a cyclic dependency between tis directory and src/mesa -Return() - -env = env.Clone() - -if env['platform'] == 'windows': - env.PrependUnique(LIBS = [ - 'user32', - ]) - -env.Prepend(LIBS = [glsl, talloc]) - -env.Program( - target = 'glsl2', - source = [ - 'main.cpp', - ] -) - -env.Program( - target = 'glcpp', - source = ['glcpp/glcpp.c'], -) +import common
+
+Import('*')
+
+env = env.Clone()
+
+env.Prepend(CPPPATH = [
+ '#src/mapi',
+ '#src/mesa',
+])
+
+if env['platform'] == 'windows':
+ env.Prepend(CPPPATH = ['#src/talloc'])
+
+sources = [
+ 'glcpp/glcpp-lex.c',
+ 'glcpp/glcpp-parse.c',
+ 'glcpp/pp.c',
+ 'ast_expr.cpp',
+ 'ast_function.cpp',
+ 'ast_to_hir.cpp',
+ 'ast_type.cpp',
+ 'builtin_function.cpp',
+ 'glsl_lexer.cpp',
+ 'glsl_parser.cpp',
+ 'glsl_parser_extras.cpp',
+ 'glsl_types.cpp',
+ 'glsl_symbol_table.cpp',
+ 'hir_field_selection.cpp',
+ 'ir_basic_block.cpp',
+ 'ir_clone.cpp',
+ 'ir_constant_expression.cpp',
+ 'ir.cpp',
+ 'ir_expression_flattening.cpp',
+ 'ir_function_can_inline.cpp',
+ 'ir_function.cpp',
+ 'ir_hierarchical_visitor.cpp',
+ 'ir_hv_accept.cpp',
+ 'ir_import_prototypes.cpp',
+ 'ir_print_visitor.cpp',
+ 'ir_reader.cpp',
+ 'ir_rvalue_visitor.cpp',
+ 'ir_set_program_inouts.cpp',
+ 'ir_validate.cpp',
+ 'ir_variable.cpp',
+ 'ir_variable_refcount.cpp',
+ 'linker.cpp',
+ 'link_functions.cpp',
+ 'loop_analysis.cpp',
+ 'loop_controls.cpp',
+ 'loop_unroll.cpp',
+ 'lower_discard.cpp',
+ 'lower_if_to_cond_assign.cpp',
+ 'lower_instructions.cpp',
+ 'lower_jumps.cpp',
+ 'lower_mat_op_to_vec.cpp',
+ 'lower_noise.cpp',
+ 'lower_variable_index_to_cond_assign.cpp',
+ 'lower_vec_index_to_cond_assign.cpp',
+ 'lower_vec_index_to_swizzle.cpp',
+ 'lower_vector.cpp',
+ 'opt_algebraic.cpp',
+ 'opt_constant_folding.cpp',
+ 'opt_constant_propagation.cpp',
+ 'opt_constant_variable.cpp',
+ 'opt_copy_propagation.cpp',
+ 'opt_dead_code.cpp',
+ 'opt_dead_code_local.cpp',
+ 'opt_dead_functions.cpp',
+ 'opt_discard_simplification.cpp',
+ 'opt_function_inlining.cpp',
+ 'opt_if_simplification.cpp',
+ 'opt_noop_swizzle.cpp',
+ 'opt_redundant_jumps.cpp',
+ 'opt_structure_splitting.cpp',
+ 'opt_swizzle_swizzle.cpp',
+ 'opt_tree_grafting.cpp',
+ 's_expression.cpp',
+ 'strtod.c',
+]
+
+glsl = env.ConvenienceLibrary(
+ target = 'glsl',
+ source = sources,
+)
+
+Export('glsl')
+
+# FIXME: We can't build the programs because there's a cyclic dependency between tis directory and src/mesa
+Return()
+
+env = env.Clone()
+
+if env['platform'] == 'windows':
+ env.PrependUnique(LIBS = [
+ 'user32',
+ ])
+
+env.Prepend(LIBS = [glsl, talloc])
+
+env.Program(
+ target = 'glsl2',
+ source = [
+ 'main.cpp',
+ ]
+)
+
+env.Program(
+ target = 'glcpp',
+ source = ['glcpp/glcpp.c'],
+)
diff --git a/mesalib/src/glsl/TODO b/mesalib/src/glsl/TODO new file mode 100644 index 000000000..6eed986bf --- /dev/null +++ b/mesalib/src/glsl/TODO @@ -0,0 +1,38 @@ +- Detect code paths in non-void functions that don't reach a return statement
+
+- 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?
+
+- Implement support for ir_binop_dot in ir_algebraic.cpp. Perform
+ transformations such as "dot(v, vec3(0.0, 1.0, 0.0))" -> v.y.
+
+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
+
+- Implement support for 1.30 style shadow compares which only return a float
+ instead of a vec4.
+
+- Implement support for gl_ClipDistance. This is non-trivial because
+ gl_ClipDistance is exposed as a float[8], but all hardware actually
+ implements it as vec4[2].
\ No newline at end of file diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h index ba30f65df..61a7c9efb 100644 --- a/mesalib/src/glsl/ast.h +++ b/mesalib/src/glsl/ast.h @@ -1,702 +1,725 @@ -/* -*- c++ -*- */ -/* - * Copyright © 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#pragma once -#ifndef AST_H -#define AST_H - -#include "list.h" -#include "glsl_parser_extras.h" - -struct _mesa_glsl_parse_state; - -struct YYLTYPE; - -/** - * \defgroup AST Abstract syntax tree node definitions - * - * An abstract syntax tree is generated by the parser. This is a fairly - * direct representation of the gramma derivation for the source program. - * No symantic checking is done during the generation of the AST. Only - * syntactic checking is done. Symantic checking is performed by a later - * stage that converts the AST to a more generic intermediate representation. - * - *@{ - */ -/** - * Base class of all abstract syntax tree nodes - */ -class ast_node { -public: - /* Callers of this talloc-based new need not call delete. It's - * easier to just talloc_free 'ctx' (or any of its ancestors). */ - static void* operator new(size_t size, void *ctx) - { - void *node; - - node = talloc_zero_size(ctx, size); - assert(node != NULL); - - return node; - } - - /* If the user *does* call delete, that's OK, we will just - * talloc_free in that case. */ - static void operator delete(void *table, void *ctx) - { - talloc_free(table); - } - static void operator delete(void *table) - { - talloc_free(table); - } - - /** - * Print an AST node in something approximating the original GLSL code - */ - virtual void print(void) const; - - /** - * Convert the AST node to the high-level intermediate representation - */ - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - /** - * Retrieve the source location of an AST node - * - * This function is primarily used to get the source position of an AST node - * into a form that can be passed to \c _mesa_glsl_error. - * - * \sa _mesa_glsl_error, ast_node::set_location - */ - struct YYLTYPE get_location(void) const - { - struct YYLTYPE locp; - - locp.source = this->location.source; - locp.first_line = this->location.line; - locp.first_column = this->location.column; - locp.last_line = locp.first_line; - locp.last_column = locp.first_column; - - return locp; - } - - /** - * Set the source location of an AST node from a parser location - * - * \sa ast_node::get_location - */ - void set_location(const struct YYLTYPE &locp) - { - this->location.source = locp.source; - this->location.line = locp.first_line; - this->location.column = locp.first_column; - } - - /** - * Source location of the AST node. - */ - struct { - unsigned source; /**< GLSL source number. */ - unsigned line; /**< Line number within the source string. */ - unsigned column; /**< Column in the line. */ - } location; - - exec_node link; - -protected: - /** - * The only constructor is protected so that only derived class objects can - * be created. - */ - ast_node(void); -}; - - -/** - * Operators for AST expression nodes. - */ -enum ast_operators { - ast_assign, - ast_plus, /**< Unary + operator. */ - ast_neg, - ast_add, - ast_sub, - ast_mul, - ast_div, - ast_mod, - ast_lshift, - ast_rshift, - ast_less, - ast_greater, - ast_lequal, - ast_gequal, - ast_equal, - ast_nequal, - ast_bit_and, - ast_bit_xor, - ast_bit_or, - ast_bit_not, - ast_logic_and, - ast_logic_xor, - ast_logic_or, - ast_logic_not, - - ast_mul_assign, - ast_div_assign, - ast_mod_assign, - ast_add_assign, - ast_sub_assign, - ast_ls_assign, - ast_rs_assign, - ast_and_assign, - ast_xor_assign, - ast_or_assign, - - ast_conditional, - - ast_pre_inc, - ast_pre_dec, - ast_post_inc, - ast_post_dec, - ast_field_selection, - ast_array_index, - - ast_function_call, - - ast_identifier, - ast_int_constant, - ast_uint_constant, - ast_float_constant, - ast_bool_constant, - - ast_sequence -}; - -/** - * Representation of any sort of expression. - */ -class ast_expression : public ast_node { -public: - ast_expression(int oper, ast_expression *, - ast_expression *, ast_expression *); - - ast_expression(const char *identifier) : - oper(ast_identifier) - { - subexpressions[0] = NULL; - subexpressions[1] = NULL; - subexpressions[2] = NULL; - primary_expression.identifier = (char *) identifier; - } - - static const char *operator_string(enum ast_operators op); - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - virtual void print(void) const; - - enum ast_operators oper; - - ast_expression *subexpressions[3]; - - union { - char *identifier; - int int_constant; - float float_constant; - unsigned uint_constant; - int bool_constant; - } primary_expression; - - - /** - * List of expressions for an \c ast_sequence or parameters for an - * \c ast_function_call - */ - exec_list expressions; -}; - -class ast_expression_bin : public ast_expression { -public: - ast_expression_bin(int oper, ast_expression *, ast_expression *); - - virtual void print(void) const; -}; - -/** - * Subclass of expressions for function calls - */ -class ast_function_expression : public ast_expression { -public: - ast_function_expression(ast_expression *callee) - : ast_expression(ast_function_call, callee, - NULL, NULL), - cons(false) - { - /* empty */ - } - - ast_function_expression(class ast_type_specifier *type) - : ast_expression(ast_function_call, (ast_expression *) type, - NULL, NULL), - cons(true) - { - /* empty */ - } - - bool is_constructor() const - { - return cons; - } - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - -private: - /** - * Is this function call actually a constructor? - */ - bool cons; -}; - - -/** - * Number of possible operators for an ast_expression - * - * This is done as a define instead of as an additional value in the enum so - * that the compiler won't generate spurious messages like "warning: - * enumeration value ‘ast_num_operators’ not handled in switch" - */ -#define AST_NUM_OPERATORS (ast_sequence + 1) - - -class ast_compound_statement : public ast_node { -public: - ast_compound_statement(int new_scope, ast_node *statements); - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - int new_scope; - exec_list statements; -}; - -class ast_declaration : public ast_node { -public: - ast_declaration(char *identifier, int is_array, ast_expression *array_size, - ast_expression *initializer); - virtual void print(void) const; - - char *identifier; - - int is_array; - ast_expression *array_size; - - ast_expression *initializer; -}; - - -enum { - ast_precision_high = 0, /**< Default precision. */ - ast_precision_medium, - ast_precision_low -}; - -struct ast_type_qualifier { - unsigned invariant:1; - unsigned constant:1; - unsigned attribute:1; - unsigned varying:1; - unsigned in:1; - unsigned out:1; - unsigned centroid:1; - unsigned uniform:1; - unsigned smooth:1; - unsigned flat:1; - unsigned noperspective:1; - - /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */ - /*@{*/ - unsigned origin_upper_left:1; - unsigned pixel_center_integer:1; - /*@}*/ -}; - -class ast_struct_specifier : public ast_node { -public: - ast_struct_specifier(char *identifier, ast_node *declarator_list); - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - char *name; - exec_list declarations; -}; - - -enum ast_types { - ast_void, - ast_float, - ast_int, - ast_uint, - ast_bool, - ast_vec2, - ast_vec3, - ast_vec4, - ast_bvec2, - ast_bvec3, - ast_bvec4, - ast_ivec2, - ast_ivec3, - ast_ivec4, - ast_uvec2, - ast_uvec3, - ast_uvec4, - ast_mat2, - ast_mat2x3, - ast_mat2x4, - ast_mat3x2, - ast_mat3, - ast_mat3x4, - ast_mat4x2, - ast_mat4x3, - ast_mat4, - ast_sampler1d, - ast_sampler2d, - ast_sampler2drect, - ast_sampler3d, - ast_samplercube, - ast_sampler1dshadow, - ast_sampler2dshadow, - ast_sampler2drectshadow, - ast_samplercubeshadow, - ast_sampler1darray, - ast_sampler2darray, - ast_sampler1darrayshadow, - ast_sampler2darrayshadow, - ast_isampler1d, - ast_isampler2d, - ast_isampler3d, - ast_isamplercube, - ast_isampler1darray, - ast_isampler2darray, - ast_usampler1d, - ast_usampler2d, - ast_usampler3d, - ast_usamplercube, - ast_usampler1darray, - ast_usampler2darray, - - ast_struct, - ast_type_name -}; - - -class ast_type_specifier : public ast_node { -public: - ast_type_specifier(int specifier); - - /** Construct a type specifier from a type name */ - ast_type_specifier(const char *name) - : type_specifier(ast_type_name), type_name(name), structure(NULL), - is_array(false), array_size(NULL), precision(ast_precision_high) - { - /* empty */ - } - - /** Construct a type specifier from a structure definition */ - ast_type_specifier(ast_struct_specifier *s) - : type_specifier(ast_struct), type_name(s->name), structure(s), - is_array(false), array_size(NULL), precision(ast_precision_high) - { - /* empty */ - } - - const struct glsl_type *glsl_type(const char **name, - struct _mesa_glsl_parse_state *state) - const; - - virtual void print(void) const; - - ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *); - - enum ast_types type_specifier; - - const char *type_name; - ast_struct_specifier *structure; - - int is_array; - ast_expression *array_size; - - unsigned precision:2; -}; - - -class ast_fully_specified_type : public ast_node { -public: - virtual void print(void) const; - bool has_qualifiers() const; - - ast_type_qualifier qualifier; - ast_type_specifier *specifier; -}; - - -class ast_declarator_list : public ast_node { -public: - ast_declarator_list(ast_fully_specified_type *); - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - ast_fully_specified_type *type; - exec_list declarations; - - /** - * Special flag for vertex shader "invariant" declarations. - * - * Vertex shaders can contain "invariant" variable redeclarations that do - * not include a type. For example, "invariant gl_Position;". This flag - * is used to note these cases when no type is specified. - */ - int invariant; -}; - - -class ast_parameter_declarator : public ast_node { -public: - ast_parameter_declarator() - { - this->identifier = NULL; - this->is_array = false; - this->array_size = 0; - } - - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - ast_fully_specified_type *type; - char *identifier; - int is_array; - ast_expression *array_size; - - static void parameters_to_hir(exec_list *ast_parameters, - bool formal, exec_list *ir_parameters, - struct _mesa_glsl_parse_state *state); - -private: - /** Is this parameter declaration part of a formal parameter list? */ - bool formal_parameter; - - /** - * Is this parameter 'void' type? - * - * This field is set by \c ::hir. - */ - bool is_void; -}; - - -class ast_function : public ast_node { -public: - ast_function(void); - - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - ast_fully_specified_type *return_type; - char *identifier; - - exec_list parameters; - -private: - /** - * Is this prototype part of the function definition? - * - * Used by ast_function_definition::hir to process the parameters, etc. - * of the function. - * - * \sa ::hir - */ - bool is_definition; - - /** - * Function signature corresponding to this function prototype instance - * - * Used by ast_function_definition::hir to process the parameters, etc. - * of the function. - * - * \sa ::hir - */ - class ir_function_signature *signature; - - friend class ast_function_definition; -}; - - -class ast_declaration_statement : public ast_node { -public: - ast_declaration_statement(void); - - enum { - ast_function, - ast_declaration, - ast_precision - } mode; - - union { - class ast_function *function; - ast_declarator_list *declarator; - ast_type_specifier *type; - ast_node *node; - } declaration; -}; - - -class ast_expression_statement : public ast_node { -public: - ast_expression_statement(ast_expression *); - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - ast_expression *expression; -}; - - -class ast_case_label : public ast_node { -public: - - /** - * An expression of NULL means 'default'. - */ - ast_expression *expression; -}; - -class ast_selection_statement : public ast_node { -public: - ast_selection_statement(ast_expression *condition, - ast_node *then_statement, - ast_node *else_statement); - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - ast_expression *condition; - ast_node *then_statement; - ast_node *else_statement; -}; - - -class ast_switch_statement : public ast_node { -public: - ast_expression *expression; - exec_list statements; -}; - -class ast_iteration_statement : public ast_node { -public: - ast_iteration_statement(int mode, ast_node *init, ast_node *condition, - ast_expression *rest_expression, ast_node *body); - - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *); - - enum ast_iteration_modes { - ast_for, - ast_while, - ast_do_while - } mode; - - - ast_node *init_statement; - ast_node *condition; - ast_expression *rest_expression; - - ast_node *body; - -private: - /** - * Generate IR from the condition of a loop - * - * This is factored out of ::hir because some loops have the condition - * test at the top (for and while), and others have it at the end (do-while). - */ - void condition_to_hir(class ir_loop *, struct _mesa_glsl_parse_state *); -}; - - -class ast_jump_statement : public ast_node { -public: - ast_jump_statement(int mode, ast_expression *return_value); - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - enum ast_jump_modes { - ast_continue, - ast_break, - ast_return, - ast_discard - } mode; - - ast_expression *opt_return_value; -}; - - -class ast_function_definition : public ast_node { -public: - virtual void print(void) const; - - virtual ir_rvalue *hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state); - - ast_function *prototype; - ast_compound_statement *body; -}; -/*@}*/ - -extern void -_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); - -extern ir_rvalue * -_mesa_ast_field_selection_to_hir(const ast_expression *expr, - exec_list *instructions, - struct _mesa_glsl_parse_state *state); - -#endif /* AST_H */ +/* -*- c++ -*- */
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+#ifndef AST_H
+#define AST_H
+
+#include "list.h"
+#include "glsl_parser_extras.h"
+
+struct _mesa_glsl_parse_state;
+
+struct YYLTYPE;
+
+/**
+ * \defgroup AST Abstract syntax tree node definitions
+ *
+ * An abstract syntax tree is generated by the parser. This is a fairly
+ * direct representation of the gramma derivation for the source program.
+ * No symantic checking is done during the generation of the AST. Only
+ * syntactic checking is done. Symantic checking is performed by a later
+ * stage that converts the AST to a more generic intermediate representation.
+ *
+ *@{
+ */
+/**
+ * Base class of all abstract syntax tree nodes
+ */
+class ast_node {
+public:
+ /* Callers of this talloc-based new need not call delete. It's
+ * easier to just talloc_free 'ctx' (or any of its ancestors). */
+ static void* operator new(size_t size, void *ctx)
+ {
+ void *node;
+
+ node = talloc_zero_size(ctx, size);
+ assert(node != NULL);
+
+ return node;
+ }
+
+ /* If the user *does* call delete, that's OK, we will just
+ * talloc_free in that case. */
+ static void operator delete(void *table, void *ctx)
+ {
+ talloc_free(table);
+ }
+ static void operator delete(void *table)
+ {
+ talloc_free(table);
+ }
+
+ /**
+ * Print an AST node in something approximating the original GLSL code
+ */
+ virtual void print(void) const;
+
+ /**
+ * Convert the AST node to the high-level intermediate representation
+ */
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ /**
+ * Retrieve the source location of an AST node
+ *
+ * This function is primarily used to get the source position of an AST node
+ * into a form that can be passed to \c _mesa_glsl_error.
+ *
+ * \sa _mesa_glsl_error, ast_node::set_location
+ */
+ struct YYLTYPE get_location(void) const
+ {
+ struct YYLTYPE locp;
+
+ locp.source = this->location.source;
+ locp.first_line = this->location.line;
+ locp.first_column = this->location.column;
+ locp.last_line = locp.first_line;
+ locp.last_column = locp.first_column;
+
+ return locp;
+ }
+
+ /**
+ * Set the source location of an AST node from a parser location
+ *
+ * \sa ast_node::get_location
+ */
+ void set_location(const struct YYLTYPE &locp)
+ {
+ this->location.source = locp.source;
+ this->location.line = locp.first_line;
+ this->location.column = locp.first_column;
+ }
+
+ /**
+ * Source location of the AST node.
+ */
+ struct {
+ unsigned source; /**< GLSL source number. */
+ unsigned line; /**< Line number within the source string. */
+ unsigned column; /**< Column in the line. */
+ } location;
+
+ exec_node link;
+
+protected:
+ /**
+ * The only constructor is protected so that only derived class objects can
+ * be created.
+ */
+ ast_node(void);
+};
+
+
+/**
+ * Operators for AST expression nodes.
+ */
+enum ast_operators {
+ ast_assign,
+ ast_plus, /**< Unary + operator. */
+ ast_neg,
+ ast_add,
+ ast_sub,
+ ast_mul,
+ ast_div,
+ ast_mod,
+ ast_lshift,
+ ast_rshift,
+ ast_less,
+ ast_greater,
+ ast_lequal,
+ ast_gequal,
+ ast_equal,
+ ast_nequal,
+ ast_bit_and,
+ ast_bit_xor,
+ ast_bit_or,
+ ast_bit_not,
+ ast_logic_and,
+ ast_logic_xor,
+ ast_logic_or,
+ ast_logic_not,
+
+ ast_mul_assign,
+ ast_div_assign,
+ ast_mod_assign,
+ ast_add_assign,
+ ast_sub_assign,
+ ast_ls_assign,
+ ast_rs_assign,
+ ast_and_assign,
+ ast_xor_assign,
+ ast_or_assign,
+
+ ast_conditional,
+
+ ast_pre_inc,
+ ast_pre_dec,
+ ast_post_inc,
+ ast_post_dec,
+ ast_field_selection,
+ ast_array_index,
+
+ ast_function_call,
+
+ ast_identifier,
+ ast_int_constant,
+ ast_uint_constant,
+ ast_float_constant,
+ ast_bool_constant,
+
+ ast_sequence
+};
+
+/**
+ * Representation of any sort of expression.
+ */
+class ast_expression : public ast_node {
+public:
+ ast_expression(int oper, ast_expression *,
+ ast_expression *, ast_expression *);
+
+ ast_expression(const char *identifier) :
+ oper(ast_identifier)
+ {
+ subexpressions[0] = NULL;
+ subexpressions[1] = NULL;
+ subexpressions[2] = NULL;
+ primary_expression.identifier = (char *) identifier;
+ }
+
+ static const char *operator_string(enum ast_operators op);
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ virtual void print(void) const;
+
+ enum ast_operators oper;
+
+ ast_expression *subexpressions[3];
+
+ union {
+ char *identifier;
+ int int_constant;
+ float float_constant;
+ unsigned uint_constant;
+ int bool_constant;
+ } primary_expression;
+
+
+ /**
+ * List of expressions for an \c ast_sequence or parameters for an
+ * \c ast_function_call
+ */
+ exec_list expressions;
+};
+
+class ast_expression_bin : public ast_expression {
+public:
+ ast_expression_bin(int oper, ast_expression *, ast_expression *);
+
+ virtual void print(void) const;
+};
+
+/**
+ * Subclass of expressions for function calls
+ */
+class ast_function_expression : public ast_expression {
+public:
+ ast_function_expression(ast_expression *callee)
+ : ast_expression(ast_function_call, callee,
+ NULL, NULL),
+ cons(false)
+ {
+ /* empty */
+ }
+
+ ast_function_expression(class ast_type_specifier *type)
+ : ast_expression(ast_function_call, (ast_expression *) type,
+ NULL, NULL),
+ cons(true)
+ {
+ /* empty */
+ }
+
+ bool is_constructor() const
+ {
+ return cons;
+ }
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+private:
+ /**
+ * Is this function call actually a constructor?
+ */
+ bool cons;
+};
+
+
+/**
+ * Number of possible operators for an ast_expression
+ *
+ * This is done as a define instead of as an additional value in the enum so
+ * that the compiler won't generate spurious messages like "warning:
+ * enumeration value ‘ast_num_operators’ not handled in switch"
+ */
+#define AST_NUM_OPERATORS (ast_sequence + 1)
+
+
+class ast_compound_statement : public ast_node {
+public:
+ ast_compound_statement(int new_scope, ast_node *statements);
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ int new_scope;
+ exec_list statements;
+};
+
+class ast_declaration : public ast_node {
+public:
+ ast_declaration(char *identifier, int is_array, ast_expression *array_size,
+ ast_expression *initializer);
+ virtual void print(void) const;
+
+ char *identifier;
+
+ int is_array;
+ ast_expression *array_size;
+
+ ast_expression *initializer;
+};
+
+
+enum {
+ ast_precision_high = 0, /**< Default precision. */
+ ast_precision_medium,
+ ast_precision_low
+};
+
+struct ast_type_qualifier {
+ union {
+ struct {
+ unsigned invariant:1;
+ unsigned constant:1;
+ unsigned attribute:1;
+ unsigned varying:1;
+ unsigned in:1;
+ unsigned out:1;
+ unsigned centroid:1;
+ unsigned uniform:1;
+ unsigned smooth:1;
+ unsigned flat:1;
+ unsigned noperspective:1;
+
+ /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */
+ /*@{*/
+ unsigned origin_upper_left:1;
+ unsigned pixel_center_integer:1;
+ /*@}*/
+
+ /**
+ * Flag set if GL_ARB_explicit_attrib_location "location" layout
+ * qualifier is used.
+ */
+ unsigned explicit_location:1;
+ } q;
+ unsigned i;
+ } flags;
+
+ /**
+ * Location specified via GL_ARB_explicit_attrib_location layout
+ *
+ * \note
+ * This field is only valid if \c explicit_location is set.
+ */
+ unsigned location;
+};
+
+class ast_struct_specifier : public ast_node {
+public:
+ ast_struct_specifier(char *identifier, ast_node *declarator_list);
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ char *name;
+ exec_list declarations;
+};
+
+
+enum ast_types {
+ ast_void,
+ ast_float,
+ ast_int,
+ ast_uint,
+ ast_bool,
+ ast_vec2,
+ ast_vec3,
+ ast_vec4,
+ ast_bvec2,
+ ast_bvec3,
+ ast_bvec4,
+ ast_ivec2,
+ ast_ivec3,
+ ast_ivec4,
+ ast_uvec2,
+ ast_uvec3,
+ ast_uvec4,
+ ast_mat2,
+ ast_mat2x3,
+ ast_mat2x4,
+ ast_mat3x2,
+ ast_mat3,
+ ast_mat3x4,
+ ast_mat4x2,
+ ast_mat4x3,
+ ast_mat4,
+ ast_sampler1d,
+ ast_sampler2d,
+ ast_sampler2drect,
+ ast_sampler3d,
+ ast_samplercube,
+ ast_sampler1dshadow,
+ ast_sampler2dshadow,
+ ast_sampler2drectshadow,
+ ast_samplercubeshadow,
+ ast_sampler1darray,
+ ast_sampler2darray,
+ ast_sampler1darrayshadow,
+ ast_sampler2darrayshadow,
+ ast_isampler1d,
+ ast_isampler2d,
+ ast_isampler3d,
+ ast_isamplercube,
+ ast_isampler1darray,
+ ast_isampler2darray,
+ ast_usampler1d,
+ ast_usampler2d,
+ ast_usampler3d,
+ ast_usamplercube,
+ ast_usampler1darray,
+ ast_usampler2darray,
+
+ ast_struct,
+ ast_type_name
+};
+
+
+class ast_type_specifier : public ast_node {
+public:
+ ast_type_specifier(int specifier);
+
+ /** Construct a type specifier from a type name */
+ ast_type_specifier(const char *name)
+ : type_specifier(ast_type_name), type_name(name), structure(NULL),
+ is_array(false), array_size(NULL), precision(ast_precision_high)
+ {
+ /* empty */
+ }
+
+ /** Construct a type specifier from a structure definition */
+ ast_type_specifier(ast_struct_specifier *s)
+ : type_specifier(ast_struct), type_name(s->name), structure(s),
+ is_array(false), array_size(NULL), precision(ast_precision_high)
+ {
+ /* empty */
+ }
+
+ const struct glsl_type *glsl_type(const char **name,
+ struct _mesa_glsl_parse_state *state)
+ const;
+
+ virtual void print(void) const;
+
+ ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
+
+ enum ast_types type_specifier;
+
+ const char *type_name;
+ ast_struct_specifier *structure;
+
+ int is_array;
+ ast_expression *array_size;
+
+ unsigned precision:2;
+};
+
+
+class ast_fully_specified_type : public ast_node {
+public:
+ virtual void print(void) const;
+ bool has_qualifiers() const;
+
+ ast_type_qualifier qualifier;
+ ast_type_specifier *specifier;
+};
+
+
+class ast_declarator_list : public ast_node {
+public:
+ ast_declarator_list(ast_fully_specified_type *);
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ ast_fully_specified_type *type;
+ exec_list declarations;
+
+ /**
+ * Special flag for vertex shader "invariant" declarations.
+ *
+ * Vertex shaders can contain "invariant" variable redeclarations that do
+ * not include a type. For example, "invariant gl_Position;". This flag
+ * is used to note these cases when no type is specified.
+ */
+ int invariant;
+};
+
+
+class ast_parameter_declarator : public ast_node {
+public:
+ ast_parameter_declarator()
+ {
+ this->identifier = NULL;
+ this->is_array = false;
+ this->array_size = 0;
+ }
+
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ ast_fully_specified_type *type;
+ char *identifier;
+ int is_array;
+ ast_expression *array_size;
+
+ static void parameters_to_hir(exec_list *ast_parameters,
+ bool formal, exec_list *ir_parameters,
+ struct _mesa_glsl_parse_state *state);
+
+private:
+ /** Is this parameter declaration part of a formal parameter list? */
+ bool formal_parameter;
+
+ /**
+ * Is this parameter 'void' type?
+ *
+ * This field is set by \c ::hir.
+ */
+ bool is_void;
+};
+
+
+class ast_function : public ast_node {
+public:
+ ast_function(void);
+
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ ast_fully_specified_type *return_type;
+ char *identifier;
+
+ exec_list parameters;
+
+private:
+ /**
+ * Is this prototype part of the function definition?
+ *
+ * Used by ast_function_definition::hir to process the parameters, etc.
+ * of the function.
+ *
+ * \sa ::hir
+ */
+ bool is_definition;
+
+ /**
+ * Function signature corresponding to this function prototype instance
+ *
+ * Used by ast_function_definition::hir to process the parameters, etc.
+ * of the function.
+ *
+ * \sa ::hir
+ */
+ class ir_function_signature *signature;
+
+ friend class ast_function_definition;
+};
+
+
+class ast_declaration_statement : public ast_node {
+public:
+ ast_declaration_statement(void);
+
+ enum {
+ ast_function,
+ ast_declaration,
+ ast_precision
+ } mode;
+
+ union {
+ class ast_function *function;
+ ast_declarator_list *declarator;
+ ast_type_specifier *type;
+ ast_node *node;
+ } declaration;
+};
+
+
+class ast_expression_statement : public ast_node {
+public:
+ ast_expression_statement(ast_expression *);
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ ast_expression *expression;
+};
+
+
+class ast_case_label : public ast_node {
+public:
+
+ /**
+ * An expression of NULL means 'default'.
+ */
+ ast_expression *expression;
+};
+
+class ast_selection_statement : public ast_node {
+public:
+ ast_selection_statement(ast_expression *condition,
+ ast_node *then_statement,
+ ast_node *else_statement);
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ ast_expression *condition;
+ ast_node *then_statement;
+ ast_node *else_statement;
+};
+
+
+class ast_switch_statement : public ast_node {
+public:
+ ast_expression *expression;
+ exec_list statements;
+};
+
+class ast_iteration_statement : public ast_node {
+public:
+ ast_iteration_statement(int mode, ast_node *init, ast_node *condition,
+ ast_expression *rest_expression, ast_node *body);
+
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
+
+ enum ast_iteration_modes {
+ ast_for,
+ ast_while,
+ ast_do_while
+ } mode;
+
+
+ ast_node *init_statement;
+ ast_node *condition;
+ ast_expression *rest_expression;
+
+ ast_node *body;
+
+private:
+ /**
+ * Generate IR from the condition of a loop
+ *
+ * This is factored out of ::hir because some loops have the condition
+ * test at the top (for and while), and others have it at the end (do-while).
+ */
+ void condition_to_hir(class ir_loop *, struct _mesa_glsl_parse_state *);
+};
+
+
+class ast_jump_statement : public ast_node {
+public:
+ ast_jump_statement(int mode, ast_expression *return_value);
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ enum ast_jump_modes {
+ ast_continue,
+ ast_break,
+ ast_return,
+ ast_discard
+ } mode;
+
+ ast_expression *opt_return_value;
+};
+
+
+class ast_function_definition : public ast_node {
+public:
+ virtual void print(void) const;
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ ast_function *prototype;
+ ast_compound_statement *body;
+};
+/*@}*/
+
+extern void
+_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state);
+
+extern ir_rvalue *
+_mesa_ast_field_selection_to_hir(const ast_expression *expr,
+ exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+void
+emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
+ ir_function *f);
+
+#endif /* AST_H */
diff --git a/mesalib/src/glsl/ast_expr.cpp b/mesalib/src/glsl/ast_expr.cpp index 4e83decb9..c45d60757 100644 --- a/mesalib/src/glsl/ast_expr.cpp +++ b/mesalib/src/glsl/ast_expr.cpp @@ -1,96 +1,96 @@ -/* - * 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(); -} +/*
+ * 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();
+}
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 20448f5a9..2e1a4d9f6 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -1,1241 +1,1254 @@ -/* - * 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" -#include "main/core.h" /* for MIN2 */ - -static ir_rvalue * -convert_component(ir_rvalue *src, const glsl_type *desired_type); - -bool -apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, - struct _mesa_glsl_parse_state *state); - -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; -} - - -/** - * Generate a source prototype for a function signature - * - * \param return_type Return type of the function. May be \c NULL. - * \param name Name of the function. - * \param parameters Parameter list for the function. This may be either a - * formal or actual parameter list. Only the type is used. - * - * \return - * A talloced string representing the prototype of the function. - */ -char * -prototype_string(const glsl_type *return_type, const char *name, - exec_list *parameters) -{ - char *str = NULL; - - if (return_type != NULL) - str = talloc_asprintf(str, "%s ", return_type->name); - - str = talloc_asprintf_append(str, "%s(", name); - - const char *comma = ""; - foreach_list(node, parameters) { - const ir_instruction *const param = (ir_instruction *) node; - - str = talloc_asprintf_append(str, "%s%s", comma, param->type->name); - comma = ", "; - } - - str = talloc_strdup_append(str, ")"); - return str; -} - - -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 = state; - - 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"); - } - } - - if (formal->type->is_numeric() || formal->type->is_boolean()) { - ir_rvalue *converted = convert_component(actual, formal->type); - actual->replace_with(converted); - } - - actual_iter.next(); - formal_iter.next(); - } - - /* Always insert the call in the instruction stream, and return a deref - * of its return val if it returns a value, since we don't know if - * the rvalue is going to be assigned to anything or not. - */ - ir_call *call = new(ctx) ir_call(sig, actual_parameters); - if (!sig->return_type->is_void()) { - ir_variable *var; - ir_dereference_variable *deref; - - var = new(ctx) ir_variable(sig->return_type, - talloc_asprintf(ctx, "%s_retval", - sig->function_name()), - ir_var_temporary); - instructions->push_tail(var); - - deref = new(ctx) ir_dereference_variable(var); - ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL); - instructions->push_tail(assign); - if (state->language_version >= 120) - var->constant_value = call->constant_expression_value(); - - deref = new(ctx) ir_dereference_variable(var); - return deref; - } else { - instructions->push_tail(call); - return NULL; - } - } else { - char *str = prototype_string(NULL, f->name, actual_parameters); - - _mesa_glsl_error(loc, state, "no matching function for call to `%s'", - str); - talloc_free(str); - - const char *prefix = "candidates are: "; - foreach_list (node, &f->signatures) { - ir_function_signature *sig = (ir_function_signature *) node; - - str = prototype_string(sig->return_type, f->name, &sig->parameters); - _mesa_glsl_error(loc, state, "%s%s\n", prefix, str); - talloc_free(str); - - prefix = " "; - } - - 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 = 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 - * - * This implements the rules in the "Conversion and Scalar Constructors" - * section (GLSL 1.10 section 5.4.1), not the "Implicit Conversions" rules. - */ -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: - switch (b) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: - result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL); - break; - case GLSL_TYPE_FLOAT: - result = new(ctx) ir_expression(ir_unop_f2b, desired_type, src, NULL); - break; - } - break; - } - - assert(result != NULL); - - /* Try constant folding; it may fold in the conversion we just added. */ - 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 = 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(constructor_type->element_type(), - parameter_count); - assert(constructor_type != NULL); - assert(constructor_type->length == parameter_count); - } - - bool all_parameters_are_constant = true; - - /* Type cast each parameter and, if possible, fold constants. */ - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *ir = (ir_rvalue *) n; - ir_rvalue *result = ir; - - /* Apply implicit conversions (not the scalar constructor rules!) */ - if (constructor_type->element_type()->is_float()) { - const glsl_type *desired_type = - glsl_type::get_instance(GLSL_TYPE_FLOAT, - ir->type->vector_elements, - ir->type->matrix_columns); - result = convert_component(ir, desired_type); - } - - if (result->type != constructor_type->element_type()) { - _mesa_glsl_error(loc, state, "type error in array constructor: " - "expected: %s, found %s", - constructor_type->element_type()->name, - result->type->name); - } - - /* 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; - - ir->replace_with(result); - } - - if (all_parameters_are_constant) - return new(ctx) ir_constant(constructor_type, &actual_parameters); - - ir_variable *var = new(ctx) ir_variable(constructor_type, "array_ctor", - ir_var_temporary); - instructions->push_tail(var); - - int i = 0; - foreach_list(node, &actual_parameters) { - ir_rvalue *rhs = (ir_rvalue *) node; - ir_rvalue *lhs = new(ctx) ir_dereference_array(var, - new(ctx) ir_constant(i)); - - ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(assignment); - - i++; - } - - return new(ctx) ir_dereference_variable(var); -} - - -/** - * Try to convert a record constructor to a constant expression - */ -static ir_constant * -constant_record_constructor(const glsl_type *constructor_type, - exec_list *parameters, void *mem_ctx) -{ - foreach_list(node, parameters) { - ir_constant *constant = ((ir_instruction *) node)->as_constant(); - if (constant == NULL) - return NULL; - node->replace_with(constant); - } - - return new(mem_ctx) ir_constant(constructor_type, parameters); -} - - -/** - * Determine if a list consists of a single scalar r-value - */ -bool -single_scalar_parameter(exec_list *parameters) -{ - const ir_rvalue *const p = (ir_rvalue *) parameters->head; - assert(((ir_rvalue *)p)->as_rvalue() != NULL); - - return (p->type->is_scalar() && p->next->is_tail_sentinel()); -} - - -/** - * Generate inline code for a vector constructor - * - * The generated constructor code will consist of a temporary variable - * declaration of the same type as the constructor. A sequence of assignments - * from constructor parameters to the temporary will follow. - * - * \return - * An \c ir_dereference_variable of the temprorary generated in the constructor - * body. - */ -ir_rvalue * -emit_inline_vector_constructor(const glsl_type *type, - exec_list *instructions, - exec_list *parameters, - void *ctx) -{ - assert(!parameters->is_empty()); - - ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary); - instructions->push_tail(var); - - /* There are two kinds of vector constructors. - * - * - Construct a vector from a single scalar by replicating that scalar to - * all components of the vector. - * - * - Construct a vector from an arbirary combination of vectors and - * scalars. The components of the constructor parameters are assigned - * to the vector in order until the vector is full. - */ - const unsigned lhs_components = type->components(); - if (single_scalar_parameter(parameters)) { - ir_rvalue *first_param = (ir_rvalue *)parameters->head; - ir_rvalue *rhs = new(ctx) ir_swizzle(first_param, 0, 0, 0, 0, - lhs_components); - ir_dereference_variable *lhs = new(ctx) ir_dereference_variable(var); - const unsigned mask = (1U << lhs_components) - 1; - - assert(rhs->type == lhs->type); - - ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL, mask); - instructions->push_tail(inst); - } else { - unsigned base_component = 0; - unsigned base_lhs_component = 0; - ir_constant_data data; - unsigned constant_mask = 0, constant_components = 0; - - memset(&data, 0, sizeof(data)); - - foreach_list(node, parameters) { - ir_rvalue *param = (ir_rvalue *) node; - unsigned rhs_components = param->type->components(); - - /* Do not try to assign more components to the vector than it has! - */ - if ((rhs_components + base_lhs_component) > lhs_components) { - rhs_components = lhs_components - base_lhs_component; - } - - const ir_constant *const c = param->as_constant(); - if (c != NULL) { - for (unsigned i = 0; i < rhs_components; i++) { - switch (c->type->base_type) { - case GLSL_TYPE_UINT: - data.u[i + base_component] = c->get_uint_component(i); - break; - case GLSL_TYPE_INT: - data.i[i + base_component] = c->get_int_component(i); - break; - case GLSL_TYPE_FLOAT: - data.f[i + base_component] = c->get_float_component(i); - break; - case GLSL_TYPE_BOOL: - data.b[i + base_component] = c->get_bool_component(i); - break; - default: - assert(!"Should not get here."); - break; - } - } - - /* Mask of fields to be written in the assignment. - */ - constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component; - constant_components++; - - base_component += rhs_components; - } - /* Advance the component index by the number of components - * that were just assigned. - */ - base_lhs_component += rhs_components; - } - - if (constant_mask != 0) { - ir_dereference *lhs = new(ctx) ir_dereference_variable(var); - const glsl_type *rhs_type = glsl_type::get_instance(var->type->base_type, - constant_components, - 1); - ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data); - - ir_instruction *inst = - new(ctx) ir_assignment(lhs, rhs, NULL, constant_mask); - instructions->push_tail(inst); - } - - base_component = 0; - foreach_list(node, parameters) { - ir_rvalue *param = (ir_rvalue *) node; - unsigned rhs_components = param->type->components(); - - /* Do not try to assign more components to the vector than it has! - */ - if ((rhs_components + base_component) > lhs_components) { - rhs_components = lhs_components - base_component; - } - - const ir_constant *const c = param->as_constant(); - if (c == NULL) { - /* Generate a swizzle in case rhs_components != rhs->type->vector_elements. */ - unsigned swiz[4] = { 0, 0, 0, 0 }; - for (unsigned i = 0; i < rhs_components; i++) - swiz[i] = i; - - /* Mask of fields to be written in the assignment. - */ - const unsigned write_mask = ((1U << rhs_components) - 1) - << base_component; - - ir_dereference *lhs = new(ctx) ir_dereference_variable(var); - ir_rvalue *rhs = new(ctx) ir_swizzle(param, swiz, rhs_components); - - ir_instruction *inst = - new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); - instructions->push_tail(inst); - } - - /* Advance the component index by the number of components that were - * just assigned. - */ - base_component += rhs_components; - } - } - return new(ctx) ir_dereference_variable(var); -} - - -/** - * Generate assignment of a portion of a vector to a portion of a matrix column - * - * \param src_base First component of the source to be used in assignment - * \param column Column of destination to be assiged - * \param row_base First component of the destination column to be assigned - * \param count Number of components to be assigned - * - * \note - * \c src_base + \c count must be less than or equal to the number of components - * in the source vector. - */ -ir_instruction * -assign_to_matrix_column(ir_variable *var, unsigned column, unsigned row_base, - ir_rvalue *src, unsigned src_base, unsigned count, - void *mem_ctx) -{ - ir_constant *col_idx = new(mem_ctx) ir_constant(column); - ir_dereference *column_ref = new(mem_ctx) ir_dereference_array(var, col_idx); - - assert(column_ref->type->components() >= (row_base + count)); - assert(src->type->components() >= (src_base + count)); - - /* Generate a swizzle that puts the first element of the source at the - * location of the first element of the destination. - */ - unsigned swiz[4] = { src_base, src_base, src_base, src_base }; - for (unsigned i = 0; i < count; i++) - swiz[i + row_base] = i; - - ir_rvalue *const rhs = - new(mem_ctx) ir_swizzle(src, swiz, count); - - /* Mask of fields to be written in the assignment. - */ - const unsigned write_mask = ((1U << count) - 1) << row_base; - - return new(mem_ctx) ir_assignment(column_ref, rhs, NULL, write_mask); -} - - -/** - * Generate inline code for a matrix constructor - * - * The generated constructor code will consist of a temporary variable - * declaration of the same type as the constructor. A sequence of assignments - * from constructor parameters to the temporary will follow. - * - * \return - * An \c ir_dereference_variable of the temprorary generated in the constructor - * body. - */ -ir_rvalue * -emit_inline_matrix_constructor(const glsl_type *type, - exec_list *instructions, - exec_list *parameters, - void *ctx) -{ - assert(!parameters->is_empty()); - - ir_variable *var = new(ctx) ir_variable(type, "mat_ctor", ir_var_temporary); - instructions->push_tail(var); - - /* There are three kinds of matrix constructors. - * - * - Construct a matrix from a single scalar by replicating that scalar to - * along the diagonal of the matrix and setting all other components to - * zero. - * - * - Construct a matrix from an arbirary combination of vectors and - * scalars. The components of the constructor parameters are assigned - * to the matrix in colum-major order until the matrix is full. - * - * - Construct a matrix from a single matrix. The source matrix is copied - * to the upper left portion of the constructed matrix, and the remaining - * elements take values from the identity matrix. - */ - ir_rvalue *const first_param = (ir_rvalue *) parameters->head; - if (single_scalar_parameter(parameters)) { - /* Assign the scalar to the X component of a vec4, and fill the remaining - * components with zero. - */ - ir_variable *rhs_var = - new(ctx) ir_variable(glsl_type::vec4_type, "mat_ctor_vec", - ir_var_temporary); - instructions->push_tail(rhs_var); - - ir_constant_data zero; - zero.f[0] = 0.0; - zero.f[1] = 0.0; - zero.f[2] = 0.0; - zero.f[3] = 0.0; - - ir_instruction *inst = - new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var), - new(ctx) ir_constant(rhs_var->type, &zero), - NULL); - instructions->push_tail(inst); - - ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); - - inst = new(ctx) ir_assignment(rhs_ref, first_param, NULL, 0x01); - instructions->push_tail(inst); - - /* Assign the temporary vector to each column of the destination matrix - * with a swizzle that puts the X component on the diagonal of the - * matrix. In some cases this may mean that the X component does not - * get assigned into the column at all (i.e., when the matrix has more - * columns than rows). - */ - static const unsigned rhs_swiz[4][4] = { - { 0, 1, 1, 1 }, - { 1, 0, 1, 1 }, - { 1, 1, 0, 1 }, - { 1, 1, 1, 0 } - }; - - const unsigned cols_to_init = MIN2(type->matrix_columns, - type->vector_elements); - for (unsigned i = 0; i < cols_to_init; i++) { - ir_constant *const col_idx = new(ctx) ir_constant(i); - ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx); - - ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); - ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i], - type->vector_elements); - - inst = new(ctx) ir_assignment(col_ref, rhs, NULL); - instructions->push_tail(inst); - } - - for (unsigned i = cols_to_init; i < type->matrix_columns; i++) { - ir_constant *const col_idx = new(ctx) ir_constant(i); - ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx); - - ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); - ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1, - type->vector_elements); - - inst = new(ctx) ir_assignment(col_ref, rhs, NULL); - instructions->push_tail(inst); - } - } else if (first_param->type->is_matrix()) { - /* From page 50 (56 of the PDF) of the GLSL 1.50 spec: - * - * "If a matrix is constructed from a matrix, then each component - * (column i, row j) in the result that has a corresponding - * component (column i, row j) in the argument will be initialized - * from there. All other components will be initialized to the - * identity matrix. If a matrix argument is given to a matrix - * constructor, it is an error to have any other arguments." - */ - assert(first_param->next->is_tail_sentinel()); - ir_rvalue *const src_matrix = first_param; - - /* If the source matrix is smaller, pre-initialize the relavent parts of - * the destination matrix to the identity matrix. - */ - if ((src_matrix->type->matrix_columns < var->type->matrix_columns) - || (src_matrix->type->vector_elements < var->type->vector_elements)) { - - /* If the source matrix has fewer rows, every column of the destination - * must be initialized. Otherwise only the columns in the destination - * that do not exist in the source must be initialized. - */ - unsigned col = - (src_matrix->type->vector_elements < var->type->vector_elements) - ? 0 : src_matrix->type->matrix_columns; - - const glsl_type *const col_type = var->type->column_type(); - for (/* empty */; col < var->type->matrix_columns; col++) { - ir_constant_data ident; - - ident.f[0] = 0.0; - ident.f[1] = 0.0; - ident.f[2] = 0.0; - ident.f[3] = 0.0; - - ident.f[col] = 1.0; - - ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident); - - ir_rvalue *const lhs = - new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col)); - - ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(inst); - } - } - - /* Assign columns from the source matrix to the destination matrix. - * - * Since the parameter will be used in the RHS of multiple assignments, - * generate a temporary and copy the paramter there. - */ - ir_variable *const rhs_var = - new(ctx) ir_variable(first_param->type, "mat_ctor_mat", - ir_var_temporary); - instructions->push_tail(rhs_var); - - ir_dereference *const rhs_var_ref = - new(ctx) ir_dereference_variable(rhs_var); - ir_instruction *const inst = - new(ctx) ir_assignment(rhs_var_ref, first_param, NULL); - instructions->push_tail(inst); - - const unsigned last_row = MIN2(src_matrix->type->vector_elements, - var->type->vector_elements); - const unsigned last_col = MIN2(src_matrix->type->matrix_columns, - var->type->matrix_columns); - - unsigned swiz[4] = { 0, 0, 0, 0 }; - for (unsigned i = 1; i < last_row; i++) - swiz[i] = i; - - const unsigned write_mask = (1U << last_row) - 1; - - for (unsigned i = 0; i < last_col; i++) { - ir_dereference *const lhs = - new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i)); - ir_rvalue *const rhs_col = - new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i)); - - /* If one matrix has columns that are smaller than the columns of the - * other matrix, wrap the column access of the larger with a swizzle - * so that the LHS and RHS of the assignment have the same size (and - * therefore have the same type). - * - * It would be perfectly valid to unconditionally generate the - * swizzles, this this will typically result in a more compact IR tree. - */ - ir_rvalue *rhs; - if (lhs->type->vector_elements != rhs_col->type->vector_elements) { - rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row); - } else { - rhs = rhs_col; - } - - ir_instruction *inst = - new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); - instructions->push_tail(inst); - } - } else { - const unsigned cols = type->matrix_columns; - const unsigned rows = type->vector_elements; - unsigned col_idx = 0; - unsigned row_idx = 0; - - foreach_list (node, parameters) { - ir_rvalue *const rhs = (ir_rvalue *) node; - const unsigned components_remaining_this_column = rows - row_idx; - unsigned rhs_components = rhs->type->components(); - unsigned rhs_base = 0; - - /* Since the parameter might be used in the RHS of two assignments, - * generate a temporary and copy the paramter there. - */ - ir_variable *rhs_var = - new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary); - instructions->push_tail(rhs_var); - - ir_dereference *rhs_var_ref = - new(ctx) ir_dereference_variable(rhs_var); - ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL); - instructions->push_tail(inst); - - /* Assign the current parameter to as many components of the matrix - * as it will fill. - * - * NOTE: A single vector parameter can span two matrix columns. A - * single vec4, for example, can completely fill a mat2. - */ - if (rhs_components >= components_remaining_this_column) { - const unsigned count = MIN2(rhs_components, - components_remaining_this_column); - - rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var); - - ir_instruction *inst = assign_to_matrix_column(var, col_idx, - row_idx, - rhs_var_ref, 0, - count, ctx); - instructions->push_tail(inst); - - rhs_base = count; - - col_idx++; - row_idx = 0; - } - - /* If there is data left in the parameter and components left to be - * set in the destination, emit another assignment. It is possible - * that the assignment could be of a vec4 to the last element of the - * matrix. In this case col_idx==cols, but there is still data - * left in the source parameter. Obviously, don't emit an assignment - * to data outside the destination matrix. - */ - if ((col_idx < cols) && (rhs_base < rhs_components)) { - const unsigned count = rhs_components - rhs_base; - - rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var); - - ir_instruction *inst = assign_to_matrix_column(var, col_idx, - row_idx, - rhs_var_ref, - rhs_base, - count, ctx); - instructions->push_tail(inst); - - row_idx += count; - } - } - } - - return new(ctx) ir_dereference_variable(var); -} - - -ir_rvalue * -emit_inline_record_constructor(const glsl_type *type, - exec_list *instructions, - exec_list *parameters, - void *mem_ctx) -{ - ir_variable *const var = - new(mem_ctx) ir_variable(type, "record_ctor", ir_var_temporary); - ir_dereference_variable *const d = new(mem_ctx) ir_dereference_variable(var); - - instructions->push_tail(var); - - exec_node *node = parameters->head; - for (unsigned i = 0; i < type->length; i++) { - assert(!node->is_tail_sentinel()); - - ir_dereference *const lhs = - new(mem_ctx) ir_dereference_record(d->clone(mem_ctx, NULL), - type->fields.structure[i].name); - - ir_rvalue *const rhs = ((ir_instruction *) node)->as_rvalue(); - assert(rhs != NULL); - - ir_instruction *const assign = new(mem_ctx) ir_assignment(lhs, rhs, NULL); - - instructions->push_tail(assign); - node = node->next; - } - - return d; -} - - -ir_rvalue * -ast_function_expression::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - /* There are three sorts of function calls. - * - * 1. constructors - 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()) - return ir_call::get_error_instruction(ctx); - - /* 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; - - foreach_list (n, &this->expressions) { - ast_node *ast = exec_node_data(ast_node, n, link); - ir_rvalue *result = ast->hir(instructions, state)->as_rvalue(); - - /* 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++; - - actual_parameters.push_tail(result); - components_used += result->type->components(); - } - - /* 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 - && matrix_parameters == 0) { - _mesa_glsl_error(& loc, state, "too few components to construct " - "`%s'", - constructor_type->name); - return ir_call::get_error_instruction(ctx); - } - - /* Later, we cast each parameter to the same base type as the - * constructor. Since there are no non-floating point matrices, we - * need to break them up into a series of column vectors. - */ - if (constructor_type->base_type != GLSL_TYPE_FLOAT) { - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *matrix = (ir_rvalue *) n; - - if (!matrix->type->is_matrix()) - continue; - - /* Create a temporary containing the matrix. */ - ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp", - ir_var_temporary); - instructions->push_tail(var); - instructions->push_tail(new(ctx) ir_assignment(new(ctx) - ir_dereference_variable(var), matrix, NULL)); - var->constant_value = matrix->constant_expression_value(); - - /* Replace the matrix with dereferences of its columns. */ - for (int i = 0; i < matrix->type->matrix_columns; i++) { - matrix->insert_before(new (ctx) ir_dereference_array(var, - new(ctx) ir_constant(i))); - } - matrix->remove(); - } - } - - bool all_parameters_are_constant = true; - - /* Type cast each parameter and, if possible, fold constants.*/ - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *ir = (ir_rvalue *) n; - - const glsl_type *desired_type = - glsl_type::get_instance(constructor_type->base_type, - ir->type->vector_elements, - ir->type->matrix_columns); - ir_rvalue *result = convert_component(ir, desired_type); - - /* 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; - - if (result != ir) { - ir->replace_with(result); - } - } - - /* If all of the parameters are trivially constant, create a - * constant representing the complete collection of parameters. - */ - if (all_parameters_are_constant) { - return new(ctx) ir_constant(constructor_type, &actual_parameters); - } else if (constructor_type->is_scalar()) { - return dereference_component((ir_rvalue *) actual_parameters.head, - 0); - } else if (constructor_type->is_vector()) { - return emit_inline_vector_constructor(constructor_type, - instructions, - &actual_parameters, - ctx); - } else { - assert(constructor_type->is_matrix()); - return emit_inline_matrix_constructor(constructor_type, - instructions, - &actual_parameters, - 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()) { - exec_node *node = actual_parameters.head; - for (unsigned i = 0; i < type->length; i++) { - ir_rvalue *ir = (ir_rvalue *) node; - - if (node->is_tail_sentinel()) { - _mesa_glsl_error(&loc, state, - "insufficient parameters to constructor " - "for `%s'", - type->name); - return ir_call::get_error_instruction(ctx); - } - - if (apply_implicit_conversion(type->fields.structure[i].type, ir, - state)) { - node->replace_with(ir); - } else { - _mesa_glsl_error(&loc, state, - "parameter type mismatch in constructor " - "for `%s.%s' (%s vs %s)", - type->name, - type->fields.structure[i].name, - ir->type->name, - type->fields.structure[i].type->name); - return ir_call::get_error_instruction(ctx);; - } - - node = node->next; - } - - if (!node->is_tail_sentinel()) { - _mesa_glsl_error(&loc, state, "too many parameters in constructor " - "for `%s'", type->name); - return ir_call::get_error_instruction(ctx); - } - - ir_rvalue *const constant = - constant_record_constructor(type, &actual_parameters, state); - - return (constant != NULL) - ? constant - : emit_inline_record_constructor(type, instructions, - &actual_parameters, state); - } - - return match_function_by_name(instructions, - id->primary_expression.identifier, & loc, - &actual_parameters, state); - } - - return ir_call::get_error_instruction(ctx); -} +/*
+ * 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"
+#include "main/core.h" /* for MIN2 */
+
+static ir_rvalue *
+convert_component(ir_rvalue *src, const glsl_type *desired_type);
+
+bool
+apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
+ struct _mesa_glsl_parse_state *state);
+
+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;
+}
+
+
+/**
+ * Generate a source prototype for a function signature
+ *
+ * \param return_type Return type of the function. May be \c NULL.
+ * \param name Name of the function.
+ * \param parameters Parameter list for the function. This may be either a
+ * formal or actual parameter list. Only the type is used.
+ *
+ * \return
+ * A talloced string representing the prototype of the function.
+ */
+char *
+prototype_string(const glsl_type *return_type, const char *name,
+ exec_list *parameters)
+{
+ char *str = NULL;
+
+ if (return_type != NULL)
+ str = talloc_asprintf(str, "%s ", return_type->name);
+
+ str = talloc_asprintf_append(str, "%s(", name);
+
+ const char *comma = "";
+ foreach_list(node, parameters) {
+ const ir_instruction *const param = (ir_instruction *) node;
+
+ str = talloc_asprintf_append(str, "%s%s", comma, param->type->name);
+ comma = ", ";
+ }
+
+ str = talloc_strdup_append(str, ")");
+ return str;
+}
+
+
+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 = state;
+ ir_function *f = state->symbols->get_function(name);
+ ir_function_signature *sig;
+
+ sig = f ? f->matching_signature(actual_parameters) : NULL;
+
+ /* FINISHME: This doesn't handle the case where shader X contains a
+ * FINISHME: matching signature but shader X + N contains an _exact_
+ * FINISHME: matching signature.
+ */
+ if (sig == NULL && (f == NULL || state->es_shader || !f->has_user_signature()) && state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) {
+ /* The current shader doesn't contain a matching function or signature.
+ * Before giving up, look for the prototype in the built-in functions.
+ */
+ for (unsigned i = 0; i < state->num_builtins_to_link; i++) {
+ ir_function *builtin;
+ builtin = state->builtins_to_link[i]->symbols->get_function(name);
+ sig = builtin ? builtin->matching_signature(actual_parameters) : NULL;
+ if (sig != NULL) {
+ if (f == NULL) {
+ f = new(ctx) ir_function(name);
+ state->symbols->add_global_function(f);
+ emit_function(state, instructions, f);
+ }
+
+ f->add_signature(sig->clone_prototype(f, NULL));
+ break;
+ }
+ }
+ }
+
+ 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");
+ }
+ }
+
+ if (formal->type->is_numeric() || formal->type->is_boolean()) {
+ ir_rvalue *converted = convert_component(actual, formal->type);
+ actual->replace_with(converted);
+ }
+
+ actual_iter.next();
+ formal_iter.next();
+ }
+
+ /* Always insert the call in the instruction stream, and return a deref
+ * of its return val if it returns a value, since we don't know if
+ * the rvalue is going to be assigned to anything or not.
+ */
+ ir_call *call = new(ctx) ir_call(sig, actual_parameters);
+ if (!sig->return_type->is_void()) {
+ ir_variable *var;
+ ir_dereference_variable *deref;
+
+ var = new(ctx) ir_variable(sig->return_type,
+ talloc_asprintf(ctx, "%s_retval",
+ sig->function_name()),
+ ir_var_temporary);
+ instructions->push_tail(var);
+
+ deref = new(ctx) ir_dereference_variable(var);
+ ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL);
+ instructions->push_tail(assign);
+ if (state->language_version >= 120)
+ var->constant_value = call->constant_expression_value();
+
+ deref = new(ctx) ir_dereference_variable(var);
+ return deref;
+ } else {
+ instructions->push_tail(call);
+ return NULL;
+ }
+ } else {
+ char *str = prototype_string(NULL, name, actual_parameters);
+
+ _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
+ str);
+ talloc_free(str);
+
+ const char *prefix = "candidates are: ";
+
+ for (int i = -1; i < state->num_builtins_to_link; i++) {
+ glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols
+ : state->symbols;
+ f = syms->get_function(name);
+ if (f == NULL)
+ continue;
+
+ foreach_list (node, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) node;
+
+ str = prototype_string(sig->return_type, f->name, &sig->parameters);
+ _mesa_glsl_error(loc, state, "%s%s\n", prefix, str);
+ talloc_free(str);
+
+ prefix = " ";
+ }
+
+ }
+
+ return ir_call::get_error_instruction(ctx);
+ }
+}
+
+
+/**
+ * Perform automatic type conversion of constructor parameters
+ *
+ * This implements the rules in the "Conversion and Scalar Constructors"
+ * section (GLSL 1.10 section 5.4.1), not the "Implicit Conversions" rules.
+ */
+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:
+ switch (b) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL);
+ break;
+ case GLSL_TYPE_FLOAT:
+ result = new(ctx) ir_expression(ir_unop_f2b, desired_type, src, NULL);
+ break;
+ }
+ break;
+ }
+
+ assert(result != NULL);
+
+ /* Try constant folding; it may fold in the conversion we just added. */
+ 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 = 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(constructor_type->element_type(),
+ parameter_count);
+ assert(constructor_type != NULL);
+ assert(constructor_type->length == parameter_count);
+ }
+
+ bool all_parameters_are_constant = true;
+
+ /* Type cast each parameter and, if possible, fold constants. */
+ foreach_list_safe(n, &actual_parameters) {
+ ir_rvalue *ir = (ir_rvalue *) n;
+ ir_rvalue *result = ir;
+
+ /* Apply implicit conversions (not the scalar constructor rules!) */
+ if (constructor_type->element_type()->is_float()) {
+ const glsl_type *desired_type =
+ glsl_type::get_instance(GLSL_TYPE_FLOAT,
+ ir->type->vector_elements,
+ ir->type->matrix_columns);
+ result = convert_component(ir, desired_type);
+ }
+
+ if (result->type != constructor_type->element_type()) {
+ _mesa_glsl_error(loc, state, "type error in array constructor: "
+ "expected: %s, found %s",
+ constructor_type->element_type()->name,
+ result->type->name);
+ }
+
+ /* 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;
+
+ ir->replace_with(result);
+ }
+
+ if (all_parameters_are_constant)
+ return new(ctx) ir_constant(constructor_type, &actual_parameters);
+
+ ir_variable *var = new(ctx) ir_variable(constructor_type, "array_ctor",
+ ir_var_temporary);
+ instructions->push_tail(var);
+
+ int i = 0;
+ foreach_list(node, &actual_parameters) {
+ ir_rvalue *rhs = (ir_rvalue *) node;
+ ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
+ new(ctx) ir_constant(i));
+
+ ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
+ instructions->push_tail(assignment);
+
+ i++;
+ }
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+
+/**
+ * Try to convert a record constructor to a constant expression
+ */
+static ir_constant *
+constant_record_constructor(const glsl_type *constructor_type,
+ exec_list *parameters, void *mem_ctx)
+{
+ foreach_list(node, parameters) {
+ ir_constant *constant = ((ir_instruction *) node)->as_constant();
+ if (constant == NULL)
+ return NULL;
+ node->replace_with(constant);
+ }
+
+ return new(mem_ctx) ir_constant(constructor_type, parameters);
+}
+
+
+/**
+ * Determine if a list consists of a single scalar r-value
+ */
+bool
+single_scalar_parameter(exec_list *parameters)
+{
+ const ir_rvalue *const p = (ir_rvalue *) parameters->head;
+ assert(((ir_rvalue *)p)->as_rvalue() != NULL);
+
+ return (p->type->is_scalar() && p->next->is_tail_sentinel());
+}
+
+
+/**
+ * Generate inline code for a vector constructor
+ *
+ * The generated constructor code will consist of a temporary variable
+ * declaration of the same type as the constructor. A sequence of assignments
+ * from constructor parameters to the temporary will follow.
+ *
+ * \return
+ * An \c ir_dereference_variable of the temprorary generated in the constructor
+ * body.
+ */
+ir_rvalue *
+emit_inline_vector_constructor(const glsl_type *type,
+ exec_list *instructions,
+ exec_list *parameters,
+ void *ctx)
+{
+ assert(!parameters->is_empty());
+
+ ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary);
+ instructions->push_tail(var);
+
+ /* There are two kinds of vector constructors.
+ *
+ * - Construct a vector from a single scalar by replicating that scalar to
+ * all components of the vector.
+ *
+ * - Construct a vector from an arbirary combination of vectors and
+ * scalars. The components of the constructor parameters are assigned
+ * to the vector in order until the vector is full.
+ */
+ const unsigned lhs_components = type->components();
+ if (single_scalar_parameter(parameters)) {
+ ir_rvalue *first_param = (ir_rvalue *)parameters->head;
+ ir_rvalue *rhs = new(ctx) ir_swizzle(first_param, 0, 0, 0, 0,
+ lhs_components);
+ ir_dereference_variable *lhs = new(ctx) ir_dereference_variable(var);
+ const unsigned mask = (1U << lhs_components) - 1;
+
+ assert(rhs->type == lhs->type);
+
+ ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL, mask);
+ instructions->push_tail(inst);
+ } else {
+ unsigned base_component = 0;
+ unsigned base_lhs_component = 0;
+ ir_constant_data data;
+ unsigned constant_mask = 0, constant_components = 0;
+
+ memset(&data, 0, sizeof(data));
+
+ foreach_list(node, parameters) {
+ ir_rvalue *param = (ir_rvalue *) node;
+ unsigned rhs_components = param->type->components();
+
+ /* Do not try to assign more components to the vector than it has!
+ */
+ if ((rhs_components + base_lhs_component) > lhs_components) {
+ rhs_components = lhs_components - base_lhs_component;
+ }
+
+ const ir_constant *const c = param->as_constant();
+ if (c != NULL) {
+ for (unsigned i = 0; i < rhs_components; i++) {
+ switch (c->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[i + base_component] = c->get_uint_component(i);
+ break;
+ case GLSL_TYPE_INT:
+ data.i[i + base_component] = c->get_int_component(i);
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[i + base_component] = c->get_float_component(i);
+ break;
+ case GLSL_TYPE_BOOL:
+ data.b[i + base_component] = c->get_bool_component(i);
+ break;
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ }
+
+ /* Mask of fields to be written in the assignment.
+ */
+ constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component;
+ constant_components += rhs_components;
+
+ base_component += rhs_components;
+ }
+ /* Advance the component index by the number of components
+ * that were just assigned.
+ */
+ base_lhs_component += rhs_components;
+ }
+
+ if (constant_mask != 0) {
+ ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
+ const glsl_type *rhs_type = glsl_type::get_instance(var->type->base_type,
+ constant_components,
+ 1);
+ ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data);
+
+ ir_instruction *inst =
+ new(ctx) ir_assignment(lhs, rhs, NULL, constant_mask);
+ instructions->push_tail(inst);
+ }
+
+ base_component = 0;
+ foreach_list(node, parameters) {
+ ir_rvalue *param = (ir_rvalue *) node;
+ unsigned rhs_components = param->type->components();
+
+ /* Do not try to assign more components to the vector than it has!
+ */
+ if ((rhs_components + base_component) > lhs_components) {
+ rhs_components = lhs_components - base_component;
+ }
+
+ const ir_constant *const c = param->as_constant();
+ if (c == NULL) {
+ /* Mask of fields to be written in the assignment.
+ */
+ const unsigned write_mask = ((1U << rhs_components) - 1)
+ << base_component;
+
+ ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
+
+ /* Generate a swizzle so that LHS and RHS sizes match.
+ */
+ ir_rvalue *rhs =
+ new(ctx) ir_swizzle(param, 0, 1, 2, 3, rhs_components);
+
+ ir_instruction *inst =
+ new(ctx) ir_assignment(lhs, rhs, NULL, write_mask);
+ instructions->push_tail(inst);
+ }
+
+ /* Advance the component index by the number of components that were
+ * just assigned.
+ */
+ base_component += rhs_components;
+ }
+ }
+ return new(ctx) ir_dereference_variable(var);
+}
+
+
+/**
+ * Generate assignment of a portion of a vector to a portion of a matrix column
+ *
+ * \param src_base First component of the source to be used in assignment
+ * \param column Column of destination to be assiged
+ * \param row_base First component of the destination column to be assigned
+ * \param count Number of components to be assigned
+ *
+ * \note
+ * \c src_base + \c count must be less than or equal to the number of components
+ * in the source vector.
+ */
+ir_instruction *
+assign_to_matrix_column(ir_variable *var, unsigned column, unsigned row_base,
+ ir_rvalue *src, unsigned src_base, unsigned count,
+ void *mem_ctx)
+{
+ ir_constant *col_idx = new(mem_ctx) ir_constant(column);
+ ir_dereference *column_ref = new(mem_ctx) ir_dereference_array(var, col_idx);
+
+ assert(column_ref->type->components() >= (row_base + count));
+ assert(src->type->components() >= (src_base + count));
+
+ /* Generate a swizzle that extracts the number of components from the source
+ * that are to be assigned to the column of the matrix.
+ */
+ if (count < src->type->vector_elements) {
+ src = new(mem_ctx) ir_swizzle(src,
+ src_base + 0, src_base + 1,
+ src_base + 2, src_base + 3,
+ count);
+ }
+
+ /* Mask of fields to be written in the assignment.
+ */
+ const unsigned write_mask = ((1U << count) - 1) << row_base;
+
+ return new(mem_ctx) ir_assignment(column_ref, src, NULL, write_mask);
+}
+
+
+/**
+ * Generate inline code for a matrix constructor
+ *
+ * The generated constructor code will consist of a temporary variable
+ * declaration of the same type as the constructor. A sequence of assignments
+ * from constructor parameters to the temporary will follow.
+ *
+ * \return
+ * An \c ir_dereference_variable of the temprorary generated in the constructor
+ * body.
+ */
+ir_rvalue *
+emit_inline_matrix_constructor(const glsl_type *type,
+ exec_list *instructions,
+ exec_list *parameters,
+ void *ctx)
+{
+ assert(!parameters->is_empty());
+
+ ir_variable *var = new(ctx) ir_variable(type, "mat_ctor", ir_var_temporary);
+ instructions->push_tail(var);
+
+ /* There are three kinds of matrix constructors.
+ *
+ * - Construct a matrix from a single scalar by replicating that scalar to
+ * along the diagonal of the matrix and setting all other components to
+ * zero.
+ *
+ * - Construct a matrix from an arbirary combination of vectors and
+ * scalars. The components of the constructor parameters are assigned
+ * to the matrix in colum-major order until the matrix is full.
+ *
+ * - Construct a matrix from a single matrix. The source matrix is copied
+ * to the upper left portion of the constructed matrix, and the remaining
+ * elements take values from the identity matrix.
+ */
+ ir_rvalue *const first_param = (ir_rvalue *) parameters->head;
+ if (single_scalar_parameter(parameters)) {
+ /* Assign the scalar to the X component of a vec4, and fill the remaining
+ * components with zero.
+ */
+ ir_variable *rhs_var =
+ new(ctx) ir_variable(glsl_type::vec4_type, "mat_ctor_vec",
+ ir_var_temporary);
+ instructions->push_tail(rhs_var);
+
+ ir_constant_data zero;
+ zero.f[0] = 0.0;
+ zero.f[1] = 0.0;
+ zero.f[2] = 0.0;
+ zero.f[3] = 0.0;
+
+ ir_instruction *inst =
+ new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var),
+ new(ctx) ir_constant(rhs_var->type, &zero),
+ NULL);
+ instructions->push_tail(inst);
+
+ ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
+
+ inst = new(ctx) ir_assignment(rhs_ref, first_param, NULL, 0x01);
+ instructions->push_tail(inst);
+
+ /* Assign the temporary vector to each column of the destination matrix
+ * with a swizzle that puts the X component on the diagonal of the
+ * matrix. In some cases this may mean that the X component does not
+ * get assigned into the column at all (i.e., when the matrix has more
+ * columns than rows).
+ */
+ static const unsigned rhs_swiz[4][4] = {
+ { 0, 1, 1, 1 },
+ { 1, 0, 1, 1 },
+ { 1, 1, 0, 1 },
+ { 1, 1, 1, 0 }
+ };
+
+ const unsigned cols_to_init = MIN2(type->matrix_columns,
+ type->vector_elements);
+ for (unsigned i = 0; i < cols_to_init; i++) {
+ ir_constant *const col_idx = new(ctx) ir_constant(i);
+ ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx);
+
+ ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
+ ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i],
+ type->vector_elements);
+
+ inst = new(ctx) ir_assignment(col_ref, rhs, NULL);
+ instructions->push_tail(inst);
+ }
+
+ for (unsigned i = cols_to_init; i < type->matrix_columns; i++) {
+ ir_constant *const col_idx = new(ctx) ir_constant(i);
+ ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx);
+
+ ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
+ ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1,
+ type->vector_elements);
+
+ inst = new(ctx) ir_assignment(col_ref, rhs, NULL);
+ instructions->push_tail(inst);
+ }
+ } else if (first_param->type->is_matrix()) {
+ /* From page 50 (56 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "If a matrix is constructed from a matrix, then each component
+ * (column i, row j) in the result that has a corresponding
+ * component (column i, row j) in the argument will be initialized
+ * from there. All other components will be initialized to the
+ * identity matrix. If a matrix argument is given to a matrix
+ * constructor, it is an error to have any other arguments."
+ */
+ assert(first_param->next->is_tail_sentinel());
+ ir_rvalue *const src_matrix = first_param;
+
+ /* If the source matrix is smaller, pre-initialize the relavent parts of
+ * the destination matrix to the identity matrix.
+ */
+ if ((src_matrix->type->matrix_columns < var->type->matrix_columns)
+ || (src_matrix->type->vector_elements < var->type->vector_elements)) {
+
+ /* If the source matrix has fewer rows, every column of the destination
+ * must be initialized. Otherwise only the columns in the destination
+ * that do not exist in the source must be initialized.
+ */
+ unsigned col =
+ (src_matrix->type->vector_elements < var->type->vector_elements)
+ ? 0 : src_matrix->type->matrix_columns;
+
+ const glsl_type *const col_type = var->type->column_type();
+ for (/* empty */; col < var->type->matrix_columns; col++) {
+ ir_constant_data ident;
+
+ ident.f[0] = 0.0;
+ ident.f[1] = 0.0;
+ ident.f[2] = 0.0;
+ ident.f[3] = 0.0;
+
+ ident.f[col] = 1.0;
+
+ ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident);
+
+ ir_rvalue *const lhs =
+ new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col));
+
+ ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL);
+ instructions->push_tail(inst);
+ }
+ }
+
+ /* Assign columns from the source matrix to the destination matrix.
+ *
+ * Since the parameter will be used in the RHS of multiple assignments,
+ * generate a temporary and copy the paramter there.
+ */
+ ir_variable *const rhs_var =
+ new(ctx) ir_variable(first_param->type, "mat_ctor_mat",
+ ir_var_temporary);
+ instructions->push_tail(rhs_var);
+
+ ir_dereference *const rhs_var_ref =
+ new(ctx) ir_dereference_variable(rhs_var);
+ ir_instruction *const inst =
+ new(ctx) ir_assignment(rhs_var_ref, first_param, NULL);
+ instructions->push_tail(inst);
+
+ const unsigned last_row = MIN2(src_matrix->type->vector_elements,
+ var->type->vector_elements);
+ const unsigned last_col = MIN2(src_matrix->type->matrix_columns,
+ var->type->matrix_columns);
+
+ unsigned swiz[4] = { 0, 0, 0, 0 };
+ for (unsigned i = 1; i < last_row; i++)
+ swiz[i] = i;
+
+ const unsigned write_mask = (1U << last_row) - 1;
+
+ for (unsigned i = 0; i < last_col; i++) {
+ ir_dereference *const lhs =
+ new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i));
+ ir_rvalue *const rhs_col =
+ new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i));
+
+ /* If one matrix has columns that are smaller than the columns of the
+ * other matrix, wrap the column access of the larger with a swizzle
+ * so that the LHS and RHS of the assignment have the same size (and
+ * therefore have the same type).
+ *
+ * It would be perfectly valid to unconditionally generate the
+ * swizzles, this this will typically result in a more compact IR tree.
+ */
+ ir_rvalue *rhs;
+ if (lhs->type->vector_elements != rhs_col->type->vector_elements) {
+ rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row);
+ } else {
+ rhs = rhs_col;
+ }
+
+ ir_instruction *inst =
+ new(ctx) ir_assignment(lhs, rhs, NULL, write_mask);
+ instructions->push_tail(inst);
+ }
+ } else {
+ const unsigned cols = type->matrix_columns;
+ const unsigned rows = type->vector_elements;
+ unsigned col_idx = 0;
+ unsigned row_idx = 0;
+
+ foreach_list (node, parameters) {
+ ir_rvalue *const rhs = (ir_rvalue *) node;
+ const unsigned components_remaining_this_column = rows - row_idx;
+ unsigned rhs_components = rhs->type->components();
+ unsigned rhs_base = 0;
+
+ /* Since the parameter might be used in the RHS of two assignments,
+ * generate a temporary and copy the paramter there.
+ */
+ ir_variable *rhs_var =
+ new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary);
+ instructions->push_tail(rhs_var);
+
+ ir_dereference *rhs_var_ref =
+ new(ctx) ir_dereference_variable(rhs_var);
+ ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL);
+ instructions->push_tail(inst);
+
+ /* Assign the current parameter to as many components of the matrix
+ * as it will fill.
+ *
+ * NOTE: A single vector parameter can span two matrix columns. A
+ * single vec4, for example, can completely fill a mat2.
+ */
+ if (rhs_components >= components_remaining_this_column) {
+ const unsigned count = MIN2(rhs_components,
+ components_remaining_this_column);
+
+ rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
+
+ ir_instruction *inst = assign_to_matrix_column(var, col_idx,
+ row_idx,
+ rhs_var_ref, 0,
+ count, ctx);
+ instructions->push_tail(inst);
+
+ rhs_base = count;
+
+ col_idx++;
+ row_idx = 0;
+ }
+
+ /* If there is data left in the parameter and components left to be
+ * set in the destination, emit another assignment. It is possible
+ * that the assignment could be of a vec4 to the last element of the
+ * matrix. In this case col_idx==cols, but there is still data
+ * left in the source parameter. Obviously, don't emit an assignment
+ * to data outside the destination matrix.
+ */
+ if ((col_idx < cols) && (rhs_base < rhs_components)) {
+ const unsigned count = rhs_components - rhs_base;
+
+ rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
+
+ ir_instruction *inst = assign_to_matrix_column(var, col_idx,
+ row_idx,
+ rhs_var_ref,
+ rhs_base,
+ count, ctx);
+ instructions->push_tail(inst);
+
+ row_idx += count;
+ }
+ }
+ }
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+
+ir_rvalue *
+emit_inline_record_constructor(const glsl_type *type,
+ exec_list *instructions,
+ exec_list *parameters,
+ void *mem_ctx)
+{
+ ir_variable *const var =
+ new(mem_ctx) ir_variable(type, "record_ctor", ir_var_temporary);
+ ir_dereference_variable *const d = new(mem_ctx) ir_dereference_variable(var);
+
+ instructions->push_tail(var);
+
+ exec_node *node = parameters->head;
+ for (unsigned i = 0; i < type->length; i++) {
+ assert(!node->is_tail_sentinel());
+
+ ir_dereference *const lhs =
+ new(mem_ctx) ir_dereference_record(d->clone(mem_ctx, NULL),
+ type->fields.structure[i].name);
+
+ ir_rvalue *const rhs = ((ir_instruction *) node)->as_rvalue();
+ assert(rhs != NULL);
+
+ ir_instruction *const assign = new(mem_ctx) ir_assignment(lhs, rhs, NULL);
+
+ instructions->push_tail(assign);
+ node = node->next;
+ }
+
+ return d;
+}
+
+
+ir_rvalue *
+ast_function_expression::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ /* There are three sorts of function calls.
+ *
+ * 1. constructors - 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())
+ return ir_call::get_error_instruction(ctx);
+
+ /* 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;
+
+ foreach_list (n, &this->expressions) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ir_rvalue *result = ast->hir(instructions, state)->as_rvalue();
+
+ /* 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++;
+
+ actual_parameters.push_tail(result);
+ components_used += result->type->components();
+ }
+
+ /* 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
+ && matrix_parameters == 0) {
+ _mesa_glsl_error(& loc, state, "too few components to construct "
+ "`%s'",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ /* Later, we cast each parameter to the same base type as the
+ * constructor. Since there are no non-floating point matrices, we
+ * need to break them up into a series of column vectors.
+ */
+ if (constructor_type->base_type != GLSL_TYPE_FLOAT) {
+ foreach_list_safe(n, &actual_parameters) {
+ ir_rvalue *matrix = (ir_rvalue *) n;
+
+ if (!matrix->type->is_matrix())
+ continue;
+
+ /* Create a temporary containing the matrix. */
+ ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp",
+ ir_var_temporary);
+ instructions->push_tail(var);
+ instructions->push_tail(new(ctx) ir_assignment(new(ctx)
+ ir_dereference_variable(var), matrix, NULL));
+ var->constant_value = matrix->constant_expression_value();
+
+ /* Replace the matrix with dereferences of its columns. */
+ for (int i = 0; i < matrix->type->matrix_columns; i++) {
+ matrix->insert_before(new (ctx) ir_dereference_array(var,
+ new(ctx) ir_constant(i)));
+ }
+ matrix->remove();
+ }
+ }
+
+ bool all_parameters_are_constant = true;
+
+ /* Type cast each parameter and, if possible, fold constants.*/
+ foreach_list_safe(n, &actual_parameters) {
+ ir_rvalue *ir = (ir_rvalue *) n;
+
+ const glsl_type *desired_type =
+ glsl_type::get_instance(constructor_type->base_type,
+ ir->type->vector_elements,
+ ir->type->matrix_columns);
+ ir_rvalue *result = convert_component(ir, desired_type);
+
+ /* 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;
+
+ if (result != ir) {
+ ir->replace_with(result);
+ }
+ }
+
+ /* If all of the parameters are trivially constant, create a
+ * constant representing the complete collection of parameters.
+ */
+ if (all_parameters_are_constant) {
+ return new(ctx) ir_constant(constructor_type, &actual_parameters);
+ } else if (constructor_type->is_scalar()) {
+ return dereference_component((ir_rvalue *) actual_parameters.head,
+ 0);
+ } else if (constructor_type->is_vector()) {
+ return emit_inline_vector_constructor(constructor_type,
+ instructions,
+ &actual_parameters,
+ ctx);
+ } else {
+ assert(constructor_type->is_matrix());
+ return emit_inline_matrix_constructor(constructor_type,
+ instructions,
+ &actual_parameters,
+ 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()) {
+ exec_node *node = actual_parameters.head;
+ for (unsigned i = 0; i < type->length; i++) {
+ ir_rvalue *ir = (ir_rvalue *) node;
+
+ if (node->is_tail_sentinel()) {
+ _mesa_glsl_error(&loc, state,
+ "insufficient parameters to constructor "
+ "for `%s'",
+ type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ if (apply_implicit_conversion(type->fields.structure[i].type, ir,
+ state)) {
+ node->replace_with(ir);
+ } else {
+ _mesa_glsl_error(&loc, state,
+ "parameter type mismatch in constructor "
+ "for `%s.%s' (%s vs %s)",
+ type->name,
+ type->fields.structure[i].name,
+ ir->type->name,
+ type->fields.structure[i].type->name);
+ return ir_call::get_error_instruction(ctx);;
+ }
+
+ node = node->next;
+ }
+
+ if (!node->is_tail_sentinel()) {
+ _mesa_glsl_error(&loc, state, "too many parameters in constructor "
+ "for `%s'", type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ ir_rvalue *const constant =
+ constant_record_constructor(type, &actual_parameters, state);
+
+ return (constant != NULL)
+ ? constant
+ : emit_inline_record_constructor(type, instructions,
+ &actual_parameters, state);
+ }
+
+ return match_function_by_name(instructions,
+ id->primary_expression.identifier, & loc,
+ &actual_parameters, state);
+ }
+
+ return ir_call::get_error_instruction(ctx);
+}
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 0cbb4315a..282bc3ff5 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -1,2769 +1,3086 @@ -/* - * 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/core.h" /* for struct gl_extensions */ -#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_functions(instructions, state); - - state->symbols->language_version = state->language_version; - - state->current_function = NULL; - - /* Section 4.2 of the GLSL 1.20 specification states: - * "The built-in functions are scoped in a scope outside the global scope - * users declare global variables in. That is, a shader's global scope, - * available for user-defined functions and global variables, is nested - * inside the scope containing the built-in functions." - * - * Since built-in functions like ftransform() access built-in variables, - * it follows that those must be in the outer scope as well. - * - * We push scope here to create this nesting effect...but don't pop. - * This way, a shader's globals are still in the symbol table for use - * by the linker. - */ - state->symbols->push_scope(); - - 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. - */ -bool -apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = 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; - - /* Convert to a floating point type with the same number of components - * as the original type - i.e. int to float, not int to vec4. - */ - to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements, - from->type->matrix_columns); - - 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) { - /* The resulting vector has a number of elements equal to - * the number of rows of matrix A. */ - const glsl_type *const type = - glsl_type::get_instance(type_a->base_type, - type_a->column_type()->vector_elements, - 1); - assert(type != glsl_type::error_type); - - return type; - } - } 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()) { - /* The resulting vector has a number of elements equal to - * the number of columns of matrix B. */ - const glsl_type *const type = - glsl_type::get_instance(type_a->base_type, - type_b->row_type()->vector_elements, - 1); - assert(type != glsl_type::error_type); - - return type; - } - } - - _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 = state; - bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); - - if (!error_emitted) { - if (!lhs->is_lvalue()) { - _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment"); - error_emitted = true; - } - - if (state->es_shader && lhs->type->is_array()) { - _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not " - "allowed in GLSL ES 1.00."); - 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(lhs->type->element_type(), - rhs->type->array_size()); - d->type = var->type; - } - } - - /* 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_var_temporary); - 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); - - if (!error_emitted) - instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var, NULL)); - - return new(ctx) ir_dereference_variable(var); -} - -static ir_rvalue * -get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) -{ - void *ctx = talloc_parent(lvalue); - ir_variable *var; - - var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp", - ir_var_temporary); - instructions->push_tail(var); - 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 = 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_all_equal, - ir_binop_any_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[3]; - 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); - - type = unary_arithmetic_result_type(op[0]->type, state, & loc); - - error_emitted = type->is_error(); - - 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: - op[0] = this->subexpressions[0]->hir(instructions, state); - op[1] = this->subexpressions[1]->hir(instructions, state); - - if (state->language_version < 130) { - _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30"); - error_emitted = true; - } - - if (!op[0]->type->is_integer()) { - _mesa_glsl_error(&loc, state, "LHS of `%s' must be an integer", - operator_string(this->oper)); - error_emitted = true; - } - - if (!op[1]->type->is_integer()) { - _mesa_glsl_error(&loc, state, "RHS of `%s' must be an integer", - operator_string(this->oper)); - error_emitted = true; - } - - if (op[0]->type->base_type != op[1]->type->base_type) { - _mesa_glsl_error(&loc, state, "operands of `%s' must have the same " - "base type", operator_string(this->oper)); - error_emitted = true; - } - - if (op[0]->type->is_vector() && op[1]->type->is_vector() - && op[0]->type->vector_elements != op[1]->type->vector_elements) { - _mesa_glsl_error(&loc, state, "operands of `%s' cannot be vectors of " - "different sizes", operator_string(this->oper)); - error_emitted = true; - } - - type = op[0]->type->is_scalar() ? op[1]->type : op[0]->type; - result = new(ctx) ir_expression(operations[this->oper], type, - op[0], op[1]); - error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); - break; - - case ast_bit_not: - op[0] = this->subexpressions[0]->hir(instructions, state); - - if (state->language_version < 130) { - _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30"); - error_emitted = true; - } - - if (!op[0]->type->is_integer()) { - _mesa_glsl_error(&loc, state, "operand of `~' must be an integer"); - error_emitted = true; - } - - type = op[0]->type; - result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL); - 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_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, - "and_tmp", - ir_var_temporary); - instructions->push_tail(tmp); - - 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_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_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, - "or_tmp", - ir_var_temporary); - instructions->push_tail(tmp); - - ir_if *const stmt = new(ctx) ir_if(op[0]); - instructions->push_tail(stmt); - - op[1] = this->subexpressions[1]->hir(&stmt->else_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, - op[0]->clone(ctx, 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); - - ir_rvalue *temp_rhs; - temp_rhs = new(ctx) ir_expression(operations[this->oper], type, - op[0], op[1]); - - result = do_assignment(instructions, state, - op[0]->clone(ctx, 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; - } - - /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec: - * - * "The second and third expressions must be the same type, but can - * be of any type other than an array." - */ - if ((state->language_version <= 110) && type->is_array()) { - _mesa_glsl_error(& loc, state, "Second and third operands of ?: " - "operator must not be arrays."); - error_emitted = true; - } - - 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 = - new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary); - instructions->push_tail(tmp); - - 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); - - ir_rvalue *temp_rhs; - temp_rhs = new(ctx) ir_expression(operations[this->oper], type, - op[0], op[1]); - - result = do_assignment(instructions, state, - op[0]->clone(ctx, 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); - - 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, op[0]->clone(ctx, NULL)); - - (void)do_assignment(instructions, state, - op[0]->clone(ctx, 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; - } - } else if (array->type->array_size() == 0) { - _mesa_glsl_error(&loc, state, "unsized array index must be constant"); - } else { - if (array->type->is_array()) { - /* whole_variable_referenced can return NULL if the array is a - * member of a structure. In this case it is safe to not update - * the max_array_access field because it is never used for fields - * of structures. - */ - ir_variable *v = array->whole_variable_referenced(); - if (v != NULL) - v->max_array_access = array->type->array_size(); - } - } - - 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(YYLTYPE *loc, 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]; - } - } - } - } else if (state->es_shader) { - /* Section 10.17 of the GLSL ES 1.00 specification states that unsized - * array declarations have been removed from the language. - */ - _mesa_glsl_error(loc, state, "unsized array declarations are not " - "allowed in GLSL ES 1.00."); - } - - return glsl_type::get_array_instance(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; - - type = state->symbols->get_type(this->type_name); - *name = this->type_name; - - if (this->is_array) { - YYLTYPE loc = this->get_location(); - type = process_array_type(&loc, type, this->array_size, state); - } - - return type; -} - - -static void -apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, - 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 there is no qualifier that changes the mode of the variable, leave - * the setting alone. - */ - 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; - - if (qual->flat) - var->interpolation = ir_var_flat; - else if (qual->noperspective) - var->interpolation = ir_var_noperspective; - else - var->interpolation = ir_var_smooth; - - var->pixel_center_integer = qual->pixel_center_integer; - var->origin_upper_left = qual->origin_upper_left; - if ((qual->origin_upper_left || qual->pixel_center_integer) - && (strcmp(var->name, "gl_FragCoord") != 0)) { - const char *const qual_string = (qual->origin_upper_left) - ? "origin_upper_left" : "pixel_center_integer"; - - _mesa_glsl_error(loc, state, - "layout qualifier `%s' can only be applied to " - "fragment shader input `gl_FragCoord'", - qual_string); - } - - if (var->type->is_array() && state->language_version != 110) { - var->array_lvalue = true; - } -} - - -ir_rvalue * -ast_declarator_list::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - const struct glsl_type *decl_type; - const char *type_name = NULL; - ir_rvalue *result = NULL; - YYLTYPE loc = this->get_location(); - - /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec: - * - * "To ensure that a particular output variable is invariant, it is - * necessary to use the invariant qualifier. It can either be used to - * qualify a previously declared variable as being invariant - * - * invariant gl_Position; // make existing gl_Position be invariant" - * - * In these cases the parser will set the 'invariant' flag in the declarator - * list, and the type will be NULL. - */ - if (this->invariant) { - assert(this->type == NULL); - - if (state->current_function != NULL) { - _mesa_glsl_error(& loc, state, - "All uses of `invariant' keyword must be at global " - "scope\n"); - } - - foreach_list_typed (ast_declaration, decl, link, &this->declarations) { - assert(!decl->is_array); - assert(decl->array_size == NULL); - assert(decl->initializer == NULL); - - ir_variable *const earlier = - state->symbols->get_variable(decl->identifier); - if (earlier == NULL) { - _mesa_glsl_error(& loc, state, - "Undeclared variable `%s' cannot be marked " - "invariant\n", decl->identifier); - } else if ((state->target == vertex_shader) - && (earlier->mode != ir_var_out)) { - _mesa_glsl_error(& loc, state, - "`%s' cannot be marked invariant, vertex shader " - "outputs only\n", decl->identifier); - } else if ((state->target == fragment_shader) - && (earlier->mode != ir_var_in)) { - _mesa_glsl_error(& loc, state, - "`%s' cannot be marked invariant, fragment shader " - "inputs only\n", decl->identifier); - } else { - earlier->invariant = true; - } - } - - /* Invariant redeclarations do not have r-values. - */ - return NULL; - } - - assert(this->type != NULL); - assert(!this->invariant); - - /* The type specifier may contain a structure definition. Process that - * before any of the variable declarations. - */ - (void) this->type->specifier->hir(instructions, state); - - decl_type = this->type->specifier->glsl_type(& type_name, state); - if (this->declarations.is_empty()) { - /* The only valid case where the declaration list can be empty is when - * the declaration is setting the default precision of a built-in type - * (e.g., 'precision highp vec4;'). - */ - - 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; - 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(&loc, decl_type, decl->array_size, - state); - } else { - var_type = decl_type; - } - - var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto); - - /* 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); - - if (this->type->qualifier.invariant) { - if ((state->target == vertex_shader) && !(var->mode == ir_var_out || - var->mode == ir_var_inout)) { - /* FINISHME: Note that this doesn't work for invariant on - * a function signature outval - */ - _mesa_glsl_error(& loc, state, - "`%s' cannot be marked invariant, vertex shader " - "outputs only\n", var->name); - } else if ((state->target == fragment_shader) && - !(var->mode == ir_var_in || var->mode == ir_var_inout)) { - /* FINISHME: Note that this doesn't work for invariant on - * a function signature inval - */ - _mesa_glsl_error(& loc, state, - "`%s' cannot be marked invariant, fragment shader " - "inputs only\n", var->name); - } - } - - 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; - } - } - } - - /* Process the initializer and add its instructions to a temporary - * list. This list will be added to the instruction stream (below) after - * the declaration is added. This is done because in some cases (such as - * redeclarations) the declaration may not actually be added to the - * instruction stream. - */ - exec_list initializer_instructions; - 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(&initializer_instructions, - state); - - /* Calculate the constant value if this is a const or uniform - * declaration. - */ - if (this->type->qualifier.constant || this->type->qualifier.uniform) { - ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs); - if (new_rhs != NULL) { - rhs = new_rhs; - - 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); - if (var->type->is_numeric()) { - /* Reduce cascading errors. */ - var->constant_value = ir_constant::zero(ctx, var->type); - } - } else { - rhs = constant_value; - var->constant_value = constant_value; - } - } else { - _mesa_glsl_error(&initializer_loc, state, - "initializer of type %s cannot be assigned to " - "variable of type %s", - rhs->type->name, var->type->name); - if (var->type->is_numeric()) { - /* Reduce cascading errors. */ - var->constant_value = ir_constant::zero(ctx, var->type); - } - } - } - - 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(&initializer_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"); - } - - /* Check if this declaration is actually a re-declaration, either to - * resize an array or add qualifiers to an existing variable. - * - * This is allowed for variables in the current scope, or when at - * global scope (for built-ins in the implicit outer scope). - */ - ir_variable *earlier = state->symbols->get_variable(decl->identifier); - if (earlier != NULL && (state->current_function == NULL || - state->symbols->name_declared_this_scope(decl->identifier))) { - - /* 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 ((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. - */ - - /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: - * - * "The size [of gl_TexCoord] can be at most - * gl_MaxTextureCoords." - */ - const unsigned size = unsigned(var->type->array_size()); - if ((strcmp("gl_TexCoord", var->name) == 0) - && (size > state->Const.MaxTextureCoords)) { - YYLTYPE loc = this->get_location(); - - _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot " - "be larger than gl_MaxTextureCoords (%u)\n", - state->Const.MaxTextureCoords); - } else if ((size > 0) && (size <= 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 if (state->extensions->ARB_fragment_coord_conventions - && strcmp(var->name, "gl_FragCoord") == 0 - && earlier->type == var->type - && earlier->mode == var->mode) { - /* Allow redeclaration of gl_FragCoord for ARB_fcc layout - * qualifiers. - */ - earlier->origin_upper_left = var->origin_upper_left; - earlier->pixel_center_integer = var->pixel_center_integer; - } else { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier); - } - - continue; - } - - /* By now, we know it's a new variable declaration (we didn't hit the - * above "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) - _mesa_glsl_error(& loc, state, - "identifier `%s' uses reserved `gl_' prefix", - decl->identifier); - - /* Add the variable to the symbol table. Note that the initializer's - * IR was already processed earlier (though it hasn't been emitted yet), - * without the variable in scope. - * - * 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." - */ - if (!state->symbols->add_variable(var->name, var)) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, "name `%s' already taken in the " - "current scope", decl->identifier); - continue; - } - - /* Push the variable declaration to the top. It means that all - * the variable declarations will appear in a funny - * last-to-first order, but otherwise we run into trouble if a - * function is prototyped, a global var is decled, then the - * function is defined with usage of the global var. See - * glslparsertest's CorrectModule.frag. - */ - instructions->push_head(var); - instructions->append_list(&initializer_instructions); - } - - - /* 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 = 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; - } - - /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...) - * call already handled the "vec4[..] foo" case. - */ - if (this->is_array) { - type = process_array_type(&loc, type, this->array_size, state); - } - - if (type->array_size() == 0) { - _mesa_glsl_error(&loc, state, "arrays passed as parameters must have " - "a declared size."); - type = glsl_type::error_type; - } - - is_void = false; - ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in); - - /* 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); - - 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 = state; - ir_function *f = NULL; - ir_function_signature *sig = NULL; - exec_list hir_parameters; - - const char *const name = identifier; - - /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec, - * - * "Function declarations (prototypes) cannot occur inside of functions; - * they must be at global scope, or for the built-in functions, outside - * the global scope." - * - * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec, - * - * "User defined functions may only be defined within the global scope." - * - * Note that this language does not appear in GLSL 1.10. - */ - if ((state->current_function != NULL) && (state->language_version != 110)) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, - "declaration of function `%s' not allowed within " - "function body", name); - } - - /* 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(name, "gl_", 3) == 0) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, - "identifier `%s' uses reserved `gl_' prefix", name); - } - - /* 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); - - if (!return_type) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, - "function `%s' has undeclared return type `%s'", - name, return_type_name); - return_type = glsl_type::error_type; - } - - /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec: - * "No qualifier is allowed on the return type of a function." - */ - if (this->return_type->has_qualifiers()) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(& loc, state, - "function `%s' return type has qualifiers", name); - } - - /* 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. - */ - f = state->symbols->get_function(name); - if (f != NULL && (state->es_shader || f->has_user_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); - } - } - } else { - f = new(ctx) ir_function(name); - if (!state->symbols->add_function(f->name, f)) { - /* 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); - return NULL; - } - - /* Emit the new function header */ - if (state->current_function == NULL) - instructions->push_tail(f); - else { - /* IR invariants disallow function declarations or definitions nested - * within other function definitions. Insert the new ir_function - * block in the instruction sequence before the ir_function block - * containing the current ir_function_signature. - * - * This can only happen in a GLSL 1.10 shader. In all other GLSL - * versions this nesting is disallowed. There is a check for this at - * the top of this function. - */ - ir_function *const curr = - const_cast<ir_function *>(state->current_function->function()); - - curr->insert_before(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; - if (signature == NULL) - return NULL; - - assert(state->current_function == NULL); - state->current_function = signature; - state->found_return = false; - - /* 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; - - if (!signature->return_type->is_void() && !state->found_return) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(& loc, state, "function `%s' has non-void return type " - "%s, but no return statement", - signature->function_name(), - signature->return_type->name); - } - - /* 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 = 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); - - /* Implicit conversions are not allowed for return values. */ - if (state->current_function->return_type != ret->type) { - YYLTYPE loc = this->get_location(); - - _mesa_glsl_error(& loc, state, - "`return' with wrong type %s, in function `%s' " - "returning %s", - ret->type->name, - state->current_function->function_name(), - state->current_function->return_type->name); - } - - 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; - } - - state->found_return = true; - instructions->push_tail(inst); - break; - } - - case ast_discard: - if (state->target != fragment_shader) { - YYLTYPE loc = this->get_location(); - - _mesa_glsl_error(& loc, state, - "`discard' may only appear in a fragment shader"); - } - instructions->push_tail(new(ctx) ir_discard); - 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(); - - /* Inline the for loop expression again, since we don't know - * where near the end of the loop body the normal copy of it - * is going to be placed. - */ - if (mode == ast_continue && - state->loop_or_switch_nesting_ast->rest_expression) { - state->loop_or_switch_nesting_ast->rest_expression->hir(instructions, - state); - } - - 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 = 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) { - state->symbols->push_scope(); - then_statement->hir(& stmt->then_instructions, state); - state->symbols->pop_scope(); - } - - if (else_statement != NULL) { - state->symbols->push_scope(); - else_statement->hir(& stmt->else_instructions, state); - state->symbols->pop_scope(); - } - - 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 = 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 = 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; - ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast; - - state->loop_or_switch_nesting = stmt; - state->loop_or_switch_nesting_ast = this; - - 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; - state->loop_or_switch_nesting_ast = nesting_ast; - - /* 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) -{ - 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 = talloc_array(state, glsl_struct_field, - 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); - - /* Section 10.9 of the GLSL ES 1.00 specification states that - * embedded structure definitions have been removed from the language. - */ - if (state->es_shader && decl_list->type->specifier->structure != NULL) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, "Embedded structure definitions are " - "not allowed in GLSL ES 1.00."); - } - - 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 *field_type = decl_type; - if (decl->is_array) { - YYLTYPE loc = decl->get_location(); - field_type = process_array_type(&loc, decl_type, decl->array_size, - state); - } - fields[i].type = (field_type != NULL) - ? field_type : glsl_type::error_type; - fields[i].name = decl->identifier; - i++; - } - } - - assert(i == decl_count); - - const glsl_type *t = - glsl_type::get_record_instance(fields, decl_count, this->name); - - YYLTYPE loc = this->get_location(); - if (!state->symbols->add_type(name, t)) { - _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name); - } else { - - 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; -} +/*
+ * 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/core.h" /* for struct gl_extensions */
+#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_functions(instructions, state);
+
+ state->symbols->language_version = state->language_version;
+
+ state->current_function = NULL;
+
+ /* Section 4.2 of the GLSL 1.20 specification states:
+ * "The built-in functions are scoped in a scope outside the global scope
+ * users declare global variables in. That is, a shader's global scope,
+ * available for user-defined functions and global variables, is nested
+ * inside the scope containing the built-in functions."
+ *
+ * Since built-in functions like ftransform() access built-in variables,
+ * it follows that those must be in the outer scope as well.
+ *
+ * We push scope here to create this nesting effect...but don't pop.
+ * This way, a shader's globals are still in the symbol table for use
+ * by the linker.
+ */
+ state->symbols->push_scope();
+
+ 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.
+ */
+bool
+apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = 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;
+
+ /* Convert to a floating point type with the same number of components
+ * as the original type - i.e. int to float, not int to vec4.
+ */
+ to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements,
+ from->type->matrix_columns);
+
+ 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) {
+ /* The resulting vector has a number of elements equal to
+ * the number of rows of matrix A. */
+ const glsl_type *const type =
+ glsl_type::get_instance(type_a->base_type,
+ type_a->column_type()->vector_elements,
+ 1);
+ assert(type != glsl_type::error_type);
+
+ return type;
+ }
+ } 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()) {
+ /* The resulting vector has a number of elements equal to
+ * the number of columns of matrix B. */
+ const glsl_type *const type =
+ glsl_type::get_instance(type_a->base_type,
+ type_b->row_type()->vector_elements,
+ 1);
+ assert(type != glsl_type::error_type);
+
+ return type;
+ }
+ }
+
+ _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;
+}
+
+/**
+ * \brief Return the result type of a bit-logic operation.
+ *
+ * If the given types to the bit-logic operator are invalid, return
+ * glsl_type::error_type.
+ *
+ * \param type_a Type of LHS of bit-logic op
+ * \param type_b Type of RHS of bit-logic op
+ */
+static const struct glsl_type *
+bit_logic_result_type(const struct glsl_type *type_a,
+ const struct glsl_type *type_b,
+ ast_operators op,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ if (state->language_version < 130) {
+ _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+ return glsl_type::error_type;
+ }
+
+ /* From page 50 (page 56 of PDF) of GLSL 1.30 spec:
+ *
+ * "The bitwise operators and (&), exclusive-or (^), and inclusive-or
+ * (|). The operands must be of type signed or unsigned integers or
+ * integer vectors."
+ */
+ if (!type_a->is_integer()) {
+ _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+ if (!type_b->is_integer()) {
+ _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "The fundamental types of the operands (signed or unsigned) must
+ * match,"
+ */
+ if (type_a->base_type != type_b->base_type) {
+ _mesa_glsl_error(loc, state, "operands of `%s' must have the same "
+ "base type", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "The operands cannot be vectors of differing size." */
+ if (type_a->is_vector() &&
+ type_b->is_vector() &&
+ type_a->vector_elements != type_b->vector_elements) {
+ _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of "
+ "different sizes", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "If one operand is a scalar and the other a vector, the scalar is
+ * applied component-wise to the vector, resulting in the same type as
+ * the vector. The fundamental types of the operands [...] will be the
+ * resulting fundamental type."
+ */
+ if (type_a->is_scalar())
+ return type_b;
+ else
+ return type_a;
+}
+
+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;
+}
+
+/**
+ * \brief Return the result type of a bit-shift operation.
+ *
+ * If the given types to the bit-shift operator are invalid, return
+ * glsl_type::error_type.
+ *
+ * \param type_a Type of LHS of bit-shift op
+ * \param type_b Type of RHS of bit-shift op
+ */
+static const struct glsl_type *
+shift_result_type(const struct glsl_type *type_a,
+ const struct glsl_type *type_b,
+ ast_operators op,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ if (state->language_version < 130) {
+ _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+ return glsl_type::error_type;
+ }
+
+ /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec:
+ *
+ * "The shift operators (<<) and (>>). For both operators, the operands
+ * must be signed or unsigned integers or integer vectors. One operand
+ * can be signed while the other is unsigned."
+ */
+ if (!type_a->is_integer()) {
+ _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
+ "integer vector", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+
+ }
+ if (!type_b->is_integer()) {
+ _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
+ "integer vector", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "If the first operand is a scalar, the second operand has to be
+ * a scalar as well."
+ */
+ if (type_a->is_scalar() && !type_b->is_scalar()) {
+ _mesa_glsl_error(loc, state, "If the first operand of %s is scalar, the "
+ "second must be scalar as well",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* If both operands are vectors, check that they have same number of
+ * elements.
+ */
+ if (type_a->is_vector() &&
+ type_b->is_vector() &&
+ type_a->vector_elements != type_b->vector_elements) {
+ _mesa_glsl_error(loc, state, "Vector operands to operator %s must "
+ "have same number of elements",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "In all cases, the resulting type will be the same type as the left
+ * operand."
+ */
+ return type_a;
+}
+
+/**
+ * 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)
+{
+ /* 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)) {
+ 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 = state;
+ bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
+
+ if (!error_emitted) {
+ if (!lhs->is_lvalue()) {
+ _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
+ error_emitted = true;
+ }
+
+ if (state->es_shader && lhs->type->is_array()) {
+ _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
+ "allowed in GLSL ES 1.00.");
+ 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(lhs->type->element_type(),
+ rhs->type->array_size());
+ d->type = var->type;
+ }
+ }
+
+ /* 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_var_temporary);
+ 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);
+
+ if (!error_emitted)
+ instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var, NULL));
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+static ir_rvalue *
+get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
+{
+ void *ctx = talloc_parent(lvalue);
+ ir_variable *var;
+
+ var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
+ ir_var_temporary);
+ instructions->push_tail(var);
+ 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;
+}
+
+static void
+mark_whole_array_access(ir_rvalue *access)
+{
+ ir_dereference_variable *deref = access->as_dereference_variable();
+
+ if (deref) {
+ deref->var->max_array_access = deref->type->length - 1;
+ }
+}
+
+static ir_rvalue *
+do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
+{
+ int join_op;
+ ir_rvalue *cmp = NULL;
+
+ if (operation == ir_binop_all_equal)
+ join_op = ir_binop_logic_and;
+ else
+ join_op = ir_binop_logic_or;
+
+ switch (op0->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_BOOL:
+ return new(mem_ctx) ir_expression(operation, op0, op1);
+
+ case GLSL_TYPE_ARRAY: {
+ for (unsigned int i = 0; i < op0->type->length; i++) {
+ ir_rvalue *e0, *e1, *result;
+
+ e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
+ new(mem_ctx) ir_constant(i));
+ e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
+ new(mem_ctx) ir_constant(i));
+ result = do_comparison(mem_ctx, operation, e0, e1);
+
+ if (cmp) {
+ cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+ } else {
+ cmp = result;
+ }
+ }
+
+ mark_whole_array_access(op0);
+ mark_whole_array_access(op1);
+ break;
+ }
+
+ case GLSL_TYPE_STRUCT: {
+ for (unsigned int i = 0; i < op0->type->length; i++) {
+ ir_rvalue *e0, *e1, *result;
+ const char *field_name = op0->type->fields.structure[i].name;
+
+ e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
+ field_name);
+ e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
+ field_name);
+ result = do_comparison(mem_ctx, operation, e0, e1);
+
+ if (cmp) {
+ cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+ } else {
+ cmp = result;
+ }
+ }
+ break;
+ }
+
+ case GLSL_TYPE_ERROR:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_SAMPLER:
+ /* I assume a comparison of a struct containing a sampler just
+ * ignores the sampler present in the type.
+ */
+ break;
+
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+
+ if (cmp == NULL)
+ cmp = new(mem_ctx) ir_constant(true);
+
+ return cmp;
+}
+
+ir_rvalue *
+ast_expression::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = 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_all_equal,
+ ir_binop_any_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[3];
+ 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);
+
+ type = unary_arithmetic_result_type(op[0]->type, state, & loc);
+
+ error_emitted = type->is_error();
+
+ 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:
+ if (state->language_version < 130) {
+ _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
+ &loc);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ 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 = do_comparison(ctx, operations[this->oper], op[0], op[1]);
+ type = glsl_type::bool_type;
+
+ assert(error_emitted || (result->type == glsl_type::bool_type));
+ break;
+
+ case ast_bit_and:
+ case ast_bit_xor:
+ case ast_bit_or:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
+ state, &loc);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ break;
+
+ case ast_bit_not:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (state->language_version < 130) {
+ _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30");
+ error_emitted = true;
+ }
+
+ if (!op[0]->type->is_integer()) {
+ _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
+ error_emitted = true;
+ }
+
+ type = op[0]->type;
+ result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL);
+ 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_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+ "and_tmp",
+ ir_var_temporary);
+ instructions->push_tail(tmp);
+
+ 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_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_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+ "or_tmp",
+ ir_var_temporary);
+ instructions->push_tail(tmp);
+
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
+ instructions->push_tail(stmt);
+
+ op[1] = this->subexpressions[1]->hir(&stmt->else_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,
+ op[0]->clone(ctx, 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);
+
+ ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ op[0]->clone(ctx, 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: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
+ &loc);
+ ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+ type, op[0], op[1]);
+ result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
+ temp_rhs,
+ this->subexpressions[0]->get_location());
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ break;
+ }
+
+ case ast_and_assign:
+ case ast_xor_assign:
+ case ast_or_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
+ state, &loc);
+ ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+ type, op[0], op[1]);
+ result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
+ temp_rhs,
+ this->subexpressions[0]->get_location());
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ 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;
+ }
+
+ /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "The second and third expressions must be the same type, but can
+ * be of any type other than an array."
+ */
+ if ((state->language_version <= 110) && type->is_array()) {
+ _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
+ "operator must not be arrays.");
+ error_emitted = true;
+ }
+
+ 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 =
+ new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
+ instructions->push_tail(tmp);
+
+ 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);
+
+ ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ op[0]->clone(ctx, 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);
+
+ 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, op[0]->clone(ctx, NULL));
+
+ (void)do_assignment(instructions, state,
+ op[0]->clone(ctx, 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;
+ }
+ } else if (array->type->array_size() == 0) {
+ _mesa_glsl_error(&loc, state, "unsized array index must be constant");
+ } else {
+ if (array->type->is_array()) {
+ /* whole_variable_referenced can return NULL if the array is a
+ * member of a structure. In this case it is safe to not update
+ * the max_array_access field because it is never used for fields
+ * of structures.
+ */
+ ir_variable *v = array->whole_variable_referenced();
+ if (v != NULL)
+ v->max_array_access = array->type->array_size();
+ }
+ }
+
+ /* From section 4.1.7 of the GLSL 1.30 spec:
+ * "Samplers aggregated into arrays within a shader (using square
+ * brackets [ ]) can only be indexed with integral constant
+ * expressions [...]."
+ */
+ if (array->type->is_array() &&
+ array->type->element_type()->is_sampler() &&
+ const_index == NULL) {
+
+ _mesa_glsl_error(&loc, state, "sampler arrays can only be indexed "
+ "with constant expressions");
+ error_emitted = true;
+ }
+
+ 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(YYLTYPE *loc, 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];
+ }
+ }
+ }
+ } else if (state->es_shader) {
+ /* Section 10.17 of the GLSL ES 1.00 specification states that unsized
+ * array declarations have been removed from the language.
+ */
+ _mesa_glsl_error(loc, state, "unsized array declarations are not "
+ "allowed in GLSL ES 1.00.");
+ }
+
+ return glsl_type::get_array_instance(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;
+
+ type = state->symbols->get_type(this->type_name);
+ *name = this->type_name;
+
+ if (this->is_array) {
+ YYLTYPE loc = this->get_location();
+ type = process_array_type(&loc, type, this->array_size, state);
+ }
+
+ return type;
+}
+
+
+static void
+apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
+ ir_variable *var,
+ struct _mesa_glsl_parse_state *state,
+ YYLTYPE *loc)
+{
+ if (qual->flags.q.invariant)
+ var->invariant = 1;
+
+ /* FINISHME: Mark 'in' variables at global scope as read-only. */
+ if (qual->flags.q.constant || qual->flags.q.attribute
+ || qual->flags.q.uniform
+ || (qual->flags.q.varying && (state->target == fragment_shader)))
+ var->read_only = 1;
+
+ if (qual->flags.q.centroid)
+ var->centroid = 1;
+
+ if (qual->flags.q.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->flags.q.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 there is no qualifier that changes the mode of the variable, leave
+ * the setting alone.
+ */
+ if (qual->flags.q.in && qual->flags.q.out)
+ var->mode = ir_var_inout;
+ else if (qual->flags.q.attribute || qual->flags.q.in
+ || (qual->flags.q.varying && (state->target == fragment_shader)))
+ var->mode = ir_var_in;
+ else if (qual->flags.q.out
+ || (qual->flags.q.varying && (state->target == vertex_shader)))
+ var->mode = ir_var_out;
+ else if (qual->flags.q.uniform)
+ var->mode = ir_var_uniform;
+
+ if (qual->flags.q.flat)
+ var->interpolation = ir_var_flat;
+ else if (qual->flags.q.noperspective)
+ var->interpolation = ir_var_noperspective;
+ else
+ var->interpolation = ir_var_smooth;
+
+ var->pixel_center_integer = qual->flags.q.pixel_center_integer;
+ var->origin_upper_left = qual->flags.q.origin_upper_left;
+ if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
+ && (strcmp(var->name, "gl_FragCoord") != 0)) {
+ const char *const qual_string = (qual->flags.q.origin_upper_left)
+ ? "origin_upper_left" : "pixel_center_integer";
+
+ _mesa_glsl_error(loc, state,
+ "layout qualifier `%s' can only be applied to "
+ "fragment shader input `gl_FragCoord'",
+ qual_string);
+ }
+
+ if (qual->flags.q.explicit_location) {
+ const bool global_scope = (state->current_function == NULL);
+ bool fail = false;
+ const char *string = "";
+
+ /* In the vertex shader only shader inputs can be given explicit
+ * locations.
+ *
+ * In the fragment shader only shader outputs can be given explicit
+ * locations.
+ */
+ switch (state->target) {
+ case vertex_shader:
+ if (!global_scope || (var->mode != ir_var_in)) {
+ fail = true;
+ string = "input";
+ }
+ break;
+
+ case geometry_shader:
+ _mesa_glsl_error(loc, state,
+ "geometry shader variables cannot be given "
+ "explicit locations\n");
+ break;
+
+ case fragment_shader:
+ if (!global_scope || (var->mode != ir_var_in)) {
+ fail = true;
+ string = "output";
+ }
+ break;
+ };
+
+ if (fail) {
+ _mesa_glsl_error(loc, state,
+ "only %s shader %s variables can be given an "
+ "explicit location\n",
+ _mesa_glsl_shader_target_name(state->target),
+ string);
+ } else {
+ var->explicit_location = true;
+
+ /* This bit of silliness is needed because invalid explicit locations
+ * are supposed to be flagged during linking. Small negative values
+ * biased by VERT_ATTRIB_GENERIC0 or FRAG_RESULT_DATA0 could alias
+ * built-in values (e.g., -16+VERT_ATTRIB_GENERIC0 = VERT_ATTRIB_POS).
+ * The linker needs to be able to differentiate these cases. This
+ * ensures that negative values stay negative.
+ */
+ if (qual->location >= 0) {
+ var->location = (state->target == vertex_shader)
+ ? (qual->location + VERT_ATTRIB_GENERIC0)
+ : (qual->location + FRAG_RESULT_DATA0);
+ } else {
+ var->location = qual->location;
+ }
+ }
+ }
+
+ if (var->type->is_array() && state->language_version != 110) {
+ var->array_lvalue = true;
+ }
+}
+
+
+ir_rvalue *
+ast_declarator_list::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ const struct glsl_type *decl_type;
+ const char *type_name = NULL;
+ ir_rvalue *result = NULL;
+ YYLTYPE loc = this->get_location();
+
+ /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "To ensure that a particular output variable is invariant, it is
+ * necessary to use the invariant qualifier. It can either be used to
+ * qualify a previously declared variable as being invariant
+ *
+ * invariant gl_Position; // make existing gl_Position be invariant"
+ *
+ * In these cases the parser will set the 'invariant' flag in the declarator
+ * list, and the type will be NULL.
+ */
+ if (this->invariant) {
+ assert(this->type == NULL);
+
+ if (state->current_function != NULL) {
+ _mesa_glsl_error(& loc, state,
+ "All uses of `invariant' keyword must be at global "
+ "scope\n");
+ }
+
+ foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+ assert(!decl->is_array);
+ assert(decl->array_size == NULL);
+ assert(decl->initializer == NULL);
+
+ ir_variable *const earlier =
+ state->symbols->get_variable(decl->identifier);
+ if (earlier == NULL) {
+ _mesa_glsl_error(& loc, state,
+ "Undeclared variable `%s' cannot be marked "
+ "invariant\n", decl->identifier);
+ } else if ((state->target == vertex_shader)
+ && (earlier->mode != ir_var_out)) {
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, vertex shader "
+ "outputs only\n", decl->identifier);
+ } else if ((state->target == fragment_shader)
+ && (earlier->mode != ir_var_in)) {
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, fragment shader "
+ "inputs only\n", decl->identifier);
+ } else {
+ earlier->invariant = true;
+ }
+ }
+
+ /* Invariant redeclarations do not have r-values.
+ */
+ return NULL;
+ }
+
+ assert(this->type != NULL);
+ assert(!this->invariant);
+
+ /* The type specifier may contain a structure definition. Process that
+ * before any of the variable declarations.
+ */
+ (void) this->type->specifier->hir(instructions, state);
+
+ decl_type = this->type->specifier->glsl_type(& type_name, state);
+ if (this->declarations.is_empty()) {
+ /* The only valid case where the declaration list can be empty is when
+ * the declaration is setting the default precision of a built-in type
+ * (e.g., 'precision highp vec4;').
+ */
+
+ 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;
+ 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(&loc, decl_type, decl->array_size,
+ state);
+ } else {
+ var_type = decl_type;
+ }
+
+ var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
+
+ /* 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.flags.q.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.flags.q.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);
+
+ if (this->type->qualifier.flags.q.invariant) {
+ if ((state->target == vertex_shader) && !(var->mode == ir_var_out ||
+ var->mode == ir_var_inout)) {
+ /* FINISHME: Note that this doesn't work for invariant on
+ * a function signature outval
+ */
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, vertex shader "
+ "outputs only\n", var->name);
+ } else if ((state->target == fragment_shader) &&
+ !(var->mode == ir_var_in || var->mode == ir_var_inout)) {
+ /* FINISHME: Note that this doesn't work for invariant on
+ * a function signature inval
+ */
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, fragment shader "
+ "inputs only\n", var->name);
+ }
+ }
+
+ 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.flags.q.attribute) {
+ mode = "attribute";
+ } else if (this->type->qualifier.flags.q.uniform) {
+ mode = "uniform";
+ } else if (this->type->qualifier.flags.q.varying) {
+ mode = "varying";
+ } else if (this->type->qualifier.flags.q.in) {
+ mode = "in";
+ extra = " or in function parameter list";
+ } else if (this->type->qualifier.flags.q.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;
+ }
+ }
+ }
+
+ /* Process the initializer and add its instructions to a temporary
+ * list. This list will be added to the instruction stream (below) after
+ * the declaration is added. This is done because in some cases (such as
+ * redeclarations) the declaration may not actually be added to the
+ * instruction stream.
+ */
+ exec_list initializer_instructions;
+ 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(&initializer_instructions,
+ state);
+
+ /* Calculate the constant value if this is a const or uniform
+ * declaration.
+ */
+ if (this->type->qualifier.flags.q.constant
+ || this->type->qualifier.flags.q.uniform) {
+ ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs);
+ if (new_rhs != NULL) {
+ rhs = new_rhs;
+
+ 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.flags.q.constant)
+ ? "const" : "uniform",
+ decl->identifier);
+ if (var->type->is_numeric()) {
+ /* Reduce cascading errors. */
+ var->constant_value = ir_constant::zero(ctx, var->type);
+ }
+ } else {
+ rhs = constant_value;
+ var->constant_value = constant_value;
+ }
+ } else {
+ _mesa_glsl_error(&initializer_loc, state,
+ "initializer of type %s cannot be assigned to "
+ "variable of type %s",
+ rhs->type->name, var->type->name);
+ if (var->type->is_numeric()) {
+ /* Reduce cascading errors. */
+ var->constant_value = ir_constant::zero(ctx, var->type);
+ }
+ }
+ }
+
+ if (rhs && !rhs->type->is_error()) {
+ bool temp = var->read_only;
+ if (this->type->qualifier.flags.q.constant)
+ var->read_only = false;
+
+ /* Never emit code to initialize a uniform.
+ */
+ const glsl_type *initializer_type;
+ if (!this->type->qualifier.flags.q.uniform) {
+ result = do_assignment(&initializer_instructions, state,
+ lhs, rhs,
+ this->get_location());
+ initializer_type = result->type;
+ } else
+ initializer_type = rhs->type;
+
+ /* If the declared variable is an unsized array, it must inherrit
+ * its full type from the initializer. A declaration such as
+ *
+ * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
+ *
+ * becomes
+ *
+ * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
+ *
+ * The assignment generated in the if-statement (below) will also
+ * automatically handle this case for non-uniforms.
+ *
+ * If the declared variable is not an array, the types must
+ * already match exactly. As a result, the type assignment
+ * here can be done unconditionally. For non-uniforms the call
+ * to do_assignment can change the type of the initializer (via
+ * the implicit conversion rules). For uniforms the initializer
+ * must be a constant expression, and the type of that expression
+ * was validated above.
+ */
+ var->type = initializer_type;
+
+ 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.flags.q.constant && decl->initializer == NULL) {
+ _mesa_glsl_error(& loc, state,
+ "const declaration of `%s' must be initialized");
+ }
+
+ /* Check if this declaration is actually a re-declaration, either to
+ * resize an array or add qualifiers to an existing variable.
+ *
+ * This is allowed for variables in the current scope, or when at
+ * global scope (for built-ins in the implicit outer scope).
+ */
+ ir_variable *earlier = state->symbols->get_variable(decl->identifier);
+ if (earlier != NULL && (state->current_function == NULL ||
+ state->symbols->name_declared_this_scope(decl->identifier))) {
+
+ /* 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 ((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.
+ */
+
+ /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "The size [of gl_TexCoord] can be at most
+ * gl_MaxTextureCoords."
+ */
+ const unsigned size = unsigned(var->type->array_size());
+ if ((strcmp("gl_TexCoord", var->name) == 0)
+ && (size > state->Const.MaxTextureCoords)) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot "
+ "be larger than gl_MaxTextureCoords (%u)\n",
+ state->Const.MaxTextureCoords);
+ } else if ((size > 0) && (size <= 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 if (state->ARB_fragment_coord_conventions_enable
+ && strcmp(var->name, "gl_FragCoord") == 0
+ && earlier->type == var->type
+ && earlier->mode == var->mode) {
+ /* Allow redeclaration of gl_FragCoord for ARB_fcc layout
+ * qualifiers.
+ */
+ earlier->origin_upper_left = var->origin_upper_left;
+ earlier->pixel_center_integer = var->pixel_center_integer;
+ } else {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier);
+ }
+
+ continue;
+ }
+
+ /* By now, we know it's a new variable declaration (we didn't hit the
+ * above "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)
+ _mesa_glsl_error(& loc, state,
+ "identifier `%s' uses reserved `gl_' prefix",
+ decl->identifier);
+
+ /* Add the variable to the symbol table. Note that the initializer's
+ * IR was already processed earlier (though it hasn't been emitted yet),
+ * without the variable in scope.
+ *
+ * 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."
+ */
+ if (!state->symbols->add_variable(var)) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
+ "current scope", decl->identifier);
+ continue;
+ }
+
+ /* Push the variable declaration to the top. It means that all
+ * the variable declarations will appear in a funny
+ * last-to-first order, but otherwise we run into trouble if a
+ * function is prototyped, a global var is decled, then the
+ * function is defined with usage of the global var. See
+ * glslparsertest's CorrectModule.frag.
+ */
+ instructions->push_head(var);
+ instructions->append_list(&initializer_instructions);
+ }
+
+
+ /* 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 = 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;
+ }
+
+ /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...)
+ * call already handled the "vec4[..] foo" case.
+ */
+ if (this->is_array) {
+ type = process_array_type(&loc, type, this->array_size, state);
+ }
+
+ if (type->array_size() == 0) {
+ _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
+ "a declared size.");
+ type = glsl_type::error_type;
+ }
+
+ is_void = false;
+ ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in);
+
+ /* 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);
+
+ 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");
+ }
+}
+
+
+void
+emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
+ ir_function *f)
+{
+ /* Emit the new function header */
+ if (state->current_function == NULL) {
+ instructions->push_tail(f);
+ } else {
+ /* IR invariants disallow function declarations or definitions nested
+ * within other function definitions. Insert the new ir_function
+ * block in the instruction sequence before the ir_function block
+ * containing the current ir_function_signature.
+ */
+ ir_function *const curr =
+ const_cast<ir_function *>(state->current_function->function());
+
+ curr->insert_before(f);
+ }
+}
+
+
+ir_rvalue *
+ast_function::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ ir_function *f = NULL;
+ ir_function_signature *sig = NULL;
+ exec_list hir_parameters;
+
+ const char *const name = identifier;
+
+ /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
+ *
+ * "Function declarations (prototypes) cannot occur inside of functions;
+ * they must be at global scope, or for the built-in functions, outside
+ * the global scope."
+ *
+ * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
+ *
+ * "User defined functions may only be defined within the global scope."
+ *
+ * Note that this language does not appear in GLSL 1.10.
+ */
+ if ((state->current_function != NULL) && (state->language_version != 110)) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "declaration of function `%s' not allowed within "
+ "function body", name);
+ }
+
+ /* 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(name, "gl_", 3) == 0) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "identifier `%s' uses reserved `gl_' prefix", name);
+ }
+
+ /* 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);
+
+ if (!return_type) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "function `%s' has undeclared return type `%s'",
+ name, return_type_name);
+ return_type = glsl_type::error_type;
+ }
+
+ /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
+ * "No qualifier is allowed on the return type of a function."
+ */
+ if (this->return_type->has_qualifiers()) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(& loc, state,
+ "function `%s' return type has qualifiers", name);
+ }
+
+ /* 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.
+ */
+ f = state->symbols->get_function(name);
+ if (f != NULL && (state->es_shader || f->has_user_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);
+ }
+ }
+ } else {
+ f = new(ctx) ir_function(name);
+ if (!state->symbols->add_function(f)) {
+ /* 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);
+ return NULL;
+ }
+
+ emit_function(state, instructions, 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;
+ if (signature == NULL)
+ return NULL;
+
+ assert(state->current_function == NULL);
+ state->current_function = signature;
+ state->found_return = false;
+
+ /* 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);
+ }
+ }
+
+ /* 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;
+
+ if (!signature->return_type->is_void() && !state->found_return) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
+ "%s, but no return statement",
+ signature->function_name(),
+ signature->return_type->name);
+ }
+
+ /* 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 = 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_rvalue *const ret = opt_return_value->hir(instructions, state);
+ assert(ret != NULL);
+
+ /* Implicit conversions are not allowed for return values. */
+ if (state->current_function->return_type != ret->type) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`return' with wrong type %s, in function `%s' "
+ "returning %s",
+ ret->type->name,
+ state->current_function->function_name(),
+ state->current_function->return_type->name);
+ }
+
+ 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;
+ }
+
+ state->found_return = true;
+ instructions->push_tail(inst);
+ break;
+ }
+
+ case ast_discard:
+ if (state->target != fragment_shader) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`discard' may only appear in a fragment shader");
+ }
+ instructions->push_tail(new(ctx) ir_discard);
+ 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();
+
+ /* Inline the for loop expression again, since we don't know
+ * where near the end of the loop body the normal copy of it
+ * is going to be placed.
+ */
+ if (mode == ast_continue &&
+ state->loop_or_switch_nesting_ast->rest_expression) {
+ state->loop_or_switch_nesting_ast->rest_expression->hir(instructions,
+ state);
+ }
+
+ 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 = 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) {
+ state->symbols->push_scope();
+ then_statement->hir(& stmt->then_instructions, state);
+ state->symbols->pop_scope();
+ }
+
+ if (else_statement != NULL) {
+ state->symbols->push_scope();
+ else_statement->hir(& stmt->else_instructions, state);
+ state->symbols->pop_scope();
+ }
+
+ 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 = 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 = 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;
+ ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast;
+
+ state->loop_or_switch_nesting = stmt;
+ state->loop_or_switch_nesting_ast = this;
+
+ 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;
+ state->loop_or_switch_nesting_ast = nesting_ast;
+
+ /* 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)
+{
+ 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 = talloc_array(state, glsl_struct_field,
+ 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);
+
+ /* Section 10.9 of the GLSL ES 1.00 specification states that
+ * embedded structure definitions have been removed from the language.
+ */
+ if (state->es_shader && decl_list->type->specifier->structure != NULL) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state, "Embedded structure definitions are "
+ "not allowed in GLSL ES 1.00.");
+ }
+
+ 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 *field_type = decl_type;
+ if (decl->is_array) {
+ YYLTYPE loc = decl->get_location();
+ field_type = process_array_type(&loc, decl_type, decl->array_size,
+ state);
+ }
+ fields[i].type = (field_type != NULL)
+ ? field_type : glsl_type::error_type;
+ fields[i].name = decl->identifier;
+ i++;
+ }
+ }
+
+ assert(i == decl_count);
+
+ const glsl_type *t =
+ glsl_type::get_record_instance(fields, decl_count, this->name);
+
+ YYLTYPE loc = this->get_location();
+ if (!state->symbols->add_type(name, t)) {
+ _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
+ } else {
+
+ 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;
+}
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp index 9a957044e..c1cf43591 100644 --- a/mesalib/src/glsl/ast_type.cpp +++ b/mesalib/src/glsl/ast_type.cpp @@ -1,122 +1,118 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <cstdio> -#include "ast.h" -extern "C" { -#include "program/symbol_table.h" -} - -void -ast_type_specifier::print(void) const -{ - if (type_specifier == ast_struct) { - structure->print(); - } else { - printf("%s ", type_name); - } - - if (is_array) { - printf("[ "); - - if (array_size) { - array_size->print(); - } - - printf("] "); - } -} - -ast_type_specifier::ast_type_specifier(int specifier) - : type_specifier(ast_types(specifier)), type_name(NULL), structure(NULL), - is_array(false), array_size(NULL), precision(ast_precision_high) -{ - static const char *const names[] = { - "void", - "float", - "int", - "uint", - "bool", - "vec2", - "vec3", - "vec4", - "bvec2", - "bvec3", - "bvec4", - "ivec2", - "ivec3", - "ivec4", - "uvec2", - "uvec3", - "uvec4", - "mat2", - "mat2x3", - "mat2x4", - "mat3x2", - "mat3", - "mat3x4", - "mat4x2", - "mat4x3", - "mat4", - "sampler1D", - "sampler2D", - "sampler2DRect", - "sampler3D", - "samplerCube", - "sampler1DShadow", - "sampler2DShadow", - "sampler2DRectShadow", - "samplerCubeShadow", - "sampler1DArray", - "sampler2DArray", - "sampler1DArrayShadow", - "sampler2DArrayShadow", - "isampler1D", - "isampler2D", - "isampler3D", - "isamplerCube", - "isampler1DArray", - "isampler2DArray", - "usampler1D", - "usampler2D", - "usampler3D", - "usamplerCube", - "usampler1DArray", - "usampler2DArray", - - NULL, /* ast_struct */ - NULL /* ast_type_name */ - }; - - type_name = names[specifier]; -} - -bool -ast_fully_specified_type::has_qualifiers() const -{ - return qualifier.invariant || qualifier.constant || qualifier.attribute - || qualifier.varying || qualifier.in - || qualifier.out || qualifier.centroid - || qualifier.uniform || qualifier.smooth - || qualifier.flat || qualifier.noperspective; -} +/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <cstdio>
+#include "ast.h"
+extern "C" {
+#include "program/symbol_table.h"
+}
+
+void
+ast_type_specifier::print(void) const
+{
+ if (type_specifier == ast_struct) {
+ structure->print();
+ } else {
+ printf("%s ", type_name);
+ }
+
+ if (is_array) {
+ printf("[ ");
+
+ if (array_size) {
+ array_size->print();
+ }
+
+ printf("] ");
+ }
+}
+
+ast_type_specifier::ast_type_specifier(int specifier)
+ : type_specifier(ast_types(specifier)), type_name(NULL), structure(NULL),
+ is_array(false), array_size(NULL), precision(ast_precision_high)
+{
+ static const char *const names[] = {
+ "void",
+ "float",
+ "int",
+ "uint",
+ "bool",
+ "vec2",
+ "vec3",
+ "vec4",
+ "bvec2",
+ "bvec3",
+ "bvec4",
+ "ivec2",
+ "ivec3",
+ "ivec4",
+ "uvec2",
+ "uvec3",
+ "uvec4",
+ "mat2",
+ "mat2x3",
+ "mat2x4",
+ "mat3x2",
+ "mat3",
+ "mat3x4",
+ "mat4x2",
+ "mat4x3",
+ "mat4",
+ "sampler1D",
+ "sampler2D",
+ "sampler2DRect",
+ "sampler3D",
+ "samplerCube",
+ "sampler1DShadow",
+ "sampler2DShadow",
+ "sampler2DRectShadow",
+ "samplerCubeShadow",
+ "sampler1DArray",
+ "sampler2DArray",
+ "sampler1DArrayShadow",
+ "sampler2DArrayShadow",
+ "isampler1D",
+ "isampler2D",
+ "isampler3D",
+ "isamplerCube",
+ "isampler1DArray",
+ "isampler2DArray",
+ "usampler1D",
+ "usampler2D",
+ "usampler3D",
+ "usamplerCube",
+ "usampler1DArray",
+ "usampler2DArray",
+
+ NULL, /* ast_struct */
+ NULL /* ast_type_name */
+ };
+
+ type_name = names[specifier];
+}
+
+bool
+ast_fully_specified_type::has_qualifiers() const
+{
+ return this->qualifier.flags.i != 0;
+}
diff --git a/mesalib/src/glsl/builtin_function.cpp b/mesalib/src/glsl/builtin_function.cpp index 5f9bbec2f..f3effe074 100644 --- a/mesalib/src/glsl/builtin_function.cpp +++ b/mesalib/src/glsl/builtin_function.cpp @@ -1,19203 +1,13639 @@ -/* DO NOT MODIFY - automatically generated by generate_builtins.py */ -/* - * 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 "main/core.h" /* for struct gl_shader */ -#include "glsl_parser_extras.h" -#include "ir_reader.h" -#include "program.h" -#include "ast.h" - -extern "C" struct gl_shader * -_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type); - -gl_shader * -read_builtins(GLenum target, const char *protos, const char **functions, unsigned count) -{ - GLcontext fakeCtx; - fakeCtx.API = API_OPENGL; - gl_shader *sh = _mesa_new_shader(NULL, 0, target); - struct _mesa_glsl_parse_state *st = - new(sh) _mesa_glsl_parse_state(&fakeCtx, target, sh); - - st->language_version = 130; - st->symbols->language_version = 130; - st->ARB_texture_rectangle_enable = true; - st->EXT_texture_array_enable = true; - _mesa_glsl_initialize_types(st); - - sh->ir = new(sh) exec_list; - sh->symbols = st->symbols; - - /* Read the IR containing the prototypes */ - _mesa_glsl_read_ir(st, sh->ir, protos, true); - - /* Read ALL the function bodies, telling the IR reader not to scan for - * prototypes (we've already created them). The IR reader will skip any - * signature that does not already exist as a prototype. - */ - for (unsigned i = 0; i < count; i++) { - _mesa_glsl_read_ir(st, sh->ir, functions[i], false); - - if (st->error) { - printf("error reading builtin: %.35s ...\n", functions[i]); - printf("Info log:\n%s\n", st->info_log); - talloc_free(sh); - return NULL; - } - } - - reparent_ir(sh->ir, sh); - delete st; - - return sh; -} - -static const char *builtin_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 *builtin_acos = - "((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 *builtin_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 *builtin_any = - "((function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 arg0))\n" - " ((return (expression bool any (var_ref arg0)))))\n" - "\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 arg0))\n" - " ((return (expression bool any (var_ref arg0)))))\n" - "\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 arg0))\n" - " ((return (expression bool any (var_ref arg0)))))\n" - "))\n" - "" -; -static const char *builtin_asin = - "((function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ((return (expression float *\n" - " (expression float sign (var_ref x))\n" - " (expression float -\n" - " (expression float *\n" - " (constant float (3.1415926))\n" - " (constant float (0.5)))\n" - " (expression float *\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 vec2 sign (var_ref x))\n" - " (expression vec2 -\n" - " (expression float *\n" - " (constant float (3.1415926))\n" - " (constant float (0.5)))\n" - " (expression vec2 *\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 sign (var_ref x))\n" - " (expression vec3 -\n" - " (expression float *\n" - " (constant float (3.1415926))\n" - " (constant float (0.5)))\n" - " (expression vec3 *\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 sign (var_ref x))\n" - " (expression vec4 -\n" - " (expression float *\n" - " (constant float (3.1415926))\n" - " (constant float (0.5)))\n" - " (expression vec4 *\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" - "" -; -static const char *builtin_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" - " )\n" - " (\n" - " (declare () float r)\n" - " (declare ( ) float abs_retval)\n" - " (assign (constant bool (1)) (x) (var_ref abs_retval) (call abs ((var_ref x) ))\n" - ")\n" - " (if (expression bool > (var_ref abs_retval) (constant float (0.000100)) ) (\n" - " (declare ( ) float atan_retval)\n" - " (assign (constant bool (1)) (x) (var_ref atan_retval) (call atan ((expression float / (var_ref y) (var_ref x) ) ))\n" - ")\n" - " (assign (constant bool (1)) (x) (var_ref r) (var_ref atan_retval) )\n" - " (if (expression bool < (var_ref x) (constant float (0.000000)) ) (\n" - " (if (expression bool >= (var_ref y) (constant float (0.000000)) ) (\n" - " (declare ( ) float assignment_tmp)\n" - " (assign (constant bool (1)) (x) (var_ref assignment_tmp) (expression float + (var_ref r) (constant float (3.141593)) ) )\n" - " (assign (constant bool (1)) (x) (var_ref r) (var_ref assignment_tmp) )\n" - " )\n" - " (\n" - " (declare ( ) float assignment_tmp)\n" - " (assign (constant bool (1)) (x) (var_ref assignment_tmp) (expression float - (var_ref r) (constant float (3.141593)) ) )\n" - " (assign (constant bool (1)) (x) (var_ref r) (var_ref assignment_tmp) )\n" - " ))\n" - "\n" - " )\n" - " (\n" - " ))\n" - "\n" - " )\n" - " (\n" - " (declare () float sgn)\n" - " (assign (constant bool (1)) (x) (var_ref sgn) (expression float sign (var_ref y)))\n" - " (assign (constant bool (1)) (x) (var_ref r) (expression float * (var_ref sgn) (constant float (1.5707965))))\n" - " ))\n" - "\n" - " (return (var_ref r) )\n" - " ))\n" - "\n" - "\n" - "\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ((declare () vec2 r)\n" - " (assign (constant bool (1)) (x) (var_ref r)\n" - " (call atan ((swiz x (var_ref y))\n" - " (swiz x (var_ref x)))))\n" - " (assign (constant bool (1)) (y) (var_ref r)\n" - " (call atan ((swiz y (var_ref y))\n" - " (swiz y (var_ref x)))))\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" - " (assign (constant bool (1)) (x) (var_ref r)\n" - " (call atan ((swiz x (var_ref y))\n" - " (swiz x (var_ref x)))))\n" - " (assign (constant bool (1)) (y) (var_ref r)\n" - " (call atan ((swiz y (var_ref y))\n" - " (swiz y (var_ref x)))))\n" - " (assign (constant bool (1)) (z) (var_ref r)\n" - " (call atan ((swiz z (var_ref y))\n" - " (swiz z (var_ref x)))))\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" - " (assign (constant bool (1)) (x) (var_ref r)\n" - " (call atan ((swiz x (var_ref y))\n" - " (swiz x (var_ref x)))))\n" - " (assign (constant bool (1)) (y) (var_ref r)\n" - " (call atan ((swiz y (var_ref y))\n" - " (swiz y (var_ref x)))))\n" - " (assign (constant bool (1)) (z) (var_ref r)\n" - " (call atan ((swiz z (var_ref y))\n" - " (swiz z (var_ref x)))))\n" - " (assign (constant bool (1)) (w) (var_ref r)\n" - " (call atan ((swiz w (var_ref y))\n" - " (swiz w (var_ref x)))))\n" - " (return (var_ref r)))))\n" - "\n" - "))\n" - "" -; -static const char *builtin_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 *builtin_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" - " ((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) float arg1)\n" - " (declare (in) float 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) float arg1)\n" - " (declare (in) float arg2))\n" - " ((return (expression vec4 max (expression vec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n" - "\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" - " ((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) int arg1)\n" - " (declare (in) int 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) int arg1)\n" - " (declare (in) int arg2))\n" - " ((return (expression ivec4 max (expression ivec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\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" - " ((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) uint arg1)\n" - " (declare (in) uint 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) uint arg1)\n" - " (declare (in) uint arg2))\n" - " ((return (expression uvec4 max (expression uvec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_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 *builtin_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 *builtin_cross = - "((function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) vec3 arg1))\n" - " ((return (expression vec3 cross (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_dFdx = - "((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" - "" -; -static const char *builtin_dFdy = - "((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" - "" -; -static const char *builtin_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 *builtin_distance = - "((function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ((return (expression float abs (expression float - (var_ref p0) (var_ref p1))))))\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)) (xy) (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)) (xyz) (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)) (xyzw) (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 *builtin_dot = - "((function dot\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 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 *builtin_equal = - "((function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 arg0)\n" - " (declare (in) vec2 arg1))\n" - " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) vec3 arg1))\n" - " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 arg0)\n" - " (declare (in) vec4 arg1))\n" - " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 arg0)\n" - " (declare (in) bvec2 arg1))\n" - " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 arg0)\n" - " (declare (in) bvec3 arg1))\n" - " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 arg0)\n" - " (declare (in) bvec4 arg1))\n" - " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 arg0)\n" - " (declare (in) ivec2 arg1))\n" - " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) ivec3 arg1))\n" - " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 arg0)\n" - " (declare (in) ivec4 arg1))\n" - " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 arg0)\n" - " (declare (in) uvec2 arg1))\n" - " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uvec3 arg1))\n" - " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 arg0)\n" - " (declare (in) uvec4 arg1))\n" - " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_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 *builtin_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 *builtin_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 * (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 *builtin_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 *builtin_fract = - "((function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ((return (expression float fract (var_ref x)))))\n" - "\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ((return (expression vec2 fract (var_ref x)))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ((return (expression vec3 fract (var_ref x)))))\n" - "\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ((return (expression vec4 fract (var_ref x)))))\n" - "))\n" - "\n" - "" -; -static const char *builtin_ftransform = - "((declare (uniform) mat4 gl_ModelViewProjectionMatrix)\n" - " (declare (in) vec4 gl_Vertex)\n" - " (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 *builtin_fwidth = - "((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 *builtin_greaterThan = - "((function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 arg0)\n" - " (declare (in) vec2 arg1))\n" - " ((return (expression bvec2 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) vec3 arg1))\n" - " ((return (expression bvec3 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 arg0)\n" - " (declare (in) vec4 arg1))\n" - " ((return (expression bvec4 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 arg0)\n" - " (declare (in) ivec2 arg1))\n" - " ((return (expression bvec2 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) ivec3 arg1))\n" - " ((return (expression bvec3 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 arg0)\n" - " (declare (in) ivec4 arg1))\n" - " ((return (expression bvec4 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 arg0)\n" - " (declare (in) uvec2 arg1))\n" - " ((return (expression bvec2 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uvec3 arg1))\n" - " ((return (expression bvec3 > (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 arg0)\n" - " (declare (in) uvec4 arg1))\n" - " ((return (expression bvec4 > (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_greaterThanEqual = - "((function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 arg0)\n" - " (declare (in) vec2 arg1))\n" - " ((return (expression bvec2 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) vec3 arg1))\n" - " ((return (expression bvec3 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 arg0)\n" - " (declare (in) vec4 arg1))\n" - " ((return (expression bvec4 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 arg0)\n" - " (declare (in) ivec2 arg1))\n" - " ((return (expression bvec2 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) ivec3 arg1))\n" - " ((return (expression bvec3 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 arg0)\n" - " (declare (in) ivec4 arg1))\n" - " ((return (expression bvec4 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 arg0)\n" - " (declare (in) uvec2 arg1))\n" - " ((return (expression bvec2 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uvec3 arg1))\n" - " ((return (expression bvec3 >= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 arg0)\n" - " (declare (in) uvec4 arg1))\n" - " ((return (expression bvec4 >= (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_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 *builtin_length = - "((function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float arg0))\n" - " ((return (expression float abs (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 *builtin_lessThan = - "((function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 arg0)\n" - " (declare (in) vec2 arg1))\n" - " ((return (expression bvec2 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) vec3 arg1))\n" - " ((return (expression bvec3 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 arg0)\n" - " (declare (in) vec4 arg1))\n" - " ((return (expression bvec4 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 arg0)\n" - " (declare (in) ivec2 arg1))\n" - " ((return (expression bvec2 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) ivec3 arg1))\n" - " ((return (expression bvec3 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 arg0)\n" - " (declare (in) ivec4 arg1))\n" - " ((return (expression bvec4 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 arg0)\n" - " (declare (in) uvec2 arg1))\n" - " ((return (expression bvec2 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uvec3 arg1))\n" - " ((return (expression bvec3 < (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 arg0)\n" - " (declare (in) uvec4 arg1))\n" - " ((return (expression bvec4 < (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_lessThanEqual = - "((function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 arg0)\n" - " (declare (in) vec2 arg1))\n" - " ((return (expression bvec2 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) vec3 arg1))\n" - " ((return (expression bvec3 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 arg0)\n" - " (declare (in) vec4 arg1))\n" - " ((return (expression bvec4 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 arg0)\n" - " (declare (in) ivec2 arg1))\n" - " ((return (expression bvec2 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) ivec3 arg1))\n" - " ((return (expression bvec3 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 arg0)\n" - " (declare (in) ivec4 arg1))\n" - " ((return (expression bvec4 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 arg0)\n" - " (declare (in) uvec2 arg1))\n" - " ((return (expression bvec2 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uvec3 arg1))\n" - " ((return (expression bvec3 <= (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 arg0)\n" - " (declare (in) uvec4 arg1))\n" - " ((return (expression bvec4 <= (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_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 *builtin_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 *builtin_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)) (xy) (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)) (xy) (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)) (xyz) (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)) (xyz) (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)) (xyz) (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)) (xyzw) (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)) (xyzw) (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)) (xyzw) (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)) (xyzw) (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" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat2x3 x)\n" - " (declare (in) mat2x3 y))\n" - " ((declare () mat2x3 z)\n" - " (assign (constant bool (1)) (xyz) (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)) (xyz) (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)) (xy) (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)) (xy) (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)) (xy) (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)) (xyzw) (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)) (xyzw) (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)) (xy) (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)) (xy) (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)) (xy) (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)) (xy) (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)) (xyzw) (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)) (xyzw) (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)) (xyzw) (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)) (xyz) (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)) (xyz) (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)) (xyz) (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)) (xyz) (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 *builtin_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" - " ((return (expression vec2 max (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) float 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) float arg1))\n" - " ((return (expression vec4 max (var_ref arg0) (var_ref arg1)))))\n" - "\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" - " ((return (expression ivec2 max (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) int 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) int arg1))\n" - " ((return (expression ivec4 max (var_ref arg0) (var_ref arg1)))))\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" - " ((return (expression uvec2 max (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uint 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) uint arg1))\n" - " ((return (expression uvec4 max (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_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" - " ((return (expression vec2 min (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) float 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) float arg1))\n" - " ((return (expression vec4 min (var_ref arg0) (var_ref arg1)))))\n" - "\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" - " ((return (expression ivec2 min (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) int 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) int arg1))\n" - " ((return (expression ivec4 min (var_ref arg0) (var_ref arg1)))))\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" - " ((return (expression uvec2 min (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uint 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) uint arg1))\n" - " ((return (expression uvec4 min (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_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 float - (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 float - (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 float - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))\n" - "\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float v1)\n" - " (declare (in) float v2)\n" - " (declare (in) bool a))\n" - " ((assign (var_ref a) (var_ref v1) (var_ref v2))\n" - " (return (var_ref v1))))\n" - "\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 v1)\n" - " (declare (in) vec2 v2)\n" - " (declare (in) bvec2 a))\n" - " ((assign (swiz x (var_ref a)) (x) (var_ref v1) (swiz x (var_ref v2)))\n" - " (assign (swiz y (var_ref a)) (y) (var_ref v1) (swiz y (var_ref v2)))\n" - " (return (var_ref v1))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 v1)\n" - " (declare (in) vec3 v2)\n" - " (declare (in) bvec3 a))\n" - " ((assign (swiz x (var_ref a)) (x) (var_ref v1) (swiz x (var_ref v2)))\n" - " (assign (swiz y (var_ref a)) (y) (var_ref v1) (swiz y (var_ref v2)))\n" - " (assign (swiz z (var_ref a)) (z) (var_ref v1) (swiz z (var_ref v2)))\n" - " (return (var_ref v1))))\n" - "\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 v1)\n" - " (declare (in) vec4 v2)\n" - " (declare (in) bvec4 a))\n" - " ((assign (swiz x (var_ref a)) (x) (var_ref v1) (swiz x (var_ref v2)))\n" - " (assign (swiz y (var_ref a)) (y) (var_ref v1) (swiz y (var_ref v2)))\n" - " (assign (swiz z (var_ref a)) (z) (var_ref v1) (swiz z (var_ref v2)))\n" - " (assign (swiz w (var_ref a)) (w) (var_ref v1) (swiz w (var_ref v2)))\n" - " (return (var_ref v1))))\n" - "))\n" - "" -; -static const char *builtin_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" - " ((return (expression vec2 % (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) float 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) float arg1))\n" - " ((return (expression vec4 % (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_noise1 = - "((function noise1\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ((return (expression float noise (var_ref x)))))\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ((return (expression float noise (var_ref x)))))\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ((return (expression float noise (var_ref x)))))\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ((return (expression float noise (var_ref x)))))\n" - "))\n" - "" -; -static const char *builtin_noise2 = - "((function noise2\n" - " (signature vec2\n" - " (parameters (declare (in) vec4 p))\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () vec2 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec4 + (var_ref p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (return (var_ref t))\n" - " ))\n" - "\n" - " (signature vec2\n" - " (parameters (declare (in) vec3 p))\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () vec2 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec3 + (var_ref p) (constant vec3 (601.0 313.0 29.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (return (var_ref t))\n" - " ))\n" - "\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in ) vec2 p)\n" - " )\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () vec2 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec2 + (var_ref p) (constant vec2 (601.0 313.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (return (var_ref t))\n" - " ))\n" - "\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in ) float p)\n" - " )\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () vec2 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression float + (var_ref p) (constant float (601.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (return (var_ref t))\n" - " ))\n" - "))\n" - "" -; -static const char *builtin_noise3 = - "((function noise3\n" - " (signature vec3\n" - " (parameters (declare (in) vec4 p))\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () float c)\n" - " (declare () vec3 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec4 + (var_ref p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression vec4 + (var_ref p) (constant vec4 (1559.0 113.0 1861.0 797.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n" - " (return (var_ref t))\n" - " ))\n" - "\n" - " (signature vec3\n" - " (parameters (declare (in) vec3 p))\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () float c)\n" - " (declare () vec3 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec3 + (var_ref p) (constant vec3 (601.0 313.0 29.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression vec3 + (var_ref p) (constant vec3 (1559.0 113.0 1861.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n" - " (return (var_ref t))\n" - " ))\n" - "\n" - " (signature vec3\n" - " (parameters (declare (in) vec2 p))\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () float c)\n" - " (declare () vec3 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec2 + (var_ref p) (constant vec2 (601.0 313.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression vec2 + (var_ref p) (constant vec2 (1559.0 113.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n" - " (return (var_ref t))\n" - " ))\n" - "\n" - " (signature vec3\n" - " (parameters (declare (in) float p))\n" - " (\n" - " (declare () float a)\n" - " (declare () float b)\n" - " (declare () float c)\n" - " (declare () vec3 t)\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression float + (var_ref p) (constant float (601.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression float + (var_ref p) (constant float (1559.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n" - " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n" - " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n" - " (return (var_ref t))\n" - " ))\n" - "))\n" - "" -; -static const char *builtin_noise4 = - "((function noise4\n" - " (signature vec4\n" - " (parameters (declare (in) vec4 p))\n" - " (\n" - " (declare () float _x)\n" - " (declare () float _y)\n" - " (declare () float _z)\n" - " (declare () float _w)\n" - " (declare () vec4 _r)\n" - "\n" - " (declare () vec4 _p)\n" - " (assign (constant bool (1)) (xyzw) (var_ref _p) (expression vec4 + (var_ref p) (constant vec4 (1559.0 113.0 1861.0 797.0))) )\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression vec4 + (var_ref p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n" - " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression vec4 + (var_ref _p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n" - " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n" - " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n" - " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n" - " (return (var_ref _r))\n" - " ))\n" - "\n" - " (signature vec4\n" - " (parameters (declare (in) vec3 p))\n" - " (\n" - " (declare () float _x)\n" - " (declare () float _y)\n" - " (declare () float _z)\n" - " (declare () float _w)\n" - " (declare () vec4 _r)\n" - "\n" - " (declare () vec3 _p)\n" - " (assign (constant bool (1)) (xyz) (var_ref _p) (expression vec3 + (var_ref p) (constant vec3 (1559.0 113.0 1861.0))) )\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression vec3 + (var_ref p) (constant vec3 (601.0 313.0 29.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n" - " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression vec3 + (var_ref _p) (constant vec3 (601.0 313.0 29.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n" - " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n" - " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n" - " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n" - " (return (var_ref _r))\n" - " ))\n" - "\n" - " (signature vec4\n" - " (parameters (declare (in) vec2 p))\n" - " (\n" - " (declare () float _x)\n" - " (declare () float _y)\n" - " (declare () float _z)\n" - " (declare () float _w)\n" - " (declare () vec4 _r)\n" - "\n" - " (declare () vec2 _p)\n" - " (assign (constant bool (1)) (xy) (var_ref _p) (expression vec2 + (var_ref p) (constant vec2 (1559.0 113.0))) )\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression vec2 + (var_ref p) (constant vec2 (601.0 313.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n" - " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression vec2 + (var_ref _p) (constant vec2 (601.0 313.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n" - " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n" - " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n" - " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n" - " (return (var_ref _r))\n" - " ))\n" - "\n" - " (signature vec4\n" - " (parameters (declare (in) float p))\n" - " (\n" - " (declare () float _x)\n" - " (declare () float _y)\n" - " (declare () float _z)\n" - " (declare () float _w)\n" - " (declare () vec4 _r)\n" - "\n" - " (declare () float _p)\n" - " (assign (constant bool (1)) (x) (var_ref _p) (expression float + (var_ref p) (constant float (1559.0))) )\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n" - " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression float + (var_ref p) (constant float (601.0 313.0 29.0 277.0)))))\n" - " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n" - " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression float + (var_ref _p) (constant float (601.0 313.0 29.0 277.0)))))\n" - "\n" - " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n" - " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n" - " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n" - " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n" - " (return (var_ref _r))\n" - " ))\n" - "))\n" - "" -; -static const char *builtin_normalize = - "((function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float arg0))\n" - " ((return (expression float sign (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 *builtin_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 *builtin_notEqual = - "((function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 arg0)\n" - " (declare (in) vec2 arg1))\n" - " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 arg0)\n" - " (declare (in) vec3 arg1))\n" - " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 arg0)\n" - " (declare (in) vec4 arg1))\n" - " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 arg0)\n" - " (declare (in) bvec2 arg1))\n" - " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 arg0)\n" - " (declare (in) bvec3 arg1))\n" - " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 arg0)\n" - " (declare (in) bvec4 arg1))\n" - " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 arg0)\n" - " (declare (in) ivec2 arg1))\n" - " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 arg0)\n" - " (declare (in) ivec3 arg1))\n" - " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 arg0)\n" - " (declare (in) ivec4 arg1))\n" - " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 arg0)\n" - " (declare (in) uvec2 arg1))\n" - " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 arg0)\n" - " (declare (in) uvec3 arg1))\n" - " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n" - "\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 arg0)\n" - " (declare (in) uvec4 arg1))\n" - " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n" - "))\n" - "" -; -static const char *builtin_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)) (xy) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref u) (swiz y (var_ref v))))\n" - " (return (var_ref m))))\n" - "\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) vec3 u)\n" - " (declare (in) vec2 v))\n" - " ((declare () mat2x3 m)\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref u) (swiz y (var_ref v))))\n" - " (return (var_ref m))))\n" - "\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) vec4 u)\n" - " (declare (in) vec2 v))\n" - " ((declare () mat2x4 m)\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref u) (swiz y (var_ref v))))\n" - " (return (var_ref m))))\n" - "\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) vec2 u)\n" - " (declare (in) vec3 v))\n" - " ((declare () mat3x2 m)\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref u) (swiz y (var_ref v))))\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref u) (swiz z (var_ref v))))\n" - " (return (var_ref m))\n" - " ))\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)) (xyz) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref u) (swiz y (var_ref v))))\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref u) (swiz z (var_ref v))))\n" - " (return (var_ref m))))\n" - "\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) vec4 u)\n" - " (declare (in) vec3 v))\n" - " ((declare () mat3x4 m)\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref u) (swiz y (var_ref v))))\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref u) (swiz z (var_ref v))))\n" - " (return (var_ref m))))\n" - "\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) vec2 u)\n" - " (declare (in) vec4 v))\n" - " ((declare () mat4x2 m)\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref u) (swiz y (var_ref v))))\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref u) (swiz z (var_ref v))))\n" - " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (3))) (expression vec2 * (var_ref u) (swiz w (var_ref v))))\n" - " (return (var_ref m))))\n" - "\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) vec3 u)\n" - " (declare (in) vec4 v))\n" - " ((declare () mat4x3 m)\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref u) (swiz y (var_ref v))))\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref u) (swiz z (var_ref v))))\n" - " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (3))) (expression vec3 * (var_ref u) (swiz w (var_ref v))))\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)) (xyzw) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref u) (swiz x (var_ref v))))\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref u) (swiz y (var_ref v))))\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref u) (swiz z (var_ref v))))\n" - " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (3))) (expression vec4 * (var_ref u) (swiz w (var_ref v))))\n" - " (return (var_ref m))))\n" - "))\n" - "" -; -static const char *builtin_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 *builtin_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 *builtin_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 *\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 *builtin_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)) (x) (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 * (var_ref n) (var_ref i))\n" - " (expression float * (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 * (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)) (x) (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)) (x) (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 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)) (x) (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 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 *builtin_shadow1D = - "((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" - " (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" - "" -; -static const char *builtin_shadow1DArray = - "((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" - " (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 *builtin_shadow1DArrayLod = - "((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" - "" -; -static const char *builtin_shadow1DLod = - "((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" - "" -; -static const char *builtin_shadow1DProj = - "((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" - " (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" - "" -; -static const char *builtin_shadow1DProjLod = - "((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" - "" -; -static const char *builtin_shadow2D = - "((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" - " (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" - "" -; -static const char *builtin_shadow2DArray = - "((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 *builtin_shadow2DLod = - "((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" - "" -; -static const char *builtin_shadow2DProj = - "((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" - " (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 *builtin_shadow2DProjLod = - "((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 *builtin_shadow2DRect = - "((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 *builtin_shadow2DRectProj = - "((function shadow2DRectProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRectShadow 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" - "" -; -static const char *builtin_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" - " ((return (expression vec2 sign (var_ref x)))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ((return (expression vec3 sign (var_ref x)))))\n" - "\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ((return (expression vec4 sign (var_ref x)))))\n" - "\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x))\n" - " ((return (expression int sign (var_ref x)))))\n" - "\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x))\n" - " ((return (expression ivec2 sign (var_ref x)))))\n" - "\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x))\n" - " ((return (expression ivec3 sign (var_ref x)))))\n" - "\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x))\n" - " ((return (expression ivec4 sign (var_ref x)))))\n" - "))\n" - "\n" - "" -; -static const char *builtin_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 *builtin_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 *builtin_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)) (x) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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)) (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" - " ((return (expression vec2 max\n" - " (expression vec2 min\n" - " (expression vec2 / (expression vec2 - (var_ref x) (var_ref edge0)) (expression vec2 - (var_ref edge1) (var_ref edge0)))\n" - " (constant vec2 (1.0 1.0)))\n" - " (constant vec2 (0.0 0.0))))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ((return (expression vec3 max\n" - " (expression vec3 min\n" - " (expression vec3 / (expression vec3 - (var_ref x) (var_ref edge0)) (expression vec3 - (var_ref edge1) (var_ref edge0)))\n" - " (constant vec3 (1.0 1.0 1.0)))\n" - " (constant vec3 (0.0 0.0 0.0))))))\n" - "\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ((return (expression vec4 max\n" - " (expression vec4 min\n" - " (expression vec4 / (expression vec4 - (var_ref x) (var_ref edge0)) (expression vec4 - (var_ref edge1) (var_ref edge0)))\n" - " (constant vec4 (1.0 1.0 1.0 1.0)))\n" - " (constant vec4 (0.0 0.0 0.0 0.0))))))\n" - "))\n" - "\n" - "" -; -static const char *builtin_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 *builtin_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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(var_ref edge))))\n" - " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(var_ref edge))))\n" - " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(var_ref edge))))\n" - " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(var_ref edge))))\n" - " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(var_ref edge))))\n" - " (assign (constant bool (1)) (z) (var_ref t) (expression float b2f (expression bool >= (swiz z (var_ref x))(var_ref edge))))\n" - " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(swiz x (var_ref edge)))))\n" - " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(swiz x (var_ref edge)))))\n" - " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(swiz y (var_ref edge)))))\n" - " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(swiz x (var_ref edge)))))\n" - " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(swiz y (var_ref edge)))))\n" - " (assign (constant bool (1)) (z) (var_ref t) (expression float b2f (expression bool >= (swiz z (var_ref x))(swiz z (var_ref edge)))))\n" - " (assign (constant bool (1)) (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 *builtin_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 vec2 / (expression vec2 sin (var_ref angle)) (expression vec2 cos (var_ref angle))))))\n" - "\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ((return (expression vec3 / (expression vec3 sin (var_ref angle)) (expression vec3 cos (var_ref angle))))))\n" - "\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ((return (expression vec4 / (expression vec4 sin (var_ref angle)) (expression vec4 cos (var_ref angle))))))\n" - "))\n" - "" -; -static const char *builtin_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 *builtin_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 *builtin_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" - " (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 *builtin_texture1D = - "((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" - " (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" - "" -; -static const char *builtin_texture1DArray = - "((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" - " (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" - "" -; -static const char *builtin_texture1DArrayLod = - "((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" - "" -; -static const char *builtin_texture1DLod = - "((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" - "" -; -static const char *builtin_texture1DProj = - "((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" - " (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" - "" -; -static const char *builtin_texture1DProjLod = - "((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" - "" -; -static const char *builtin_texture2D = - "((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" - " (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" - "" -; -static const char *builtin_texture2DArray = - "((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" - " (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" - "" -; -static const char *builtin_texture2DArrayLod = - "((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" - "" -; -static const char *builtin_texture2DLod = - "((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" - "" -; -static const char *builtin_texture2DProj = - "((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" - " (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" - "" -; -static const char *builtin_texture2DProjLod = - "((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" - "" -; -static const char *builtin_texture2DRect = - "((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" - "" -; -static const char *builtin_texture2DRectProj = - "((function texture2DRectProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRect 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) sampler2DRect 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" - "" -; -static const char *builtin_texture3D = - "((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" - " (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" - "" -; -static const char *builtin_texture3DLod = - "((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" - "" -; -static const char *builtin_texture3DProj = - "((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" - " (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" - "" -; -static const char *builtin_texture3DProjLod = - "((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" - "" -; -static const char *builtin_textureCube = - "((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" - " (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" - "" -; -static const char *builtin_textureCubeLod = - "((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" - "" -; -static const char *builtin_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" - "" -; -static const char *builtin_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 *builtin_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" - " (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 *builtin_textureProjGrad = - "((function textureProjGrad\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 *builtin_textureProjLod = - "((function textureProjLod\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 *builtin_transpose = - "((function transpose\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 m))\n" - " ((declare () mat2 t)\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (3)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (3)))))\n" - " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (3)))))\n" - " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (0)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (1)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (2)))))\n" - " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (3)))))\n" - " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (3)))))\n" - " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (3)))))\n" - " (assign (constant bool (1)) (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 *prototypes_for_100_frag = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ())))" -; -static const char *functions_for_100_frag [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cross, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_sign, - builtin_sin, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_texture2D, - builtin_texture2DProj, - builtin_textureCube, -}; -static const char *prototypes_for_100_vert = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function texture2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function textureCubeLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ())))" -; -static const char *functions_for_100_vert [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cross, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_sign, - builtin_sin, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_texture2D, - builtin_texture2DLod, - builtin_texture2DProj, - builtin_texture2DProjLod, - builtin_textureCube, - builtin_textureCubeLod, -}; -static const char *prototypes_for_110_frag = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function dFdx\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function dFdy\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function fwidth\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function noise1\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise2\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise3\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise4\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())))" -; -static const char *functions_for_110_frag [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cross, - builtin_dFdx, - builtin_dFdy, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_fwidth, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_noise1, - builtin_noise2, - builtin_noise3, - builtin_noise4, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_shadow1D, - builtin_shadow1DProj, - builtin_shadow2D, - builtin_shadow2DProj, - builtin_sign, - builtin_sin, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_texture1D, - builtin_texture1DProj, - builtin_texture2D, - builtin_texture2DProj, - builtin_texture3D, - builtin_texture3DProj, - builtin_textureCube, -}; -static const char *prototypes_for_110_vert = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ftransform\n" - " (signature vec4\n" - " (parameters)\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord))\n" - " ()))\n" - "(function texture1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function texture1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function texture2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function texture3DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function texture3DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function textureCubeLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function shadow2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function shadow1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function shadow2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function shadow1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function noise1\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise2\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise3\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise4\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())))" -; -static const char *functions_for_110_vert [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cross, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_ftransform, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_noise1, - builtin_noise2, - builtin_noise3, - builtin_noise4, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_shadow1D, - builtin_shadow1DLod, - builtin_shadow1DProj, - builtin_shadow1DProjLod, - builtin_shadow2D, - builtin_shadow2DLod, - builtin_shadow2DProj, - builtin_shadow2DProjLod, - builtin_sign, - builtin_sin, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_texture1D, - builtin_texture1DLod, - builtin_texture1DProj, - builtin_texture1DProjLod, - builtin_texture2D, - builtin_texture2DLod, - builtin_texture2DProj, - builtin_texture2DProjLod, - builtin_texture3D, - builtin_texture3DLod, - builtin_texture3DProj, - builtin_texture3DProjLod, - builtin_textureCube, - builtin_textureCubeLod, -}; -static const char *prototypes_for_120_frag = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat2x3 x)\n" - " (declare (in) mat2x3 y))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat2x4 x)\n" - " (declare (in) mat2x4 y))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat3x2 x)\n" - " (declare (in) mat3x2 y))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat3x4 x)\n" - " (declare (in) mat3x4 y))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat4x2 x)\n" - " (declare (in) mat4x2 y))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat4x3 x)\n" - " (declare (in) mat4x3 y))\n" - " ()))\n" - "(function outerProduct\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec4 r))\n" - " ()))\n" - "(function transpose\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 m))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 m))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 m))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat3x2 m))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat2x3 m))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat4x2 m))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat2x4 m))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat4x3 m))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat3x4 m))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function dFdx\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function dFdy\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function fwidth\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function noise1\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise2\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise3\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise4\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())))" -; -static const char *functions_for_120_frag [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cross, - builtin_dFdx, - builtin_dFdy, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_fwidth, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_noise1, - builtin_noise2, - builtin_noise3, - builtin_noise4, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_outerProduct, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_shadow1D, - builtin_shadow1DProj, - builtin_shadow2D, - builtin_shadow2DProj, - builtin_sign, - builtin_sin, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_texture1D, - builtin_texture1DProj, - builtin_texture2D, - builtin_texture2DProj, - builtin_texture3D, - builtin_texture3DProj, - builtin_textureCube, - builtin_transpose, -}; -static const char *prototypes_for_120_vert = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ftransform\n" - " (signature vec4\n" - " (parameters)\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat2x3 x)\n" - " (declare (in) mat2x3 y))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat2x4 x)\n" - " (declare (in) mat2x4 y))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat3x2 x)\n" - " (declare (in) mat3x2 y))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat3x4 x)\n" - " (declare (in) mat3x4 y))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat4x2 x)\n" - " (declare (in) mat4x2 y))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat4x3 x)\n" - " (declare (in) mat4x3 y))\n" - " ()))\n" - "(function outerProduct\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec4 r))\n" - " ()))\n" - "(function transpose\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 m))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 m))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 m))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat3x2 m))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat2x3 m))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat4x2 m))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat2x4 m))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat4x3 m))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat3x4 m))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord))\n" - " ()))\n" - "(function texture1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function texture1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function texture2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function texture3DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function texture3DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function textureCubeLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function shadow2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function shadow1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function shadow2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function shadow1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function noise1\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise2\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise3\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise4\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())))" -; -static const char *functions_for_120_vert [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cross, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_ftransform, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_noise1, - builtin_noise2, - builtin_noise3, - builtin_noise4, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_outerProduct, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_shadow1D, - builtin_shadow1DLod, - builtin_shadow1DProj, - builtin_shadow1DProjLod, - builtin_shadow2D, - builtin_shadow2DLod, - builtin_shadow2DProj, - builtin_shadow2DProjLod, - builtin_sign, - builtin_sin, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_texture1D, - builtin_texture1DLod, - builtin_texture1DProj, - builtin_texture1DProjLod, - builtin_texture2D, - builtin_texture2DLod, - builtin_texture2DProj, - builtin_texture2DProjLod, - builtin_texture3D, - builtin_texture3DLod, - builtin_texture3DProj, - builtin_texture3DProjLod, - builtin_textureCube, - builtin_textureCubeLod, - builtin_transpose, -}; -static const char *prototypes_for_130_frag = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function sinh\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function cosh\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function tanh\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature uint\n" - " (parameters\n" - " (declare (in) uint x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uint y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature uint\n" - " (parameters\n" - " (declare (in) uint x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uint y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 minVal)\n" - " (declare (in) ivec2 maxVal))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 minVal)\n" - " (declare (in) ivec3 maxVal))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 minVal)\n" - " (declare (in) ivec4 maxVal))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature uint\n" - " (parameters\n" - " (declare (in) uint x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 minVal)\n" - " (declare (in) uvec2 maxVal))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 minVal)\n" - " (declare (in) uvec3 maxVal))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 minVal)\n" - " (declare (in) uvec4 maxVal))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat2x3 x)\n" - " (declare (in) mat2x3 y))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat2x4 x)\n" - " (declare (in) mat2x4 y))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat3x2 x)\n" - " (declare (in) mat3x2 y))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat3x4 x)\n" - " (declare (in) mat3x4 y))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat4x2 x)\n" - " (declare (in) mat4x2 y))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat4x3 x)\n" - " (declare (in) mat4x3 y))\n" - " ()))\n" - "(function outerProduct\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec4 r))\n" - " ()))\n" - "(function transpose\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 m))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 m))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 m))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat3x2 m))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat2x3 m))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat4x2 m))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat2x4 m))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat4x3 m))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat3x4 m))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) float P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) float P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isamplerCube sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usamplerCube sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) samplerCubeShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DArrayShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) samplerCubeShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texelFetch\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) int P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) int P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) int P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ()))\n" - "(function textureProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) samplerCubeShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) vec3 dPdx)\n" - " (declare (in) vec3 dPdy))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DArrayShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ()))\n" - "(function textureProjGrad\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ()))\n" - "(function texture1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureCubeLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function dFdx\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function dFdy\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function fwidth\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 p))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 p))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 p))\n" - " ()))\n" - "(function noise1\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise2\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise3\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise4\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())))" -; -static const char *functions_for_130_frag [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cosh, - builtin_cross, - builtin_dFdx, - builtin_dFdy, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_fwidth, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_noise1, - builtin_noise2, - builtin_noise3, - builtin_noise4, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_outerProduct, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_shadow1D, - builtin_shadow1DLod, - builtin_shadow1DProj, - builtin_shadow1DProjLod, - builtin_shadow2D, - builtin_shadow2DLod, - builtin_shadow2DProj, - builtin_shadow2DProjLod, - builtin_sign, - builtin_sin, - builtin_sinh, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_tanh, - builtin_texelFetch, - builtin_texture, - builtin_texture1D, - builtin_texture1DLod, - builtin_texture1DProj, - builtin_texture1DProjLod, - builtin_texture2D, - builtin_texture2DLod, - builtin_texture2DProj, - builtin_texture2DProjLod, - builtin_texture3D, - builtin_texture3DLod, - builtin_texture3DProj, - builtin_texture3DProjLod, - builtin_textureCube, - builtin_textureCubeLod, - builtin_textureGrad, - builtin_textureLod, - builtin_textureProj, - builtin_textureProjGrad, - builtin_textureProjLod, - builtin_transpose, -}; -static const char *prototypes_for_130_vert = - "(\n" - "(function radians\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float degrees))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 degrees))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 degrees))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 degrees))\n" - " ()))\n" - "(function degrees\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float radians))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 radians))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 radians))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 radians))\n" - " ()))\n" - "(function sin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function cos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function tan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function asin\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function acos\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float angle))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 angle))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 angle))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 angle))\n" - " ()))\n" - "(function atan\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float y_over_x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 y_over_x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 y_over_x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 y_over_x))\n" - " ()))\n" - "(function sinh\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function cosh\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function tanh\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function pow\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function exp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function exp2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function log2\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function sqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function inversesqrt\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function abs\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x))\n" - " ()))\n" - "(function sign\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x))\n" - " ()))\n" - "(function floor\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ceil\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function fract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function mod\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function min\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature uint\n" - " (parameters\n" - " (declare (in) uint x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uint y))\n" - " ()))\n" - "(function max\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) int y))\n" - " ())\n" - " (signature uint\n" - " (parameters\n" - " (declare (in) uint x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uint y))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uint y))\n" - " ()))\n" - "(function clamp\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 minVal)\n" - " (declare (in) vec2 maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 minVal)\n" - " (declare (in) vec3 maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 minVal)\n" - " (declare (in) vec4 maxVal))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) float minVal)\n" - " (declare (in) float maxVal))\n" - " ())\n" - " (signature int\n" - " (parameters\n" - " (declare (in) int x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 minVal)\n" - " (declare (in) ivec2 maxVal))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 minVal)\n" - " (declare (in) ivec3 maxVal))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 minVal)\n" - " (declare (in) ivec4 maxVal))\n" - " ())\n" - " (signature ivec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature ivec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) int minVal)\n" - " (declare (in) int maxVal))\n" - " ())\n" - " (signature uint\n" - " (parameters\n" - " (declare (in) uint x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 minVal)\n" - " (declare (in) uvec2 maxVal))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 minVal)\n" - " (declare (in) uvec3 maxVal))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 minVal)\n" - " (declare (in) uvec4 maxVal))\n" - " ())\n" - " (signature uvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ())\n" - " (signature uvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uint minVal)\n" - " (declare (in) uint maxVal))\n" - " ()))\n" - "(function mix\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) vec2 a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) vec3 a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) vec4 a))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y)\n" - " (declare (in) float a))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y)\n" - " (declare (in) float a))\n" - " ()))\n" - "(function step\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function smoothstep\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 edge0)\n" - " (declare (in) vec2 edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 edge0)\n" - " (declare (in) vec3 edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 edge0)\n" - " (declare (in) vec4 edge1)\n" - " (declare (in) vec4 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float edge0)\n" - " (declare (in) float edge1)\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function length\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function distance\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float p0)\n" - " (declare (in) float p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 p0)\n" - " (declare (in) vec2 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 p0)\n" - " (declare (in) vec3 p1))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 p0)\n" - " (declare (in) vec4 p1))\n" - " ()))\n" - "(function dot\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x)\n" - " (declare (in) float y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ()))\n" - "(function cross\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ()))\n" - "(function normalize\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function ftransform\n" - " (signature vec4\n" - " (parameters)\n" - " ()))\n" - "(function faceforward\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float N)\n" - " (declare (in) float I)\n" - " (declare (in) float Nref))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 N)\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 Nref))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 N)\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 Nref))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 N)\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 Nref))\n" - " ()))\n" - "(function reflect\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N))\n" - " ()))\n" - "(function refract\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float I)\n" - " (declare (in) float N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 I)\n" - " (declare (in) vec2 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 I)\n" - " (declare (in) vec3 N)\n" - " (declare (in) float eta))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 I)\n" - " (declare (in) vec4 N)\n" - " (declare (in) float eta))\n" - " ()))\n" - "(function matrixCompMult\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 x)\n" - " (declare (in) mat2 y))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 x)\n" - " (declare (in) mat3 y))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 x)\n" - " (declare (in) mat4 y))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat2x3 x)\n" - " (declare (in) mat2x3 y))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat2x4 x)\n" - " (declare (in) mat2x4 y))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat3x2 x)\n" - " (declare (in) mat3x2 y))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat3x4 x)\n" - " (declare (in) mat3x4 y))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat4x2 x)\n" - " (declare (in) mat4x2 y))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat4x3 x)\n" - " (declare (in) mat4x3 y))\n" - " ()))\n" - "(function outerProduct\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec2 r))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) vec2 c)\n" - " (declare (in) vec4 r))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) vec4 c)\n" - " (declare (in) vec3 r))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) vec3 c)\n" - " (declare (in) vec4 r))\n" - " ()))\n" - "(function transpose\n" - " (signature mat2\n" - " (parameters\n" - " (declare (in) mat2 m))\n" - " ())\n" - " (signature mat3\n" - " (parameters\n" - " (declare (in) mat3 m))\n" - " ())\n" - " (signature mat4\n" - " (parameters\n" - " (declare (in) mat4 m))\n" - " ())\n" - " (signature mat2x3\n" - " (parameters\n" - " (declare (in) mat3x2 m))\n" - " ())\n" - " (signature mat3x2\n" - " (parameters\n" - " (declare (in) mat2x3 m))\n" - " ())\n" - " (signature mat2x4\n" - " (parameters\n" - " (declare (in) mat4x2 m))\n" - " ())\n" - " (signature mat4x2\n" - " (parameters\n" - " (declare (in) mat2x4 m))\n" - " ())\n" - " (signature mat3x4\n" - " (parameters\n" - " (declare (in) mat4x3 m))\n" - " ())\n" - " (signature mat4x3\n" - " (parameters\n" - " (declare (in) mat3x4 m))\n" - " ()))\n" - "(function lessThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function lessThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function greaterThan\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function greaterThanEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ()))\n" - "(function equal\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function notEqual\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) vec2 x)\n" - " (declare (in) vec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) vec3 x)\n" - " (declare (in) vec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) vec4 x)\n" - " (declare (in) vec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) ivec2 x)\n" - " (declare (in) ivec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) ivec3 x)\n" - " (declare (in) ivec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) ivec4 x)\n" - " (declare (in) ivec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) uvec2 x)\n" - " (declare (in) uvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) uvec3 x)\n" - " (declare (in) uvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) uvec4 x)\n" - " (declare (in) uvec4 y))\n" - " ())\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x)\n" - " (declare (in) bvec2 y))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x)\n" - " (declare (in) bvec3 y))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x)\n" - " (declare (in) bvec4 y))\n" - " ()))\n" - "(function any\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function all\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bool\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function not\n" - " (signature bvec2\n" - " (parameters\n" - " (declare (in) bvec2 x))\n" - " ())\n" - " (signature bvec3\n" - " (parameters\n" - " (declare (in) bvec3 x))\n" - " ())\n" - " (signature bvec4\n" - " (parameters\n" - " (declare (in) bvec4 x))\n" - " ()))\n" - "(function texture\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) float P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) float P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isamplerCube sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usamplerCube sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) samplerCubeShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DArrayShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) samplerCubeShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec2 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec3 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) float P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usamplerCube sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texelFetch\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) int P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) int P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) int P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) ivec2 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) ivec3 P)\n" - " (declare (in) int lod))\n" - " ()))\n" - "(function textureProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler3D sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) samplerCubeShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) vec3 dPdx)\n" - " (declare (in) vec3 dPdy))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler1DArray sampler)\n" - " (declare (in) vec2 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature ivec4\n" - " (parameters\n" - " (declare (in) isampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature uvec4\n" - " (parameters\n" - " (declare (in) usampler2DArray sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DArrayShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ()))\n" - "(function textureProjGrad\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\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" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) float dPdx)\n" - " (declare (in) float dPdy))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 P)\n" - " (declare (in) vec2 dPdx)\n" - " (declare (in) vec2 dPdy))\n" - " ()))\n" - "(function texture1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) float coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture3DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture3DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler3D sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function textureCube\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function textureCubeLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) samplerCube sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2D\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2DProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DProjLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DShadow sampler)\n" - " (declare (in) vec4 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function noise1\n" - " (signature float\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature float\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise2\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec2\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise3\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec3\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ()))\n" - "(function noise4\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) float x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec2 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec3 x))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) vec4 x))\n" - " ())))" -; -static const char *functions_for_130_vert [] = { - builtin_abs, - builtin_acos, - builtin_all, - builtin_any, - builtin_asin, - builtin_atan, - builtin_ceil, - builtin_clamp, - builtin_cos, - builtin_cosh, - builtin_cross, - builtin_degrees, - builtin_distance, - builtin_dot, - builtin_equal, - builtin_exp, - builtin_exp2, - builtin_faceforward, - builtin_floor, - builtin_fract, - builtin_ftransform, - builtin_greaterThan, - builtin_greaterThanEqual, - builtin_inversesqrt, - builtin_length, - builtin_lessThan, - builtin_lessThanEqual, - builtin_log, - builtin_log2, - builtin_matrixCompMult, - builtin_max, - builtin_min, - builtin_mix, - builtin_mod, - builtin_noise1, - builtin_noise2, - builtin_noise3, - builtin_noise4, - builtin_normalize, - builtin_not, - builtin_notEqual, - builtin_outerProduct, - builtin_pow, - builtin_radians, - builtin_reflect, - builtin_refract, - builtin_shadow1D, - builtin_shadow1DLod, - builtin_shadow1DProj, - builtin_shadow1DProjLod, - builtin_shadow2D, - builtin_shadow2DLod, - builtin_shadow2DProj, - builtin_shadow2DProjLod, - builtin_sign, - builtin_sin, - builtin_sinh, - builtin_smoothstep, - builtin_sqrt, - builtin_step, - builtin_tan, - builtin_tanh, - builtin_texelFetch, - builtin_texture, - builtin_texture1D, - builtin_texture1DLod, - builtin_texture1DProj, - builtin_texture1DProjLod, - builtin_texture2D, - builtin_texture2DLod, - builtin_texture2DProj, - builtin_texture2DProjLod, - builtin_texture3D, - builtin_texture3DLod, - builtin_texture3DProj, - builtin_texture3DProjLod, - builtin_textureCube, - builtin_textureCubeLod, - builtin_textureGrad, - builtin_textureLod, - builtin_textureProj, - builtin_textureProjGrad, - builtin_textureProjLod, - builtin_transpose, -}; -static const char *prototypes_for_ARB_texture_rectangle_frag = - "(\n" - "(function texture2DRect\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRect sampler)\n" - " (declare (in) vec2 coord))\n" - " ()))\n" - "(function texture2DRectProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRect sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRect sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function shadow2DRect\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRectShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function shadow2DRectProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRectShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())))" -; -static const char *functions_for_ARB_texture_rectangle_frag [] = { - builtin_shadow2DRect, - builtin_shadow2DRectProj, - builtin_texture2DRect, - builtin_texture2DRectProj, -}; -static const char *prototypes_for_ARB_texture_rectangle_vert = - "(\n" - "(function texture2DRect\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRect sampler)\n" - " (declare (in) vec2 coord))\n" - " ()))\n" - "(function texture2DRectProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRect sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRect sampler)\n" - " (declare (in) vec4 coord))\n" - " ()))\n" - "(function shadow2DRect\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRectShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function shadow2DRectProj\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DRectShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())))" -; -static const char *functions_for_ARB_texture_rectangle_vert [] = { - builtin_shadow2DRect, - builtin_shadow2DRectProj, - builtin_texture2DRect, - builtin_texture2DRectProj, -}; -static const char *prototypes_for_EXT_texture_array_frag = - "(\n" - "(function texture1DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function texture2DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow1DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ())\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float bias))\n" - " ()))\n" - "(function shadow2DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArrayShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())))" -; -static const char *functions_for_EXT_texture_array_frag [] = { - builtin_shadow1DArray, - builtin_shadow2DArray, - builtin_texture1DArray, - builtin_texture2DArray, -}; -static const char *prototypes_for_EXT_texture_array_vert = - "(\n" - "(function texture1DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 coord))\n" - " ()))\n" - "(function texture1DArrayLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArray sampler)\n" - " (declare (in) vec2 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function texture2DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function texture2DArrayLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArray sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow1DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 coord))\n" - " ()))\n" - "(function shadow1DArrayLod\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler1DArrayShadow sampler)\n" - " (declare (in) vec3 coord)\n" - " (declare (in) float lod))\n" - " ()))\n" - "(function shadow2DArray\n" - " (signature vec4\n" - " (parameters\n" - " (declare (in) sampler2DArrayShadow sampler)\n" - " (declare (in) vec4 coord))\n" - " ())))" -; -static const char *functions_for_EXT_texture_array_vert [] = { - builtin_shadow1DArray, - builtin_shadow1DArrayLod, - builtin_shadow2DArray, - builtin_texture1DArray, - builtin_texture1DArrayLod, - builtin_texture2DArray, - builtin_texture2DArrayLod, -}; -static gl_shader *builtin_profiles[12]; - -void *builtin_mem_ctx = NULL; - -void -_mesa_glsl_release_functions(void) -{ - talloc_free(builtin_mem_ctx); - builtin_mem_ctx = NULL; - memset(builtin_profiles, 0, sizeof(builtin_profiles)); -} - -static void -_mesa_read_profile(struct _mesa_glsl_parse_state *state, - exec_list *instructions, - int profile_index, - const char *prototypes, - const char **functions, - int count) -{ - gl_shader *sh = builtin_profiles[profile_index]; - - if (sh == NULL) { - sh = read_builtins(GL_VERTEX_SHADER, prototypes, functions, count); - talloc_steal(builtin_mem_ctx, sh); - builtin_profiles[profile_index] = sh; - } - - import_prototypes(sh->ir, instructions, state->symbols, state); - state->builtins_to_link[state->num_builtins_to_link] = sh; - state->num_builtins_to_link++; -} - -void -_mesa_glsl_initialize_functions(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - if (builtin_mem_ctx == NULL) { - builtin_mem_ctx = talloc_init("GLSL built-in functions"); - memset(&builtin_profiles, 0, sizeof(builtin_profiles)); - } - - state->num_builtins_to_link = 0; - - if (state->target == fragment_shader && state->language_version == 100) { - _mesa_read_profile(state, instructions, 0, - prototypes_for_100_frag, - functions_for_100_frag, - Elements(functions_for_100_frag)); - } - - if (state->target == vertex_shader && state->language_version == 100) { - _mesa_read_profile(state, instructions, 1, - prototypes_for_100_vert, - functions_for_100_vert, - Elements(functions_for_100_vert)); - } - - if (state->target == fragment_shader && state->language_version == 110) { - _mesa_read_profile(state, instructions, 2, - prototypes_for_110_frag, - functions_for_110_frag, - Elements(functions_for_110_frag)); - } - - if (state->target == vertex_shader && state->language_version == 110) { - _mesa_read_profile(state, instructions, 3, - prototypes_for_110_vert, - functions_for_110_vert, - Elements(functions_for_110_vert)); - } - - if (state->target == fragment_shader && state->language_version == 120) { - _mesa_read_profile(state, instructions, 4, - prototypes_for_120_frag, - functions_for_120_frag, - Elements(functions_for_120_frag)); - } - - if (state->target == vertex_shader && state->language_version == 120) { - _mesa_read_profile(state, instructions, 5, - prototypes_for_120_vert, - functions_for_120_vert, - Elements(functions_for_120_vert)); - } - - if (state->target == fragment_shader && state->language_version == 130) { - _mesa_read_profile(state, instructions, 6, - prototypes_for_130_frag, - functions_for_130_frag, - Elements(functions_for_130_frag)); - } - - if (state->target == vertex_shader && state->language_version == 130) { - _mesa_read_profile(state, instructions, 7, - prototypes_for_130_vert, - functions_for_130_vert, - Elements(functions_for_130_vert)); - } - - if (state->target == fragment_shader && state->ARB_texture_rectangle_enable) { - _mesa_read_profile(state, instructions, 8, - prototypes_for_ARB_texture_rectangle_frag, - functions_for_ARB_texture_rectangle_frag, - Elements(functions_for_ARB_texture_rectangle_frag)); - } - - if (state->target == vertex_shader && state->ARB_texture_rectangle_enable) { - _mesa_read_profile(state, instructions, 9, - prototypes_for_ARB_texture_rectangle_vert, - functions_for_ARB_texture_rectangle_vert, - Elements(functions_for_ARB_texture_rectangle_vert)); - } - - if (state->target == fragment_shader && state->EXT_texture_array_enable) { - _mesa_read_profile(state, instructions, 10, - prototypes_for_EXT_texture_array_frag, - functions_for_EXT_texture_array_frag, - Elements(functions_for_EXT_texture_array_frag)); - } - - if (state->target == vertex_shader && state->EXT_texture_array_enable) { - _mesa_read_profile(state, instructions, 11, - prototypes_for_EXT_texture_array_vert, - functions_for_EXT_texture_array_vert, - Elements(functions_for_EXT_texture_array_vert)); - } - -} +/* DO NOT MODIFY - automatically generated by generate_builtins.py */
+/*
+ * 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 "main/core.h" /* for struct gl_shader */
+#include "glsl_parser_extras.h"
+#include "ir_reader.h"
+#include "program.h"
+#include "ast.h"
+
+extern "C" struct gl_shader *
+_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type);
+
+gl_shader *
+read_builtins(GLenum target, const char *protos, const char **functions, unsigned count)
+{
+ struct gl_context fakeCtx;
+ fakeCtx.API = API_OPENGL;
+ gl_shader *sh = _mesa_new_shader(NULL, 0, target);
+ struct _mesa_glsl_parse_state *st =
+ new(sh) _mesa_glsl_parse_state(&fakeCtx, target, sh);
+
+ st->language_version = 130;
+ st->symbols->language_version = 130;
+ st->ARB_texture_rectangle_enable = true;
+ st->EXT_texture_array_enable = true;
+ _mesa_glsl_initialize_types(st);
+
+ sh->ir = new(sh) exec_list;
+ sh->symbols = st->symbols;
+
+ /* Read the IR containing the prototypes */
+ _mesa_glsl_read_ir(st, sh->ir, protos, true);
+
+ /* Read ALL the function bodies, telling the IR reader not to scan for
+ * prototypes (we've already created them). The IR reader will skip any
+ * signature that does not already exist as a prototype.
+ */
+ for (unsigned i = 0; i < count; i++) {
+ _mesa_glsl_read_ir(st, sh->ir, functions[i], false);
+
+ if (st->error) {
+ printf("error reading builtin: %.35s ...\n", functions[i]);
+ printf("Info log:\n%s\n", st->info_log);
+ talloc_free(sh);
+ return NULL;
+ }
+ }
+
+ reparent_ir(sh->ir, sh);
+ delete st;
+
+ return sh;
+}
+
+static const char builtin_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 builtin_acos[] =
+ "((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 builtin_acosh[] =
+ "((function acosh\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float log (expression float + (var_ref x) (expression float sqrt (expression float - (expression float * (var_ref x) (var_ref x)) (constant float (1)))))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 log (expression vec2 + (var_ref x) (expression vec2 sqrt (expression vec2 - (expression vec2 * (var_ref x) (var_ref x)) (constant vec2 (1)))))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 log (expression vec3 + (var_ref x) (expression vec3 sqrt (expression vec3 - (expression vec3 * (var_ref x) (var_ref x)) (constant vec3 (1)))))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 log (expression vec4 + (var_ref x) (expression vec4 sqrt (expression vec4 - (expression vec4 * (var_ref x) (var_ref x)) (constant vec4 (1)))))))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_any[] =
+ "((function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 arg0))\n"
+ " ((return (expression bool any (var_ref arg0)))))\n"
+ "\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 arg0))\n"
+ " ((return (expression bool any (var_ref arg0)))))\n"
+ "\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 arg0))\n"
+ " ((return (expression bool any (var_ref arg0)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_asin[] =
+ "((function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float *\n"
+ " (expression float sign (var_ref x))\n"
+ " (expression float -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression float *\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 vec2 sign (var_ref x))\n"
+ " (expression vec2 -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression vec2 *\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 sign (var_ref x))\n"
+ " (expression vec3 -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression vec3 *\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 sign (var_ref x))\n"
+ " (expression vec4 -\n"
+ " (expression float *\n"
+ " (constant float (3.1415926))\n"
+ " (constant float (0.5)))\n"
+ " (expression vec4 *\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"
+ ""
+;
+static const char builtin_asinh[] =
+ "((function asinh\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float log (expression float + (var_ref x) (expression float sqrt (expression float + (expression float * (var_ref x) (var_ref x)) (constant float (1)))))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 log (expression vec2 + (var_ref x) (expression vec2 sqrt (expression vec2 + (expression vec2 * (var_ref x) (var_ref x)) (constant vec2 (1)))))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 log (expression vec3 + (var_ref x) (expression vec3 sqrt (expression vec3 + (expression vec3 * (var_ref x) (var_ref x)) (constant vec3 (1)))))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 log (expression vec4 + (var_ref x) (expression vec4 sqrt (expression vec4 + (expression vec4 * (var_ref x) (var_ref x)) (constant vec4 (1)))))))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_atan[] =
+ "((function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y_over_x))\n"
+ " ((return (call asin ((expression float *\n"
+ " (var_ref y_over_x)\n"
+ " (expression float rsq\n"
+ " (expression float +\n"
+ " (expression float *\n"
+ " (var_ref y_over_x)\n"
+ " (var_ref y_over_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"
+ " )\n"
+ " (\n"
+ " (declare () float r)\n"
+ " (if (expression bool > (expression float abs (var_ref x)) (constant float (0.000100))) (\n"
+ " (assign (constant bool (1)) (x) (var_ref r) (call atan ((expression float / (var_ref y) (var_ref x)))))\n"
+ " (if (expression bool < (var_ref x) (constant float (0.000000)) ) (\n"
+ " (if (expression bool >= (var_ref y) (constant float (0.000000)) )\n"
+ " ((assign (constant bool (1)) (x) (var_ref r) (expression float + (var_ref r) (constant float (3.141593)))))\n"
+ " ((assign (constant bool (1)) (x) (var_ref r) (expression float - (var_ref r) (constant float (3.141593))))))\n"
+ " )\n"
+ " (\n"
+ " ))\n"
+ " )\n"
+ " (\n"
+ " (declare () float sgn)\n"
+ " (assign (constant bool (1)) (x) (var_ref sgn) (expression float sign (var_ref y)))\n"
+ " (assign (constant bool (1)) (x) (var_ref r) (expression float * (var_ref sgn) (constant float (1.5707965))))\n"
+ " ))\n"
+ "\n"
+ " (return (var_ref r) )\n"
+ " ))\n"
+ "\n"
+ "\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ((declare () vec2 r)\n"
+ " (assign (constant bool (1)) (x) (var_ref r)\n"
+ " (call atan ((swiz x (var_ref y))\n"
+ " (swiz x (var_ref x)))))\n"
+ " (assign (constant bool (1)) (y) (var_ref r)\n"
+ " (call atan ((swiz y (var_ref y))\n"
+ " (swiz y (var_ref x)))))\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"
+ " (assign (constant bool (1)) (x) (var_ref r)\n"
+ " (call atan ((swiz x (var_ref y))\n"
+ " (swiz x (var_ref x)))))\n"
+ " (assign (constant bool (1)) (y) (var_ref r)\n"
+ " (call atan ((swiz y (var_ref y))\n"
+ " (swiz y (var_ref x)))))\n"
+ " (assign (constant bool (1)) (z) (var_ref r)\n"
+ " (call atan ((swiz z (var_ref y))\n"
+ " (swiz z (var_ref x)))))\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"
+ " (assign (constant bool (1)) (x) (var_ref r)\n"
+ " (call atan ((swiz x (var_ref y))\n"
+ " (swiz x (var_ref x)))))\n"
+ " (assign (constant bool (1)) (y) (var_ref r)\n"
+ " (call atan ((swiz y (var_ref y))\n"
+ " (swiz y (var_ref x)))))\n"
+ " (assign (constant bool (1)) (z) (var_ref r)\n"
+ " (call atan ((swiz z (var_ref y))\n"
+ " (swiz z (var_ref x)))))\n"
+ " (assign (constant bool (1)) (w) (var_ref r)\n"
+ " (call atan ((swiz w (var_ref y))\n"
+ " (swiz w (var_ref x)))))\n"
+ " (return (var_ref r)))))\n"
+ "\n"
+ "))\n"
+ ""
+;
+static const char builtin_atanh[] =
+ "((function atanh\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float * (constant float (0.5))\n"
+ " (expression float log\n"
+ " (expression float /\n"
+ " (expression float + (constant float (1)) (var_ref x))\n"
+ " (expression float - (constant float (1)) (var_ref x))))))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 * (constant vec2 (0.5))\n"
+ " (expression vec2 log\n"
+ " (expression vec2 /\n"
+ " (expression vec2 + (constant vec2 (1)) (var_ref x))\n"
+ " (expression vec2 - (constant vec2 (1)) (var_ref x))))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 * (constant vec3 (0.5))\n"
+ " (expression vec3 log\n"
+ " (expression vec3 /\n"
+ " (expression vec3 + (constant vec3 (1)) (var_ref x))\n"
+ " (expression vec3 - (constant vec3 (1)) (var_ref x))))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 * (constant vec4 (0.5))\n"
+ " (expression vec4 log\n"
+ " (expression vec4 /\n"
+ " (expression vec4 + (constant vec4 (1)) (var_ref x))\n"
+ " (expression vec4 - (constant vec4 (1)) (var_ref x))))))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_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"
+ " ((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) float arg1)\n"
+ " (declare (in) float 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) float arg1)\n"
+ " (declare (in) float arg2))\n"
+ " ((return (expression vec4 max (expression vec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "\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"
+ " ((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) int arg1)\n"
+ " (declare (in) int 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) int arg1)\n"
+ " (declare (in) int arg2))\n"
+ " ((return (expression ivec4 max (expression ivec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\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"
+ " ((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) uint arg1)\n"
+ " (declare (in) uint 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) uint arg1)\n"
+ " (declare (in) uint arg2))\n"
+ " ((return (expression uvec4 max (expression uvec4 min (var_ref arg0) (var_ref arg2)) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_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 builtin_cross[] =
+ "((function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 a)\n"
+ " (declare (in) vec3 b))\n"
+ " ((return (expression vec3 -\n"
+ " (expression vec3 * (swiz yzx (var_ref a)) (swiz zxy (var_ref b)))\n"
+ " (expression vec3 * (swiz zxy (var_ref a)) (swiz yzx (var_ref b)))))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_dFdx[] =
+ "((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"
+ ""
+;
+static const char builtin_dFdy[] =
+ "((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"
+ ""
+;
+static const char builtin_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 builtin_distance[] =
+ "((function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ((return (expression float abs (expression float - (var_ref p0) (var_ref p1))))))\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)) (xy) (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)) (xyz) (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)) (xyzw) (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 builtin_dot[] =
+ "((function dot\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 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 builtin_equal[] =
+ "((function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 arg0)\n"
+ " (declare (in) bvec2 arg1))\n"
+ " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 arg0)\n"
+ " (declare (in) bvec3 arg1))\n"
+ " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 arg0)\n"
+ " (declare (in) bvec4 arg1))\n"
+ " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression bvec2 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression bvec3 == (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression bvec4 == (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_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 builtin_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 * (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 builtin_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 builtin_fract[] =
+ "((function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float fract (var_ref x)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression vec2 fract (var_ref x)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 fract (var_ref x)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 fract (var_ref x)))))\n"
+ "))\n"
+ "\n"
+ ""
+;
+static const char builtin_ftransform[] =
+ "((declare (uniform) mat4 gl_ModelViewProjectionMatrix)\n"
+ " (declare (in) vec4 gl_Vertex)\n"
+ " (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 builtin_fwidth[] =
+ "((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 builtin_greaterThan[] =
+ "((function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression bvec2 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression bvec3 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression bvec4 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression bvec2 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression bvec3 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression bvec4 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression bvec2 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression bvec3 > (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression bvec4 > (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_greaterThanEqual[] =
+ "((function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression bvec2 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression bvec3 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression bvec4 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression bvec2 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression bvec3 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression bvec4 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression bvec2 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression bvec3 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression bvec4 >= (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_length[] =
+ "((function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float abs (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 builtin_lessThan[] =
+ "((function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression bvec2 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression bvec3 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression bvec4 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression bvec2 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression bvec3 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression bvec4 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression bvec2 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression bvec3 < (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression bvec4 < (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_lessThanEqual[] =
+ "((function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression bvec2 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression bvec3 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression bvec4 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression bvec2 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression bvec3 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression bvec4 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression bvec2 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression bvec3 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression bvec4 <= (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_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 builtin_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)) (xy) (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)) (xy) (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)) (xyz) (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)) (xyz) (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)) (xyz) (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)) (xyzw) (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)) (xyzw) (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)) (xyzw) (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)) (xyzw) (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"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) mat2x3 x)\n"
+ " (declare (in) mat2x3 y))\n"
+ " ((declare () mat2x3 z)\n"
+ " (assign (constant bool (1)) (xyz) (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)) (xyz) (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)) (xy) (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)) (xy) (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)) (xy) (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)) (xyzw) (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)) (xyzw) (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)) (xy) (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)) (xy) (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)) (xy) (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)) (xy) (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)) (xyzw) (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)) (xyzw) (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)) (xyzw) (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)) (xyz) (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)) (xyz) (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)) (xyz) (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)) (xyz) (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 builtin_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"
+ " ((return (expression vec2 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) float 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) float arg1))\n"
+ " ((return (expression vec4 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\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"
+ " ((return (expression ivec2 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) int 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) int arg1))\n"
+ " ((return (expression ivec4 max (var_ref arg0) (var_ref arg1)))))\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"
+ " ((return (expression uvec2 max (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uint 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) uint arg1))\n"
+ " ((return (expression uvec4 max (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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"
+ " ((return (expression vec2 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) float 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) float arg1))\n"
+ " ((return (expression vec4 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\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"
+ " ((return (expression ivec2 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) int 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) int arg1))\n"
+ " ((return (expression ivec4 min (var_ref arg0) (var_ref arg1)))))\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"
+ " ((return (expression uvec2 min (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature uvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uint 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) uint arg1))\n"
+ " ((return (expression uvec4 min (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 float - (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 float - (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 float - (constant float (1.000000)) (var_ref arg2))) (expression vec4 * (var_ref arg1) (var_ref arg2))))))\n"
+ "\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float v1)\n"
+ " (declare (in) float v2)\n"
+ " (declare (in) bool a))\n"
+ " ((assign (var_ref a) (var_ref v1) (var_ref v2))\n"
+ " (return (var_ref v1))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 v1)\n"
+ " (declare (in) vec2 v2)\n"
+ " (declare (in) bvec2 a))\n"
+ " ((assign (swiz x (var_ref a)) (x) (var_ref v1) (swiz x (var_ref v2)))\n"
+ " (assign (swiz y (var_ref a)) (y) (var_ref v1) (swiz y (var_ref v2)))\n"
+ " (return (var_ref v1))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 v1)\n"
+ " (declare (in) vec3 v2)\n"
+ " (declare (in) bvec3 a))\n"
+ " ((assign (swiz x (var_ref a)) (x) (var_ref v1) (swiz x (var_ref v2)))\n"
+ " (assign (swiz y (var_ref a)) (y) (var_ref v1) (swiz y (var_ref v2)))\n"
+ " (assign (swiz z (var_ref a)) (z) (var_ref v1) (swiz z (var_ref v2)))\n"
+ " (return (var_ref v1))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 v1)\n"
+ " (declare (in) vec4 v2)\n"
+ " (declare (in) bvec4 a))\n"
+ " ((assign (swiz x (var_ref a)) (x) (var_ref v1) (swiz x (var_ref v2)))\n"
+ " (assign (swiz y (var_ref a)) (y) (var_ref v1) (swiz y (var_ref v2)))\n"
+ " (assign (swiz z (var_ref a)) (z) (var_ref v1) (swiz z (var_ref v2)))\n"
+ " (assign (swiz w (var_ref a)) (w) (var_ref v1) (swiz w (var_ref v2)))\n"
+ " (return (var_ref v1))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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"
+ " ((return (expression vec2 % (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) float 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) float arg1))\n"
+ " ((return (expression vec4 % (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_modf[] =
+ "((function modf\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (out) float i))\n"
+ " ((declare () float t)\n"
+ " (assign (constant bool (1)) (x) (var_ref t)\n"
+ " (expression float trunc (var_ref x)))\n"
+ " (assign (constant bool (1)) (x) (var_ref i) (var_ref t))\n"
+ " (return (expression float - (var_ref x) (var_ref t)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (out) vec2 i))\n"
+ " ((declare () vec2 t)\n"
+ " (assign (constant bool (1)) (xy) (var_ref t)\n"
+ " (expression vec2 trunc (var_ref x)))\n"
+ " (assign (constant bool (1)) (xy) (var_ref i) (var_ref t))\n"
+ " (return (expression vec2 - (var_ref x) (var_ref t)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (out) vec3 i))\n"
+ " ((declare () vec3 t)\n"
+ " (assign (constant bool (1)) (xyz) (var_ref t)\n"
+ " (expression vec3 trunc (var_ref x)))\n"
+ " (assign (constant bool (1)) (xyz) (var_ref i) (var_ref t))\n"
+ " (return (expression vec3 - (var_ref x) (var_ref t)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (out) vec4 i))\n"
+ " ((declare () vec4 t)\n"
+ " (assign (constant bool (1)) (xyzw) (var_ref t)\n"
+ " (expression vec4 trunc (var_ref x)))\n"
+ " (assign (constant bool (1)) (xyzw) (var_ref i) (var_ref t))\n"
+ " (return (expression vec4 - (var_ref x) (var_ref t)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_noise1[] =
+ "((function noise1\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ((return (expression float noise (var_ref x)))))\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ((return (expression float noise (var_ref x)))))\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression float noise (var_ref x)))))\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression float noise (var_ref x)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_noise2[] =
+ "((function noise2\n"
+ " (signature vec2\n"
+ " (parameters (declare (in) vec4 p))\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () vec2 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec4 + (var_ref p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters (declare (in) vec3 p))\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () vec2 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec3 + (var_ref p) (constant vec3 (601.0 313.0 29.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in ) vec2 p)\n"
+ " )\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () vec2 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec2 + (var_ref p) (constant vec2 (601.0 313.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in ) float p)\n"
+ " )\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () vec2 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression float + (var_ref p) (constant float (601.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "))\n"
+ ""
+;
+static const char builtin_noise3[] =
+ "((function noise3\n"
+ " (signature vec3\n"
+ " (parameters (declare (in) vec4 p))\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () float c)\n"
+ " (declare () vec3 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec4 + (var_ref p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression vec4 + (var_ref p) (constant vec4 (1559.0 113.0 1861.0 797.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters (declare (in) vec3 p))\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () float c)\n"
+ " (declare () vec3 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec3 + (var_ref p) (constant vec3 (601.0 313.0 29.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression vec3 + (var_ref p) (constant vec3 (1559.0 113.0 1861.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters (declare (in) vec2 p))\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () float c)\n"
+ " (declare () vec3 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression vec2 + (var_ref p) (constant vec2 (601.0 313.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression vec2 + (var_ref p) (constant vec2 (1559.0 113.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters (declare (in) float p))\n"
+ " (\n"
+ " (declare () float a)\n"
+ " (declare () float b)\n"
+ " (declare () float c)\n"
+ " (declare () vec3 t)\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref a) (expression float noise (var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref b) (expression float noise (expression float + (var_ref p) (constant float (601.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref c) (expression float noise (expression float + (var_ref p) (constant float (1559.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref t) (var_ref a))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (var_ref b))\n"
+ " (assign (constant bool (1)) (z) (var_ref t) (var_ref c))\n"
+ " (return (var_ref t))\n"
+ " ))\n"
+ "))\n"
+ ""
+;
+static const char builtin_noise4[] =
+ "((function noise4\n"
+ " (signature vec4\n"
+ " (parameters (declare (in) vec4 p))\n"
+ " (\n"
+ " (declare () float _x)\n"
+ " (declare () float _y)\n"
+ " (declare () float _z)\n"
+ " (declare () float _w)\n"
+ " (declare () vec4 _r)\n"
+ "\n"
+ " (declare () vec4 _p)\n"
+ " (assign (constant bool (1)) (xyzw) (var_ref _p) (expression vec4 + (var_ref p) (constant vec4 (1559.0 113.0 1861.0 797.0))) )\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression vec4 + (var_ref p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression vec4 + (var_ref _p) (constant vec4 (601.0 313.0 29.0 277.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n"
+ " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n"
+ " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n"
+ " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n"
+ " (return (var_ref _r))\n"
+ " ))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters (declare (in) vec3 p))\n"
+ " (\n"
+ " (declare () float _x)\n"
+ " (declare () float _y)\n"
+ " (declare () float _z)\n"
+ " (declare () float _w)\n"
+ " (declare () vec4 _r)\n"
+ "\n"
+ " (declare () vec3 _p)\n"
+ " (assign (constant bool (1)) (xyz) (var_ref _p) (expression vec3 + (var_ref p) (constant vec3 (1559.0 113.0 1861.0))) )\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression vec3 + (var_ref p) (constant vec3 (601.0 313.0 29.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression vec3 + (var_ref _p) (constant vec3 (601.0 313.0 29.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n"
+ " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n"
+ " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n"
+ " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n"
+ " (return (var_ref _r))\n"
+ " ))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters (declare (in) vec2 p))\n"
+ " (\n"
+ " (declare () float _x)\n"
+ " (declare () float _y)\n"
+ " (declare () float _z)\n"
+ " (declare () float _w)\n"
+ " (declare () vec4 _r)\n"
+ "\n"
+ " (declare () vec2 _p)\n"
+ " (assign (constant bool (1)) (xy) (var_ref _p) (expression vec2 + (var_ref p) (constant vec2 (1559.0 113.0))) )\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression vec2 + (var_ref p) (constant vec2 (601.0 313.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression vec2 + (var_ref _p) (constant vec2 (601.0 313.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n"
+ " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n"
+ " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n"
+ " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n"
+ " (return (var_ref _r))\n"
+ " ))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters (declare (in) float p))\n"
+ " (\n"
+ " (declare () float _x)\n"
+ " (declare () float _y)\n"
+ " (declare () float _z)\n"
+ " (declare () float _w)\n"
+ " (declare () vec4 _r)\n"
+ "\n"
+ " (declare () float _p)\n"
+ " (assign (constant bool (1)) (x) (var_ref _p) (expression float + (var_ref p) (constant float (1559.0))) )\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _x) (expression float noise(var_ref p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _y) (expression float noise(expression float + (var_ref p) (constant float (601.0 313.0 29.0 277.0)))))\n"
+ " (assign (constant bool (1)) (x) (var_ref _z) (expression float noise(var_ref _p)))\n"
+ " (assign (constant bool (1)) (x) (var_ref _w) (expression float noise(expression float + (var_ref _p) (constant float (601.0 313.0 29.0 277.0)))))\n"
+ "\n"
+ " (assign (constant bool (1)) (x) (var_ref _r) (var_ref _x))\n"
+ " (assign (constant bool (1)) (y) (var_ref _r) (var_ref _y))\n"
+ " (assign (constant bool (1)) (z) (var_ref _r) (var_ref _z))\n"
+ " (assign (constant bool (1)) (w) (var_ref _r) (var_ref _w))\n"
+ " (return (var_ref _r))\n"
+ " ))\n"
+ "))\n"
+ ""
+;
+static const char builtin_normalize[] =
+ "((function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float sign (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 builtin_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 builtin_notEqual[] =
+ "((function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0)\n"
+ " (declare (in) vec2 arg1))\n"
+ " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0)\n"
+ " (declare (in) vec3 arg1))\n"
+ " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0)\n"
+ " (declare (in) vec4 arg1))\n"
+ " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 arg0)\n"
+ " (declare (in) bvec2 arg1))\n"
+ " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 arg0)\n"
+ " (declare (in) bvec3 arg1))\n"
+ " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 arg0)\n"
+ " (declare (in) bvec4 arg1))\n"
+ " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 arg0)\n"
+ " (declare (in) ivec2 arg1))\n"
+ " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 arg0)\n"
+ " (declare (in) ivec3 arg1))\n"
+ " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 arg0)\n"
+ " (declare (in) ivec4 arg1))\n"
+ " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) uvec2 arg0)\n"
+ " (declare (in) uvec2 arg1))\n"
+ " ((return (expression bvec2 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) uvec3 arg0)\n"
+ " (declare (in) uvec3 arg1))\n"
+ " ((return (expression bvec3 != (var_ref arg0) (var_ref arg1)))))\n"
+ "\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) uvec4 arg0)\n"
+ " (declare (in) uvec4 arg1))\n"
+ " ((return (expression bvec4 != (var_ref arg0) (var_ref arg1)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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)) (xy) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (return (var_ref m))))\n"
+ "\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) vec3 u)\n"
+ " (declare (in) vec2 v))\n"
+ " ((declare () mat2x3 m)\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (return (var_ref m))))\n"
+ "\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) vec4 u)\n"
+ " (declare (in) vec2 v))\n"
+ " ((declare () mat2x4 m)\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (return (var_ref m))))\n"
+ "\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) vec2 u)\n"
+ " (declare (in) vec3 v))\n"
+ " ((declare () mat3x2 m)\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref u) (swiz z (var_ref v))))\n"
+ " (return (var_ref m))\n"
+ " ))\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)) (xyz) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref u) (swiz z (var_ref v))))\n"
+ " (return (var_ref m))))\n"
+ "\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) vec4 u)\n"
+ " (declare (in) vec3 v))\n"
+ " ((declare () mat3x4 m)\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref u) (swiz z (var_ref v))))\n"
+ " (return (var_ref m))))\n"
+ "\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) vec2 u)\n"
+ " (declare (in) vec4 v))\n"
+ " ((declare () mat4x2 m)\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (0))) (expression vec2 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (1))) (expression vec2 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (2))) (expression vec2 * (var_ref u) (swiz z (var_ref v))))\n"
+ " (assign (constant bool (1)) (xy) (array_ref (var_ref m) (constant int (3))) (expression vec2 * (var_ref u) (swiz w (var_ref v))))\n"
+ " (return (var_ref m))))\n"
+ "\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) vec3 u)\n"
+ " (declare (in) vec4 v))\n"
+ " ((declare () mat4x3 m)\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (0))) (expression vec3 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (1))) (expression vec3 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (2))) (expression vec3 * (var_ref u) (swiz z (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyz) (array_ref (var_ref m) (constant int (3))) (expression vec3 * (var_ref u) (swiz w (var_ref v))))\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)) (xyzw) (array_ref (var_ref m) (constant int (0))) (expression vec4 * (var_ref u) (swiz x (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (1))) (expression vec4 * (var_ref u) (swiz y (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (2))) (expression vec4 * (var_ref u) (swiz z (var_ref v))))\n"
+ " (assign (constant bool (1)) (xyzw) (array_ref (var_ref m) (constant int (3))) (expression vec4 * (var_ref u) (swiz w (var_ref v))))\n"
+ " (return (var_ref m))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_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 builtin_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 *\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 builtin_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)) (x) (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 * (var_ref n) (var_ref i))\n"
+ " (expression float * (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 * (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)) (x) (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)) (x) (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 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)) (x) (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 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 builtin_round[] =
+ "((function round\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float round_even (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 round_even (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 round_even (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 round_even (var_ref arg0)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_roundEven[] =
+ "((function roundEven\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float round_even (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 round_even (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 round_even (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 round_even (var_ref arg0)))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_shadow1D[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_shadow1DArray[] =
+ "((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"
+ " (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 builtin_shadow1DArrayLod[] =
+ "((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"
+ ""
+;
+static const char builtin_shadow1DLod[] =
+ "((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"
+ ""
+;
+static const char builtin_shadow1DProj[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_shadow1DProjLod[] =
+ "((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"
+ ""
+;
+static const char builtin_shadow2D[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_shadow2DArray[] =
+ "((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 builtin_shadow2DLod[] =
+ "((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"
+ ""
+;
+static const char builtin_shadow2DProj[] =
+ "((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"
+ " (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 builtin_shadow2DProjLod[] =
+ "((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 builtin_shadow2DRect[] =
+ "((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 builtin_shadow2DRectProj[] =
+ "((function shadow2DRectProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRectShadow 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"
+ ""
+;
+static const char builtin_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"
+ " ((return (expression vec2 sign (var_ref x)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ((return (expression vec3 sign (var_ref x)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ((return (expression vec4 sign (var_ref x)))))\n"
+ "\n"
+ " (signature int\n"
+ " (parameters\n"
+ " (declare (in) int x))\n"
+ " ((return (expression int sign (var_ref x)))))\n"
+ "\n"
+ " (signature ivec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x))\n"
+ " ((return (expression ivec2 sign (var_ref x)))))\n"
+ "\n"
+ " (signature ivec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x))\n"
+ " ((return (expression ivec3 sign (var_ref x)))))\n"
+ "\n"
+ " (signature ivec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x))\n"
+ " ((return (expression ivec4 sign (var_ref x)))))\n"
+ "))\n"
+ "\n"
+ ""
+;
+static const char builtin_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 builtin_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 builtin_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"
+ " (assign (constant bool (1)) (x) (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.0)) (expression float * (constant float (2.0)) (var_ref t))))))))\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"
+ " (assign (constant bool (1)) (xy) (var_ref t)\n"
+ " (expression vec2 max\n"
+ " (expression vec2 min\n"
+ " (expression vec2 / (expression vec2 - (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 vec2 * (var_ref t) (expression vec2 * (var_ref t) (expression vec2 - (constant float (3.0)) (expression vec2 * (constant float (2.0)) (var_ref t))))))))\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"
+ " (assign (constant bool (1)) (xyz) (var_ref t)\n"
+ " (expression vec3 max\n"
+ " (expression vec3 min\n"
+ " (expression vec3 / (expression vec3 - (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 vec3 * (var_ref t) (expression vec3 * (var_ref t) (expression vec3 - (constant float (3.0)) (expression vec3 * (constant float (2.0)) (var_ref t))))))))\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"
+ " (assign (constant bool (1)) (xyzw) (var_ref t)\n"
+ " (expression vec4 max\n"
+ " (expression vec4 min\n"
+ " (expression vec4 / (expression vec4 - (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 vec4 * (var_ref t) (expression vec4 * (var_ref t) (expression vec4 - (constant float (3.0)) (expression vec4 * (constant float (2.0)) (var_ref t))))))))\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"
+ " (assign (constant bool (1)) (xy) (var_ref t)\n"
+ " (expression vec2 max\n"
+ " (expression vec2 min\n"
+ " (expression vec2 / (expression vec2 - (var_ref x) (var_ref edge0)) (expression vec2 - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (return (expression vec2 * (var_ref t) (expression vec2 * (var_ref t) (expression vec2 - (constant float (3.0)) (expression vec2 * (constant float (2.0)) (var_ref t))))))))\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"
+ " (assign (constant bool (1)) (xyz) (var_ref t)\n"
+ " (expression vec3 max\n"
+ " (expression vec3 min\n"
+ " (expression vec3 / (expression vec3 - (var_ref x) (var_ref edge0)) (expression vec3 - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (return (expression vec3 * (var_ref t) (expression vec3 * (var_ref t) (expression vec3 - (constant float (3.0)) (expression vec3 * (constant float (2.0)) (var_ref t))))))))\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"
+ " (assign (constant bool (1)) (xyzw) (var_ref t)\n"
+ " (expression vec4 max\n"
+ " (expression vec4 min\n"
+ " (expression vec4 / (expression vec4 - (var_ref x) (var_ref edge0)) (expression vec4 - (var_ref edge1) (var_ref edge0)))\n"
+ " (constant float (1.0)))\n"
+ " (constant float (0.0))))\n"
+ " (return (expression vec4 * (var_ref t) (expression vec4 * (var_ref t) (expression vec4 - (constant float (3.0)) (expression vec4 * (constant float (2.0)) (var_ref t))))))))\n"
+ "))\n"
+ "\n"
+ ""
+;
+static const char builtin_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 builtin_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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (z) (var_ref t) (expression float b2f (expression bool >= (swiz z (var_ref x))(var_ref edge))))\n"
+ " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (var_ref t) (expression float b2f (expression bool >= (swiz x (var_ref x))(swiz x (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (y) (var_ref t) (expression float b2f (expression bool >= (swiz y (var_ref x))(swiz y (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (z) (var_ref t) (expression float b2f (expression bool >= (swiz z (var_ref x))(swiz z (var_ref edge)))))\n"
+ " (assign (constant bool (1)) (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 builtin_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 vec2 / (expression vec2 sin (var_ref angle)) (expression vec2 cos (var_ref angle))))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ((return (expression vec3 / (expression vec3 sin (var_ref angle)) (expression vec3 cos (var_ref angle))))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ((return (expression vec4 / (expression vec4 sin (var_ref angle)) (expression vec4 cos (var_ref angle))))))\n"
+ "))\n"
+ ""
+;
+static const char builtin_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 builtin_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 builtin_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"
+ " (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 builtin_texture1D[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture1DArray[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture1DArrayLod[] =
+ "((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"
+ ""
+;
+static const char builtin_texture1DLod[] =
+ "((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"
+ ""
+;
+static const char builtin_texture1DProj[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture1DProjLod[] =
+ "((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"
+ ""
+;
+static const char builtin_texture2D[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture2DArray[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture2DArrayLod[] =
+ "((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"
+ ""
+;
+static const char builtin_texture2DLod[] =
+ "((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"
+ ""
+;
+static const char builtin_texture2DProj[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture2DProjLod[] =
+ "((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"
+ ""
+;
+static const char builtin_texture2DRect[] =
+ "((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"
+ ""
+;
+static const char builtin_texture2DRectProj[] =
+ "((function texture2DRectProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect 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) sampler2DRect 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"
+ ""
+;
+static const char builtin_texture3D[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture3DLod[] =
+ "((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"
+ ""
+;
+static const char builtin_texture3DProj[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_texture3DProjLod[] =
+ "((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"
+ ""
+;
+static const char builtin_textureCube[] =
+ "((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"
+ " (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"
+ ""
+;
+static const char builtin_textureCubeLod[] =
+ "((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"
+ ""
+;
+static const char builtin_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"
+ ""
+;
+static const char builtin_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 builtin_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"
+ " (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 builtin_textureProjGrad[] =
+ "((function textureProjGrad\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 builtin_textureProjLod[] =
+ "((function textureProjLod\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 builtin_transpose[] =
+ "((function transpose\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 m))\n"
+ " ((declare () mat2 t)\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (3)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (3)))))\n"
+ " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (3)))))\n"
+ " (assign (constant bool (1)) (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)) (x) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (x) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (0)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (y) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (1)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (z) (array_ref (var_ref t) (constant int (3))) (swiz w (array_ref (var_ref m) (constant int (2)))))\n"
+ " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (0))) (swiz x (array_ref (var_ref m) (constant int (3)))))\n"
+ " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (1))) (swiz y (array_ref (var_ref m) (constant int (3)))))\n"
+ " (assign (constant bool (1)) (w) (array_ref (var_ref t) (constant int (2))) (swiz z (array_ref (var_ref m) (constant int (3)))))\n"
+ " (assign (constant bool (1)) (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 builtin_trunc[] =
+ "((function trunc\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float arg0))\n"
+ " ((return (expression float trunc (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 arg0))\n"
+ " ((return (expression vec2 trunc (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 arg0))\n"
+ " ((return (expression vec3 trunc (var_ref arg0)))))\n"
+ "\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 arg0))\n"
+ " ((return (expression vec4 trunc (var_ref arg0)))))\n"
+ "))\n"
+ ""
+;
+static const char prototypes_for_100_frag[] =
+ "(\n"
+ "(function radians\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float degrees))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 degrees))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 degrees))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 degrees))\n"
+ " ()))\n"
+ "(function degrees\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float radians))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 radians))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 radians))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 radians))\n"
+ " ()))\n"
+ "(function sin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function cos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function tan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function acos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y_over_x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y_over_x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y_over_x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y_over_x))\n"
+ " ()))\n"
+ "(function pow\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function exp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function exp2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function inversesqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function abs\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sign\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function floor\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ceil\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function mod\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function min\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function max\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function clamp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 minVal)\n"
+ " (declare (in) vec2 maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 minVal)\n"
+ " (declare (in) vec3 maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 minVal)\n"
+ " (declare (in) vec4 maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ()))\n"
+ "(function mix\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) float a))\n"
+ " ()))\n"
+ "(function step\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function smoothstep\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge0)\n"
+ " (declare (in) vec2 edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge0)\n"
+ " (declare (in) vec3 edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge0)\n"
+ " (declare (in) vec4 edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 p0)\n"
+ " (declare (in) vec2 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 p0)\n"
+ " (declare (in) vec3 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 p0)\n"
+ " (declare (in) vec4 p1))\n"
+ " ()))\n"
+ "(function dot\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ()))\n"
+ "(function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function faceforward\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float Nref))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 Nref))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 Nref))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 Nref))\n"
+ " ()))\n"
+ "(function reflect\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N))\n"
+ " ()))\n"
+ "(function refract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) float eta))\n"
+ " ()))\n"
+ "(function matrixCompMult\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 x)\n"
+ " (declare (in) mat2 y))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 x)\n"
+ " (declare (in) mat3 y))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 x)\n"
+ " (declare (in) mat4 y))\n"
+ " ()))\n"
+ "(function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function all\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function not\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ())))"
+;
+static const char *functions_for_100_frag [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_atan,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cross,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_sign,
+ builtin_sin,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_texture2D,
+ builtin_texture2DProj,
+ builtin_textureCube,
+};
+static const char prototypes_for_100_vert[] =
+ "(\n"
+ "(function radians\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float degrees))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 degrees))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 degrees))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 degrees))\n"
+ " ()))\n"
+ "(function degrees\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float radians))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 radians))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 radians))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 radians))\n"
+ " ()))\n"
+ "(function sin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function cos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function tan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function acos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y_over_x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y_over_x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y_over_x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y_over_x))\n"
+ " ()))\n"
+ "(function pow\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function exp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function exp2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function inversesqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function abs\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sign\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function floor\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ceil\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function mod\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function min\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function max\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function clamp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 minVal)\n"
+ " (declare (in) vec2 maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 minVal)\n"
+ " (declare (in) vec3 maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 minVal)\n"
+ " (declare (in) vec4 maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ()))\n"
+ "(function mix\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) float a))\n"
+ " ()))\n"
+ "(function step\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function smoothstep\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge0)\n"
+ " (declare (in) vec2 edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge0)\n"
+ " (declare (in) vec3 edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge0)\n"
+ " (declare (in) vec4 edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 p0)\n"
+ " (declare (in) vec2 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 p0)\n"
+ " (declare (in) vec3 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 p0)\n"
+ " (declare (in) vec4 p1))\n"
+ " ()))\n"
+ "(function dot\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ()))\n"
+ "(function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function faceforward\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float Nref))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 Nref))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 Nref))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 Nref))\n"
+ " ()))\n"
+ "(function reflect\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N))\n"
+ " ()))\n"
+ "(function refract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) float eta))\n"
+ " ()))\n"
+ "(function matrixCompMult\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 x)\n"
+ " (declare (in) mat2 y))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 x)\n"
+ " (declare (in) mat3 y))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 x)\n"
+ " (declare (in) mat4 y))\n"
+ " ()))\n"
+ "(function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function all\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function not\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ()))\n"
+ "(function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function texture2DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture2DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function textureCubeLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ())))"
+;
+static const char *functions_for_100_vert [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_atan,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cross,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_sign,
+ builtin_sin,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_texture2D,
+ builtin_texture2DLod,
+ builtin_texture2DProj,
+ builtin_texture2DProjLod,
+ builtin_textureCube,
+ builtin_textureCubeLod,
+};
+static const char prototypes_for_110_frag[] =
+ "(\n"
+ "(function radians\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float degrees))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 degrees))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 degrees))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 degrees))\n"
+ " ()))\n"
+ "(function degrees\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float radians))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 radians))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 radians))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 radians))\n"
+ " ()))\n"
+ "(function sin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function cos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function tan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function acos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y_over_x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y_over_x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y_over_x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y_over_x))\n"
+ " ()))\n"
+ "(function pow\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function exp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function exp2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function inversesqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function abs\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sign\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function floor\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ceil\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function mod\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function min\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function max\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function clamp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 minVal)\n"
+ " (declare (in) vec2 maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 minVal)\n"
+ " (declare (in) vec3 maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 minVal)\n"
+ " (declare (in) vec4 maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ()))\n"
+ "(function mix\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) float a))\n"
+ " ()))\n"
+ "(function step\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function smoothstep\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge0)\n"
+ " (declare (in) vec2 edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge0)\n"
+ " (declare (in) vec3 edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge0)\n"
+ " (declare (in) vec4 edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 p0)\n"
+ " (declare (in) vec2 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 p0)\n"
+ " (declare (in) vec3 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 p0)\n"
+ " (declare (in) vec4 p1))\n"
+ " ()))\n"
+ "(function dot\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ()))\n"
+ "(function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function faceforward\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float Nref))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 Nref))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 Nref))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 Nref))\n"
+ " ()))\n"
+ "(function reflect\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N))\n"
+ " ()))\n"
+ "(function refract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) float eta))\n"
+ " ()))\n"
+ "(function matrixCompMult\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 x)\n"
+ " (declare (in) mat2 y))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 x)\n"
+ " (declare (in) mat3 y))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 x)\n"
+ " (declare (in) mat4 y))\n"
+ " ()))\n"
+ "(function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function all\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function not\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function texture1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float bias))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture3D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture3DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function dFdx\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ()))\n"
+ "(function dFdy\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ()))\n"
+ "(function fwidth\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ()))\n"
+ "(function noise1\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise2\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise3\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise4\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ())))"
+;
+static const char *functions_for_110_frag [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_atan,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cross,
+ builtin_dFdx,
+ builtin_dFdy,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_fwidth,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_noise1,
+ builtin_noise2,
+ builtin_noise3,
+ builtin_noise4,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_shadow1D,
+ builtin_shadow1DProj,
+ builtin_shadow2D,
+ builtin_shadow2DProj,
+ builtin_sign,
+ builtin_sin,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_texture1D,
+ builtin_texture1DProj,
+ builtin_texture2D,
+ builtin_texture2DProj,
+ builtin_texture3D,
+ builtin_texture3DProj,
+ builtin_textureCube,
+};
+static const char prototypes_for_110_vert[] =
+ "(\n"
+ "(function radians\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float degrees))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 degrees))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 degrees))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 degrees))\n"
+ " ()))\n"
+ "(function degrees\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float radians))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 radians))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 radians))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 radians))\n"
+ " ()))\n"
+ "(function sin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function cos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function tan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function acos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y_over_x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y_over_x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y_over_x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y_over_x))\n"
+ " ()))\n"
+ "(function pow\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function exp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function exp2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function inversesqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function abs\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sign\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function floor\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ceil\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function mod\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function min\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function max\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function clamp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 minVal)\n"
+ " (declare (in) vec2 maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 minVal)\n"
+ " (declare (in) vec3 maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 minVal)\n"
+ " (declare (in) vec4 maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ()))\n"
+ "(function mix\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) float a))\n"
+ " ()))\n"
+ "(function step\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function smoothstep\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge0)\n"
+ " (declare (in) vec2 edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge0)\n"
+ " (declare (in) vec3 edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge0)\n"
+ " (declare (in) vec4 edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 p0)\n"
+ " (declare (in) vec2 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 p0)\n"
+ " (declare (in) vec3 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 p0)\n"
+ " (declare (in) vec4 p1))\n"
+ " ()))\n"
+ "(function dot\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ()))\n"
+ "(function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ftransform\n"
+ " (signature vec4\n"
+ " (parameters)\n"
+ " ()))\n"
+ "(function faceforward\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float Nref))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 Nref))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 Nref))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 Nref))\n"
+ " ()))\n"
+ "(function reflect\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N))\n"
+ " ()))\n"
+ "(function refract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) float eta))\n"
+ " ()))\n"
+ "(function matrixCompMult\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 x)\n"
+ " (declare (in) mat2 y))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 x)\n"
+ " (declare (in) mat3 y))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 x)\n"
+ " (declare (in) mat4 y))\n"
+ " ()))\n"
+ "(function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function all\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function not\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function texture1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord))\n"
+ " ()))\n"
+ "(function texture1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function texture1DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture1DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float lod))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ()))\n"
+ "(function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function texture2DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture2DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture3D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function texture3DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function texture3DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture3DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function textureCubeLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function shadow2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function shadow1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function shadow2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function shadow1DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow2DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow1DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow2DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function noise1\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise2\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise3\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise4\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ())))"
+;
+static const char *functions_for_110_vert [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_atan,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cross,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_ftransform,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_noise1,
+ builtin_noise2,
+ builtin_noise3,
+ builtin_noise4,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_shadow1D,
+ builtin_shadow1DLod,
+ builtin_shadow1DProj,
+ builtin_shadow1DProjLod,
+ builtin_shadow2D,
+ builtin_shadow2DLod,
+ builtin_shadow2DProj,
+ builtin_shadow2DProjLod,
+ builtin_sign,
+ builtin_sin,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_texture1D,
+ builtin_texture1DLod,
+ builtin_texture1DProj,
+ builtin_texture1DProjLod,
+ builtin_texture2D,
+ builtin_texture2DLod,
+ builtin_texture2DProj,
+ builtin_texture2DProjLod,
+ builtin_texture3D,
+ builtin_texture3DLod,
+ builtin_texture3DProj,
+ builtin_texture3DProjLod,
+ builtin_textureCube,
+ builtin_textureCubeLod,
+};
+static const char prototypes_for_120_frag[] =
+ "(\n"
+ "(function radians\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float degrees))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 degrees))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 degrees))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 degrees))\n"
+ " ()))\n"
+ "(function degrees\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float radians))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 radians))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 radians))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 radians))\n"
+ " ()))\n"
+ "(function sin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function cos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function tan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function acos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y_over_x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y_over_x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y_over_x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y_over_x))\n"
+ " ()))\n"
+ "(function pow\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function exp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function exp2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function inversesqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function abs\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sign\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function floor\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ceil\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function mod\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function min\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function max\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function clamp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 minVal)\n"
+ " (declare (in) vec2 maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 minVal)\n"
+ " (declare (in) vec3 maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 minVal)\n"
+ " (declare (in) vec4 maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ()))\n"
+ "(function mix\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) float a))\n"
+ " ()))\n"
+ "(function step\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function smoothstep\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge0)\n"
+ " (declare (in) vec2 edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge0)\n"
+ " (declare (in) vec3 edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge0)\n"
+ " (declare (in) vec4 edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 p0)\n"
+ " (declare (in) vec2 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 p0)\n"
+ " (declare (in) vec3 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 p0)\n"
+ " (declare (in) vec4 p1))\n"
+ " ()))\n"
+ "(function dot\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ()))\n"
+ "(function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function faceforward\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float Nref))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 Nref))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 Nref))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 Nref))\n"
+ " ()))\n"
+ "(function reflect\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N))\n"
+ " ()))\n"
+ "(function refract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) float eta))\n"
+ " ()))\n"
+ "(function matrixCompMult\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 x)\n"
+ " (declare (in) mat2 y))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 x)\n"
+ " (declare (in) mat3 y))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 x)\n"
+ " (declare (in) mat4 y))\n"
+ " ())\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) mat2x3 x)\n"
+ " (declare (in) mat2x3 y))\n"
+ " ())\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) mat2x4 x)\n"
+ " (declare (in) mat2x4 y))\n"
+ " ())\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) mat3x2 x)\n"
+ " (declare (in) mat3x2 y))\n"
+ " ())\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) mat3x4 x)\n"
+ " (declare (in) mat3x4 y))\n"
+ " ())\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) mat4x2 x)\n"
+ " (declare (in) mat4x2 y))\n"
+ " ())\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) mat4x3 x)\n"
+ " (declare (in) mat4x3 y))\n"
+ " ()))\n"
+ "(function outerProduct\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) vec2 c)\n"
+ " (declare (in) vec2 r))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) vec3 c)\n"
+ " (declare (in) vec3 r))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) vec4 c)\n"
+ " (declare (in) vec4 r))\n"
+ " ())\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) vec3 c)\n"
+ " (declare (in) vec2 r))\n"
+ " ())\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) vec2 c)\n"
+ " (declare (in) vec3 r))\n"
+ " ())\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) vec4 c)\n"
+ " (declare (in) vec2 r))\n"
+ " ())\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) vec2 c)\n"
+ " (declare (in) vec4 r))\n"
+ " ())\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) vec4 c)\n"
+ " (declare (in) vec3 r))\n"
+ " ())\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) vec3 c)\n"
+ " (declare (in) vec4 r))\n"
+ " ()))\n"
+ "(function transpose\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 m))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 m))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 m))\n"
+ " ())\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) mat3x2 m))\n"
+ " ())\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) mat2x3 m))\n"
+ " ())\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) mat4x2 m))\n"
+ " ())\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) mat2x4 m))\n"
+ " ())\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) mat4x3 m))\n"
+ " ())\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) mat3x4 m))\n"
+ " ()))\n"
+ "(function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function all\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function not\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function texture1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float bias))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture3D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture3DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function dFdx\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ()))\n"
+ "(function dFdy\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ()))\n"
+ "(function fwidth\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 p))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 p))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 p))\n"
+ " ()))\n"
+ "(function noise1\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise2\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise3\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise4\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ())))"
+;
+static const char *functions_for_120_frag [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_atan,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cross,
+ builtin_dFdx,
+ builtin_dFdy,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_fwidth,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_noise1,
+ builtin_noise2,
+ builtin_noise3,
+ builtin_noise4,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_outerProduct,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_shadow1D,
+ builtin_shadow1DProj,
+ builtin_shadow2D,
+ builtin_shadow2DProj,
+ builtin_sign,
+ builtin_sin,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_texture1D,
+ builtin_texture1DProj,
+ builtin_texture2D,
+ builtin_texture2DProj,
+ builtin_texture3D,
+ builtin_texture3DProj,
+ builtin_textureCube,
+ builtin_transpose,
+};
+static const char prototypes_for_120_vert[] =
+ "(\n"
+ "(function radians\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float degrees))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 degrees))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 degrees))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 degrees))\n"
+ " ()))\n"
+ "(function degrees\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float radians))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 radians))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 radians))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 radians))\n"
+ " ()))\n"
+ "(function sin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function cos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function tan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function asin\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function acos\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float angle))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 angle))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 angle))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 angle))\n"
+ " ()))\n"
+ "(function atan\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float y_over_x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 y_over_x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 y_over_x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 y_over_x))\n"
+ " ()))\n"
+ "(function pow\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function exp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function exp2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function log2\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function inversesqrt\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function abs\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function sign\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function floor\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ceil\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function fract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function mod\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function min\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function max\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float y))\n"
+ " ()))\n"
+ "(function clamp\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 minVal)\n"
+ " (declare (in) vec2 maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 minVal)\n"
+ " (declare (in) vec3 maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 minVal)\n"
+ " (declare (in) vec4 maxVal))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) float minVal)\n"
+ " (declare (in) float maxVal))\n"
+ " ()))\n"
+ "(function mix\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) vec2 a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) vec3 a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) vec4 a))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y)\n"
+ " (declare (in) float a))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y)\n"
+ " (declare (in) float a))\n"
+ " ()))\n"
+ "(function step\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function smoothstep\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 edge0)\n"
+ " (declare (in) vec2 edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 edge0)\n"
+ " (declare (in) vec3 edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 edge0)\n"
+ " (declare (in) vec4 edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float edge0)\n"
+ " (declare (in) float edge1)\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function length\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function distance\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float p0)\n"
+ " (declare (in) float p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 p0)\n"
+ " (declare (in) vec2 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 p0)\n"
+ " (declare (in) vec3 p1))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 p0)\n"
+ " (declare (in) vec4 p1))\n"
+ " ()))\n"
+ "(function dot\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x)\n"
+ " (declare (in) float y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ()))\n"
+ "(function cross\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ()))\n"
+ "(function normalize\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function ftransform\n"
+ " (signature vec4\n"
+ " (parameters)\n"
+ " ()))\n"
+ "(function faceforward\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float Nref))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 Nref))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 Nref))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 Nref))\n"
+ " ()))\n"
+ "(function reflect\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N))\n"
+ " ()))\n"
+ "(function refract\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float I)\n"
+ " (declare (in) float N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 I)\n"
+ " (declare (in) vec2 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 I)\n"
+ " (declare (in) vec3 N)\n"
+ " (declare (in) float eta))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 I)\n"
+ " (declare (in) vec4 N)\n"
+ " (declare (in) float eta))\n"
+ " ()))\n"
+ "(function matrixCompMult\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 x)\n"
+ " (declare (in) mat2 y))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 x)\n"
+ " (declare (in) mat3 y))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 x)\n"
+ " (declare (in) mat4 y))\n"
+ " ())\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) mat2x3 x)\n"
+ " (declare (in) mat2x3 y))\n"
+ " ())\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) mat2x4 x)\n"
+ " (declare (in) mat2x4 y))\n"
+ " ())\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) mat3x2 x)\n"
+ " (declare (in) mat3x2 y))\n"
+ " ())\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) mat3x4 x)\n"
+ " (declare (in) mat3x4 y))\n"
+ " ())\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) mat4x2 x)\n"
+ " (declare (in) mat4x2 y))\n"
+ " ())\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) mat4x3 x)\n"
+ " (declare (in) mat4x3 y))\n"
+ " ()))\n"
+ "(function outerProduct\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) vec2 c)\n"
+ " (declare (in) vec2 r))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) vec3 c)\n"
+ " (declare (in) vec3 r))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) vec4 c)\n"
+ " (declare (in) vec4 r))\n"
+ " ())\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) vec3 c)\n"
+ " (declare (in) vec2 r))\n"
+ " ())\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) vec2 c)\n"
+ " (declare (in) vec3 r))\n"
+ " ())\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) vec4 c)\n"
+ " (declare (in) vec2 r))\n"
+ " ())\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) vec2 c)\n"
+ " (declare (in) vec4 r))\n"
+ " ())\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) vec4 c)\n"
+ " (declare (in) vec3 r))\n"
+ " ())\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) vec3 c)\n"
+ " (declare (in) vec4 r))\n"
+ " ()))\n"
+ "(function transpose\n"
+ " (signature mat2\n"
+ " (parameters\n"
+ " (declare (in) mat2 m))\n"
+ " ())\n"
+ " (signature mat3\n"
+ " (parameters\n"
+ " (declare (in) mat3 m))\n"
+ " ())\n"
+ " (signature mat4\n"
+ " (parameters\n"
+ " (declare (in) mat4 m))\n"
+ " ())\n"
+ " (signature mat2x3\n"
+ " (parameters\n"
+ " (declare (in) mat3x2 m))\n"
+ " ())\n"
+ " (signature mat3x2\n"
+ " (parameters\n"
+ " (declare (in) mat2x3 m))\n"
+ " ())\n"
+ " (signature mat2x4\n"
+ " (parameters\n"
+ " (declare (in) mat4x2 m))\n"
+ " ())\n"
+ " (signature mat4x2\n"
+ " (parameters\n"
+ " (declare (in) mat2x4 m))\n"
+ " ())\n"
+ " (signature mat3x4\n"
+ " (parameters\n"
+ " (declare (in) mat4x3 m))\n"
+ " ())\n"
+ " (signature mat4x3\n"
+ " (parameters\n"
+ " (declare (in) mat3x4 m))\n"
+ " ()))\n"
+ "(function lessThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function lessThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThan\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function greaterThanEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ()))\n"
+ "(function equal\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function notEqual\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x)\n"
+ " (declare (in) vec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x)\n"
+ " (declare (in) vec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x)\n"
+ " (declare (in) vec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) ivec2 x)\n"
+ " (declare (in) ivec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) ivec3 x)\n"
+ " (declare (in) ivec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) ivec4 x)\n"
+ " (declare (in) ivec4 y))\n"
+ " ())\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x)\n"
+ " (declare (in) bvec2 y))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x)\n"
+ " (declare (in) bvec3 y))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x)\n"
+ " (declare (in) bvec4 y))\n"
+ " ()))\n"
+ "(function any\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function all\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bool\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function not\n"
+ " (signature bvec2\n"
+ " (parameters\n"
+ " (declare (in) bvec2 x))\n"
+ " ())\n"
+ " (signature bvec3\n"
+ " (parameters\n"
+ " (declare (in) bvec3 x))\n"
+ " ())\n"
+ " (signature bvec4\n"
+ " (parameters\n"
+ " (declare (in) bvec4 x))\n"
+ " ()))\n"
+ "(function texture1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord))\n"
+ " ()))\n"
+ "(function texture1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function texture1DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) float coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture1DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float lod))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ()))\n"
+ "(function texture2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function texture2DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture2DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture3D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function texture3DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function texture3DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture3DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler3D sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function textureCube\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function textureCubeLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) samplerCube sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow1D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function shadow2D\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function shadow1DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function shadow2DProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function shadow1DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow2DLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow1DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow2DProjLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DShadow sampler)\n"
+ " (declare (in) vec4 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function noise1\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature float\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise2\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec2\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise3\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec3\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ()))\n"
+ "(function noise4\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) float x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec2 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec3 x))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) vec4 x))\n"
+ " ())))"
+;
+static const char *functions_for_120_vert [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_atan,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cross,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_ftransform,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_noise1,
+ builtin_noise2,
+ builtin_noise3,
+ builtin_noise4,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_outerProduct,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_shadow1D,
+ builtin_shadow1DLod,
+ builtin_shadow1DProj,
+ builtin_shadow1DProjLod,
+ builtin_shadow2D,
+ builtin_shadow2DLod,
+ builtin_shadow2DProj,
+ builtin_shadow2DProjLod,
+ builtin_sign,
+ builtin_sin,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_texture1D,
+ builtin_texture1DLod,
+ builtin_texture1DProj,
+ builtin_texture1DProjLod,
+ builtin_texture2D,
+ builtin_texture2DLod,
+ builtin_texture2DProj,
+ builtin_texture2DProjLod,
+ builtin_texture3D,
+ builtin_texture3DLod,
+ builtin_texture3DProj,
+ builtin_texture3DProjLod,
+ builtin_textureCube,
+ builtin_textureCubeLod,
+ builtin_transpose,
+};
+static const char prototypes_for_130_frag[] =
+{'(',
+'(','f','u','n','c','t','i','o','n',' ','r','a','d','i','a','n','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','e','g','r','e','e','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','i','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','o','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','s','i','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','c','o','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','t','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','i','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','o','s','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','a','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','s','i','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','c','o','s','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','t','a','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','p','o','w',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','e','x','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','o','g',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','e','x','p','2',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','o','g','2',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','q','r','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','i','n','v','e','r','s','e','s','q','r','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','b','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','i','g','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','l','o','o','r',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','r','u','n','c',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','o','u','n','d',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','o','u','n','d','E','v','e','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','e','i','l',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','r','a','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','o','d','f',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','f','l','o','a','t',' ','i',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','v','e','c','2',' ','i',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','v','e','c','3',' ','i',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','v','e','c','4',' ','i',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','i','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','a','x',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','l','a','m','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','i','x',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','t','e','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','m','o','o','t','h','s','t','e','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','e','n','g','t','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','i','s','t','a','n','c','e',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','p','1',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','p','1',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','p','1',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','p','1',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','o','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','r','o','s','s',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','r','m','a','l','i','z','e',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','a','c','e','f','o','r','w','a','r','d',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N','r','e','f',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N','r','e','f',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N','r','e','f',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N','r','e','f',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','e','f','l','e','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','e','f','r','a','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','a','t','r','i','x','C','o','m','p','M','u','l','t',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','3',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','o','u','t','e','r','P','r','o','d','u','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','r','a','n','s','p','o','s','e',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','2',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','3',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','2',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','4',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','3',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','4',' ','m',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','e','s','s','T','h','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','e','s','s','T','h','a','n','E','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','g','r','e','a','t','e','r','T','h','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','g','r','e','a','t','e','r','T','h','a','n','E','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','e','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','t','E','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','n','y',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','l','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','t',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','e','l','F','e','t','c','h',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','G','r','a','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','P','r','o','j','G','r','a','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','C','u','b','e',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','C','u','b','e','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','F','d','x',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','p',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','F','d','y',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','p',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','w','i','d','t','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','p',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','p',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','1',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','2',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','3',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','4',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',')'} ;
+static const char *functions_for_130_frag [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_acosh,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_asinh,
+ builtin_atan,
+ builtin_atanh,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cosh,
+ builtin_cross,
+ builtin_dFdx,
+ builtin_dFdy,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_fwidth,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_modf,
+ builtin_noise1,
+ builtin_noise2,
+ builtin_noise3,
+ builtin_noise4,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_outerProduct,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_round,
+ builtin_roundEven,
+ builtin_shadow1D,
+ builtin_shadow1DLod,
+ builtin_shadow1DProj,
+ builtin_shadow1DProjLod,
+ builtin_shadow2D,
+ builtin_shadow2DLod,
+ builtin_shadow2DProj,
+ builtin_shadow2DProjLod,
+ builtin_sign,
+ builtin_sin,
+ builtin_sinh,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_tanh,
+ builtin_texelFetch,
+ builtin_texture,
+ builtin_texture1D,
+ builtin_texture1DLod,
+ builtin_texture1DProj,
+ builtin_texture1DProjLod,
+ builtin_texture2D,
+ builtin_texture2DLod,
+ builtin_texture2DProj,
+ builtin_texture2DProjLod,
+ builtin_texture3D,
+ builtin_texture3DLod,
+ builtin_texture3DProj,
+ builtin_texture3DProjLod,
+ builtin_textureCube,
+ builtin_textureCubeLod,
+ builtin_textureGrad,
+ builtin_textureLod,
+ builtin_textureProj,
+ builtin_textureProjGrad,
+ builtin_textureProjLod,
+ builtin_transpose,
+ builtin_trunc,
+};
+static const char prototypes_for_130_vert[] =
+{'(',
+'(','f','u','n','c','t','i','o','n',' ','r','a','d','i','a','n','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','d','e','g','r','e','e','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','e','g','r','e','e','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r','a','d','i','a','n','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','i','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','o','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','s','i','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','c','o','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a','n','g','l','e',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a','n','g','l','e',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','t','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y','_','o','v','e','r','_','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','i','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','o','s','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','a','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','s','i','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','c','o','s','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','t','a','n','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','p','o','w',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','e','x','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','o','g',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','e','x','p','2',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','o','g','2',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','q','r','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','i','n','v','e','r','s','e','s','q','r','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','b','s',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','i','g','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','l','o','o','r',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','r','u','n','c',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','o','u','n','d',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','o','u','n','d','E','v','e','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','e','i','l',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','r','a','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','o','d','f',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','f','l','o','a','t',' ','i',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','v','e','c','2',' ','i',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','v','e','c','3',' ','i',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','o','u','t',')',' ','v','e','c','4',' ','i',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','i','n',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','a','x',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','l','a','m','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','i','n','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','i','n','V','a','l',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','i','n','t',' ','m','a','x','V','a','l',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','i','x',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','a',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','t','e','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','m','o','o','t','h','s','t','e','p',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','d','g','e','1',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','e','n','g','t','h',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','i','s','t','a','n','c','e',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','p','1',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','p','1',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','p','1',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','p','0',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','p','1',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','d','o','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','c','r','o','s','s',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','r','m','a','l','i','z','e',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','t','r','a','n','s','f','o','r','m',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','f','a','c','e','f','o','r','w','a','r','d',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N','r','e','f',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N','r','e','f',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N','r','e','f',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N','r','e','f',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','e','f','l','e','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','r','e','f','r','a','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','I',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','N',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','e','t','a',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','m','a','t','r','i','x','C','o','m','p','M','u','l','t',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','3',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','o','u','t','e','r','P','r','o','d','u','c','t',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','r',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','r',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','r','a','n','s','p','o','s','e',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','2',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','3',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','2','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','2',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','2','x','4',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','3','x','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','4','x','3',' ','m',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','m','a','t','4','x','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','m','a','t','3','x','4',' ','m',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','e','s','s','T','h','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','l','e','s','s','T','h','a','n','E','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','g','r','e','a','t','e','r','T','h','a','n',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','g','r','e','a','t','e','r','T','h','a','n','E','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','e','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','t','E','q','u','a','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','v','e','c','4',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','n','y',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','a','l','l',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','o','o','l',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','t',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','b','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','b','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','e','l','F','e','t','c','h',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','n','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','G','r','a','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D','A','r','r','a','y',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','A','r','r','a','y','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','P','r','o','j','G','r','a','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','i','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','i','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','u','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','u','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','d','P','d','y',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','P',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','x',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','d','P','d','y',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','1','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','2','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','3','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','3','D',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','C','u','b','e',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','t','e','x','t','u','r','e','C','u','b','e','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','C','u','b','e',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D','P','r','o','j',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','b','i','a','s',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','1','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','1','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','s','h','a','d','o','w','2','D','P','r','o','j','L','o','d',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','s','a','m','p','l','e','r','2','D','S','h','a','d','o','w',' ','s','a','m','p','l','e','r',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','c','o','o','r','d',')',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','l','o','d',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','1',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','f','l','o','a','t',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','2',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','2',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','3',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','3',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',
+'(','f','u','n','c','t','i','o','n',' ','n','o','i','s','e','4',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','f','l','o','a','t',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','2',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','3',' ','x',')',')',' ','(',')',')',' ','(','s','i','g','n','a','t','u','r','e',' ','v','e','c','4',' ','(','p','a','r','a','m','e','t','e','r','s',' ','(','d','e','c','l','a','r','e',' ','(','i','n',')',' ','v','e','c','4',' ','x',')',')',' ','(',')',')',')',')'} ;
+static const char *functions_for_130_vert [] = {
+ builtin_abs,
+ builtin_acos,
+ builtin_acosh,
+ builtin_all,
+ builtin_any,
+ builtin_asin,
+ builtin_asinh,
+ builtin_atan,
+ builtin_atanh,
+ builtin_ceil,
+ builtin_clamp,
+ builtin_cos,
+ builtin_cosh,
+ builtin_cross,
+ builtin_degrees,
+ builtin_distance,
+ builtin_dot,
+ builtin_equal,
+ builtin_exp,
+ builtin_exp2,
+ builtin_faceforward,
+ builtin_floor,
+ builtin_fract,
+ builtin_ftransform,
+ builtin_greaterThan,
+ builtin_greaterThanEqual,
+ builtin_inversesqrt,
+ builtin_length,
+ builtin_lessThan,
+ builtin_lessThanEqual,
+ builtin_log,
+ builtin_log2,
+ builtin_matrixCompMult,
+ builtin_max,
+ builtin_min,
+ builtin_mix,
+ builtin_mod,
+ builtin_modf,
+ builtin_noise1,
+ builtin_noise2,
+ builtin_noise3,
+ builtin_noise4,
+ builtin_normalize,
+ builtin_not,
+ builtin_notEqual,
+ builtin_outerProduct,
+ builtin_pow,
+ builtin_radians,
+ builtin_reflect,
+ builtin_refract,
+ builtin_round,
+ builtin_roundEven,
+ builtin_shadow1D,
+ builtin_shadow1DLod,
+ builtin_shadow1DProj,
+ builtin_shadow1DProjLod,
+ builtin_shadow2D,
+ builtin_shadow2DLod,
+ builtin_shadow2DProj,
+ builtin_shadow2DProjLod,
+ builtin_sign,
+ builtin_sin,
+ builtin_sinh,
+ builtin_smoothstep,
+ builtin_sqrt,
+ builtin_step,
+ builtin_tan,
+ builtin_tanh,
+ builtin_texelFetch,
+ builtin_texture,
+ builtin_texture1D,
+ builtin_texture1DLod,
+ builtin_texture1DProj,
+ builtin_texture1DProjLod,
+ builtin_texture2D,
+ builtin_texture2DLod,
+ builtin_texture2DProj,
+ builtin_texture2DProjLod,
+ builtin_texture3D,
+ builtin_texture3DLod,
+ builtin_texture3DProj,
+ builtin_texture3DProjLod,
+ builtin_textureCube,
+ builtin_textureCubeLod,
+ builtin_textureGrad,
+ builtin_textureLod,
+ builtin_textureProj,
+ builtin_textureProjGrad,
+ builtin_textureProjLod,
+ builtin_transpose,
+ builtin_trunc,
+};
+static const char prototypes_for_ARB_texture_rectangle_frag[] =
+ "(\n"
+ "(function texture2DRect\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ()))\n"
+ "(function texture2DRectProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function shadow2DRect\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRectShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function shadow2DRectProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRectShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())))"
+;
+static const char *functions_for_ARB_texture_rectangle_frag [] = {
+ builtin_shadow2DRect,
+ builtin_shadow2DRectProj,
+ builtin_texture2DRect,
+ builtin_texture2DRectProj,
+};
+static const char prototypes_for_ARB_texture_rectangle_vert[] =
+ "(\n"
+ "(function texture2DRect\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ()))\n"
+ "(function texture2DRectProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRect sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ()))\n"
+ "(function shadow2DRect\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRectShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function shadow2DRectProj\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DRectShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())))"
+;
+static const char *functions_for_ARB_texture_rectangle_vert [] = {
+ builtin_shadow2DRect,
+ builtin_shadow2DRectProj,
+ builtin_texture2DRect,
+ builtin_texture2DRectProj,
+};
+static const char prototypes_for_EXT_texture_array_frag[] =
+ "(\n"
+ "(function texture1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function texture2DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArrayShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ())\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArrayShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float bias))\n"
+ " ()))\n"
+ "(function shadow2DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArrayShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())))"
+;
+static const char *functions_for_EXT_texture_array_frag [] = {
+ builtin_shadow1DArray,
+ builtin_shadow2DArray,
+ builtin_texture1DArray,
+ builtin_texture2DArray,
+};
+static const char prototypes_for_EXT_texture_array_vert[] =
+ "(\n"
+ "(function texture1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 coord))\n"
+ " ()))\n"
+ "(function texture1DArrayLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArray sampler)\n"
+ " (declare (in) vec2 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function texture2DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function texture2DArrayLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArray sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow1DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArrayShadow sampler)\n"
+ " (declare (in) vec3 coord))\n"
+ " ()))\n"
+ "(function shadow1DArrayLod\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler1DArrayShadow sampler)\n"
+ " (declare (in) vec3 coord)\n"
+ " (declare (in) float lod))\n"
+ " ()))\n"
+ "(function shadow2DArray\n"
+ " (signature vec4\n"
+ " (parameters\n"
+ " (declare (in) sampler2DArrayShadow sampler)\n"
+ " (declare (in) vec4 coord))\n"
+ " ())))"
+;
+static const char *functions_for_EXT_texture_array_vert [] = {
+ builtin_shadow1DArray,
+ builtin_shadow1DArrayLod,
+ builtin_shadow2DArray,
+ builtin_texture1DArray,
+ builtin_texture1DArrayLod,
+ builtin_texture2DArray,
+ builtin_texture2DArrayLod,
+};
+static gl_shader *builtin_profiles[12];
+
+void *builtin_mem_ctx = NULL;
+
+void
+_mesa_glsl_release_functions(void)
+{
+ talloc_free(builtin_mem_ctx);
+ builtin_mem_ctx = NULL;
+ memset(builtin_profiles, 0, sizeof(builtin_profiles));
+}
+
+static void
+_mesa_read_profile(struct _mesa_glsl_parse_state *state,
+ exec_list *instructions,
+ int profile_index,
+ const char *prototypes,
+ const char **functions,
+ int count)
+{
+ gl_shader *sh = builtin_profiles[profile_index];
+
+ if (sh == NULL) {
+ sh = read_builtins(GL_VERTEX_SHADER, prototypes, functions, count);
+ talloc_steal(builtin_mem_ctx, sh);
+ builtin_profiles[profile_index] = sh;
+ }
+
+ state->builtins_to_link[state->num_builtins_to_link] = sh;
+ state->num_builtins_to_link++;
+}
+
+void
+_mesa_glsl_initialize_functions(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (builtin_mem_ctx == NULL) {
+ builtin_mem_ctx = talloc_init("GLSL built-in functions");
+ memset(&builtin_profiles, 0, sizeof(builtin_profiles));
+ }
+
+ state->num_builtins_to_link = 0;
+
+ if (state->target == fragment_shader && state->language_version == 100) {
+ _mesa_read_profile(state, instructions, 0,
+ prototypes_for_100_frag,
+ functions_for_100_frag,
+ Elements(functions_for_100_frag));
+ }
+
+ if (state->target == vertex_shader && state->language_version == 100) {
+ _mesa_read_profile(state, instructions, 1,
+ prototypes_for_100_vert,
+ functions_for_100_vert,
+ Elements(functions_for_100_vert));
+ }
+
+ if (state->target == fragment_shader && state->language_version == 110) {
+ _mesa_read_profile(state, instructions, 2,
+ prototypes_for_110_frag,
+ functions_for_110_frag,
+ Elements(functions_for_110_frag));
+ }
+
+ if (state->target == vertex_shader && state->language_version == 110) {
+ _mesa_read_profile(state, instructions, 3,
+ prototypes_for_110_vert,
+ functions_for_110_vert,
+ Elements(functions_for_110_vert));
+ }
+
+ if (state->target == fragment_shader && state->language_version == 120) {
+ _mesa_read_profile(state, instructions, 4,
+ prototypes_for_120_frag,
+ functions_for_120_frag,
+ Elements(functions_for_120_frag));
+ }
+
+ if (state->target == vertex_shader && state->language_version == 120) {
+ _mesa_read_profile(state, instructions, 5,
+ prototypes_for_120_vert,
+ functions_for_120_vert,
+ Elements(functions_for_120_vert));
+ }
+
+ if (state->target == fragment_shader && state->language_version == 130) {
+ _mesa_read_profile(state, instructions, 6,
+ prototypes_for_130_frag,
+ functions_for_130_frag,
+ Elements(functions_for_130_frag));
+ }
+
+ if (state->target == vertex_shader && state->language_version == 130) {
+ _mesa_read_profile(state, instructions, 7,
+ prototypes_for_130_vert,
+ functions_for_130_vert,
+ Elements(functions_for_130_vert));
+ }
+
+ if (state->target == fragment_shader && state->ARB_texture_rectangle_enable) {
+ _mesa_read_profile(state, instructions, 8,
+ prototypes_for_ARB_texture_rectangle_frag,
+ functions_for_ARB_texture_rectangle_frag,
+ Elements(functions_for_ARB_texture_rectangle_frag));
+ }
+
+ if (state->target == vertex_shader && state->ARB_texture_rectangle_enable) {
+ _mesa_read_profile(state, instructions, 9,
+ prototypes_for_ARB_texture_rectangle_vert,
+ functions_for_ARB_texture_rectangle_vert,
+ Elements(functions_for_ARB_texture_rectangle_vert));
+ }
+
+ if (state->target == fragment_shader && state->EXT_texture_array_enable) {
+ _mesa_read_profile(state, instructions, 10,
+ prototypes_for_EXT_texture_array_frag,
+ functions_for_EXT_texture_array_frag,
+ Elements(functions_for_EXT_texture_array_frag));
+ }
+
+ if (state->target == vertex_shader && state->EXT_texture_array_enable) {
+ _mesa_read_profile(state, instructions, 11,
+ prototypes_for_EXT_texture_array_vert,
+ functions_for_EXT_texture_array_vert,
+ Elements(functions_for_EXT_texture_array_vert));
+ }
+
+}
diff --git a/mesalib/src/glsl/builtin_types.h b/mesalib/src/glsl/builtin_types.h index 6dabbf0d3..1d00d65ee 100644 --- a/mesalib/src/glsl/builtin_types.h +++ b/mesalib/src/glsl/builtin_types.h @@ -1,297 +1,300 @@ -/* - * 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. - */ - -const glsl_type glsl_type::_error_type = - glsl_type(GL_INVALID_ENUM, GLSL_TYPE_ERROR, 0, 0, ""); - -const glsl_type glsl_type::void_type = - glsl_type(GL_INVALID_ENUM, GLSL_TYPE_VOID, 0, 0, "void"); - -const glsl_type *const glsl_type::error_type = & glsl_type::_error_type; - -/** \name Core built-in types - * - * These types exist in all versions of GLSL. - */ -/*@{*/ - -const glsl_type glsl_type::builtin_core_types[] = { - glsl_type(GL_BOOL, GLSL_TYPE_BOOL, 1, 1, "bool"), - glsl_type(GL_BOOL_VEC2, GLSL_TYPE_BOOL, 2, 1, "bvec2"), - glsl_type(GL_BOOL_VEC3, GLSL_TYPE_BOOL, 3, 1, "bvec3"), - glsl_type(GL_BOOL_VEC4, GLSL_TYPE_BOOL, 4, 1, "bvec4"), - glsl_type(GL_INT, GLSL_TYPE_INT, 1, 1, "int"), - glsl_type(GL_INT_VEC2, GLSL_TYPE_INT, 2, 1, "ivec2"), - glsl_type(GL_INT_VEC3, GLSL_TYPE_INT, 3, 1, "ivec3"), - glsl_type(GL_INT_VEC4, GLSL_TYPE_INT, 4, 1, "ivec4"), - glsl_type(GL_FLOAT, GLSL_TYPE_FLOAT, 1, 1, "float"), - glsl_type(GL_FLOAT_VEC2, GLSL_TYPE_FLOAT, 2, 1, "vec2"), - glsl_type(GL_FLOAT_VEC3, GLSL_TYPE_FLOAT, 3, 1, "vec3"), - glsl_type(GL_FLOAT_VEC4, GLSL_TYPE_FLOAT, 4, 1, "vec4"), - glsl_type(GL_FLOAT_MAT2, GLSL_TYPE_FLOAT, 2, 2, "mat2"), - glsl_type(GL_FLOAT_MAT3, GLSL_TYPE_FLOAT, 3, 3, "mat3"), - glsl_type(GL_FLOAT_MAT4, GLSL_TYPE_FLOAT, 4, 4, "mat4"), - glsl_type(GL_SAMPLER_2D, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT, - "sampler2D"), - glsl_type(GL_SAMPLER_CUBE, 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" }, -}; - -const glsl_type 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" }, -}; - -const glsl_type 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 in GLSL 1.10 (but not GLSL ES 1.00) - */ -/*@{*/ -const glsl_type glsl_type::builtin_110_types[] = { - glsl_type(GL_SAMPLER_1D, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT, - "sampler1D"), - glsl_type(GL_SAMPLER_1D_SHADOW, GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT, - "sampler1DShadow"), - glsl_type(GL_SAMPLER_2D_SHADOW, GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT, - "sampler2DShadow"), - glsl_type(GL_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT, - "sampler3D"), -}; -/*@}*/ - -/** \name Types added in GLSL 1.20 - */ -/*@{*/ - -const glsl_type glsl_type::builtin_120_types[] = { - glsl_type(GL_FLOAT_MAT2x3, GLSL_TYPE_FLOAT, 3, 2, "mat2x3"), - glsl_type(GL_FLOAT_MAT2x4, GLSL_TYPE_FLOAT, 4, 2, "mat2x4"), - glsl_type(GL_FLOAT_MAT3x2, GLSL_TYPE_FLOAT, 2, 3, "mat3x2"), - glsl_type(GL_FLOAT_MAT3x4, GLSL_TYPE_FLOAT, 4, 3, "mat3x4"), - glsl_type(GL_FLOAT_MAT4x2, GLSL_TYPE_FLOAT, 2, 4, "mat4x2"), - glsl_type(GL_FLOAT_MAT4x3, 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 - */ -/*@{*/ - -const glsl_type glsl_type::builtin_130_types[] = { - glsl_type(GL_UNSIGNED_INT, GLSL_TYPE_UINT, 1, 1, "uint"), - glsl_type(GL_UNSIGNED_INT_VEC2, GLSL_TYPE_UINT, 2, 1, "uvec2"), - glsl_type(GL_UNSIGNED_INT_VEC3, GLSL_TYPE_UINT, 3, 1, "uvec3"), - glsl_type(GL_UNSIGNED_INT_VEC4, GLSL_TYPE_UINT, 4, 1, "uvec4"), - - /* 1D and 2D texture arrays - several of these are included only in - * builtin_EXT_texture_array_types. - */ - glsl_type(GL_INT_SAMPLER_1D_ARRAY, - GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT, "isampler1DArray"), - glsl_type(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, - GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT, "usampler1DArray"), - glsl_type(GL_INT_SAMPLER_2D_ARRAY, - GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT, "isampler2DArray"), - glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, - GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT, "usampler2DArray"), - - /* cube shadow samplers */ - glsl_type(GL_SAMPLER_CUBE_SHADOW, - GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT, "samplerCubeShadow"), - - /* signed and unsigned integer samplers */ - glsl_type(GL_INT_SAMPLER_1D, - GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT, "isampler1D"), - glsl_type(GL_UNSIGNED_INT_SAMPLER_1D, - GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT, "usampler1D"), - glsl_type(GL_INT_SAMPLER_2D, - GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT, "isampler2D"), - glsl_type(GL_UNSIGNED_INT_SAMPLER_2D, - GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT, "usampler2D"), - glsl_type(GL_INT_SAMPLER_3D, - GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT, "isampler3D"), - glsl_type(GL_UNSIGNED_INT_SAMPLER_3D, - GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT, "usampler3D"), - glsl_type(GL_INT_SAMPLER_CUBE, - GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT, "isamplerCube"), - glsl_type(GL_INT_SAMPLER_CUBE, - 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 - */ -/*@{*/ - -const glsl_type glsl_type::builtin_ARB_texture_rectangle_types[] = { - glsl_type(GL_SAMPLER_2D_RECT, - GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT, "sampler2DRect"), - glsl_type(GL_SAMPLER_2D_RECT_SHADOW, - GLSL_SAMPLER_DIM_RECT, 1, 0, GLSL_TYPE_FLOAT, "sampler2DRectShadow"), -}; -/*@}*/ - -/** \name Sampler types added by GL_EXT_texture_array - */ -/*@{*/ - -const glsl_type glsl_type::builtin_EXT_texture_array_types[] = { - glsl_type(GL_SAMPLER_1D_ARRAY, - GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT, "sampler1DArray"), - glsl_type(GL_SAMPLER_1D_ARRAY_SHADOW, - GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT, "sampler2DArray"), - glsl_type(GL_SAMPLER_2D_ARRAY, - GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT, "sampler1DArrayShadow"), - glsl_type(GL_SAMPLER_2D_ARRAY_SHADOW, - GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT, "sampler2DArrayShadow"), -}; -/*@}*/ - -/** \name Sampler types added by GL_EXT_texture_buffer_object - */ -/*@{*/ - -const glsl_type glsl_type::builtin_EXT_texture_buffer_object_types[] = { - glsl_type(GL_SAMPLER_BUFFER, - GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT, "samplerBuffer"), - glsl_type(GL_INT_SAMPLER_BUFFER, - GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT, "isamplerBuffer"), - glsl_type(GL_UNSIGNED_INT_SAMPLER_BUFFER, - GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT, "usamplerBuffer"), -}; -/*@}*/ +/*
+ * 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.
+ */
+
+const glsl_type glsl_type::_error_type =
+ glsl_type(GL_INVALID_ENUM, GLSL_TYPE_ERROR, 0, 0, "");
+
+const glsl_type glsl_type::_void_type =
+ glsl_type(GL_INVALID_ENUM, GLSL_TYPE_VOID, 0, 0, "void");
+
+const glsl_type *const glsl_type::error_type = & glsl_type::_error_type;
+const glsl_type *const glsl_type::void_type = & glsl_type::_void_type;
+
+/** \name Core built-in types
+ *
+ * These types exist in all versions of GLSL.
+ */
+/*@{*/
+
+const glsl_type glsl_type::builtin_core_types[] = {
+ glsl_type(GL_BOOL, GLSL_TYPE_BOOL, 1, 1, "bool"),
+ glsl_type(GL_BOOL_VEC2, GLSL_TYPE_BOOL, 2, 1, "bvec2"),
+ glsl_type(GL_BOOL_VEC3, GLSL_TYPE_BOOL, 3, 1, "bvec3"),
+ glsl_type(GL_BOOL_VEC4, GLSL_TYPE_BOOL, 4, 1, "bvec4"),
+ glsl_type(GL_INT, GLSL_TYPE_INT, 1, 1, "int"),
+ glsl_type(GL_INT_VEC2, GLSL_TYPE_INT, 2, 1, "ivec2"),
+ glsl_type(GL_INT_VEC3, GLSL_TYPE_INT, 3, 1, "ivec3"),
+ glsl_type(GL_INT_VEC4, GLSL_TYPE_INT, 4, 1, "ivec4"),
+ glsl_type(GL_FLOAT, GLSL_TYPE_FLOAT, 1, 1, "float"),
+ glsl_type(GL_FLOAT_VEC2, GLSL_TYPE_FLOAT, 2, 1, "vec2"),
+ glsl_type(GL_FLOAT_VEC3, GLSL_TYPE_FLOAT, 3, 1, "vec3"),
+ glsl_type(GL_FLOAT_VEC4, GLSL_TYPE_FLOAT, 4, 1, "vec4"),
+ glsl_type(GL_FLOAT_MAT2, GLSL_TYPE_FLOAT, 2, 2, "mat2"),
+ glsl_type(GL_FLOAT_MAT3, GLSL_TYPE_FLOAT, 3, 3, "mat3"),
+ glsl_type(GL_FLOAT_MAT4, GLSL_TYPE_FLOAT, 4, 4, "mat4"),
+ glsl_type(GL_SAMPLER_2D, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT,
+ "sampler2D"),
+ glsl_type(GL_SAMPLER_CUBE, 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" },
+};
+
+const glsl_type 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" },
+};
+
+const glsl_type 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 in GLSL 1.10 (but not GLSL ES 1.00)
+ */
+/*@{*/
+const glsl_type glsl_type::builtin_110_types[] = {
+ glsl_type(GL_SAMPLER_1D, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT,
+ "sampler1D"),
+ glsl_type(GL_SAMPLER_1D_SHADOW, GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT,
+ "sampler1DShadow"),
+ glsl_type(GL_SAMPLER_2D_SHADOW, GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT,
+ "sampler2DShadow"),
+ glsl_type(GL_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT,
+ "sampler3D"),
+};
+/*@}*/
+
+/** \name Types added in GLSL 1.20
+ */
+/*@{*/
+
+const glsl_type glsl_type::builtin_120_types[] = {
+ glsl_type(GL_FLOAT_MAT2x3, GLSL_TYPE_FLOAT, 3, 2, "mat2x3"),
+ glsl_type(GL_FLOAT_MAT2x4, GLSL_TYPE_FLOAT, 4, 2, "mat2x4"),
+ glsl_type(GL_FLOAT_MAT3x2, GLSL_TYPE_FLOAT, 2, 3, "mat3x2"),
+ glsl_type(GL_FLOAT_MAT3x4, GLSL_TYPE_FLOAT, 4, 3, "mat3x4"),
+ glsl_type(GL_FLOAT_MAT4x2, GLSL_TYPE_FLOAT, 2, 4, "mat4x2"),
+ glsl_type(GL_FLOAT_MAT4x3, 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
+ */
+/*@{*/
+
+const glsl_type glsl_type::builtin_130_types[] = {
+ glsl_type(GL_UNSIGNED_INT, GLSL_TYPE_UINT, 1, 1, "uint"),
+ glsl_type(GL_UNSIGNED_INT_VEC2, GLSL_TYPE_UINT, 2, 1, "uvec2"),
+ glsl_type(GL_UNSIGNED_INT_VEC3, GLSL_TYPE_UINT, 3, 1, "uvec3"),
+ glsl_type(GL_UNSIGNED_INT_VEC4, GLSL_TYPE_UINT, 4, 1, "uvec4"),
+
+ /* 1D and 2D texture arrays - several of these are included only in
+ * builtin_EXT_texture_array_types.
+ */
+ glsl_type(GL_INT_SAMPLER_1D_ARRAY,
+ GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT, "isampler1DArray"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY,
+ GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT, "usampler1DArray"),
+ glsl_type(GL_INT_SAMPLER_2D_ARRAY,
+ GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT, "isampler2DArray"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,
+ GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT, "usampler2DArray"),
+
+ /* cube shadow samplers */
+ glsl_type(GL_SAMPLER_CUBE_SHADOW,
+ GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT, "samplerCubeShadow"),
+
+ /* signed and unsigned integer samplers */
+ glsl_type(GL_INT_SAMPLER_1D,
+ GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT, "isampler1D"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_1D,
+ GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT, "usampler1D"),
+ glsl_type(GL_INT_SAMPLER_2D,
+ GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT, "isampler2D"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_2D,
+ GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT, "usampler2D"),
+ glsl_type(GL_INT_SAMPLER_3D,
+ GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT, "isampler3D"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_3D,
+ GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT, "usampler3D"),
+ glsl_type(GL_INT_SAMPLER_CUBE,
+ GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT, "isamplerCube"),
+ glsl_type(GL_INT_SAMPLER_CUBE,
+ 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::uvec2_type = & builtin_130_types[1];
+const glsl_type *const glsl_type::uvec3_type = & builtin_130_types[2];
+const glsl_type *const glsl_type::uvec4_type = & builtin_130_types[3];
+/*@}*/
+
+/** \name Sampler types added by GL_ARB_texture_rectangle
+ */
+/*@{*/
+
+const glsl_type glsl_type::builtin_ARB_texture_rectangle_types[] = {
+ glsl_type(GL_SAMPLER_2D_RECT,
+ GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT, "sampler2DRect"),
+ glsl_type(GL_SAMPLER_2D_RECT_SHADOW,
+ GLSL_SAMPLER_DIM_RECT, 1, 0, GLSL_TYPE_FLOAT, "sampler2DRectShadow"),
+};
+/*@}*/
+
+/** \name Sampler types added by GL_EXT_texture_array
+ */
+/*@{*/
+
+const glsl_type glsl_type::builtin_EXT_texture_array_types[] = {
+ glsl_type(GL_SAMPLER_1D_ARRAY,
+ GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT, "sampler1DArray"),
+ glsl_type(GL_SAMPLER_2D_ARRAY,
+ GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT, "sampler2DArray"),
+ glsl_type(GL_SAMPLER_1D_ARRAY_SHADOW,
+ GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT, "sampler1DArrayShadow"),
+ glsl_type(GL_SAMPLER_2D_ARRAY_SHADOW,
+ GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT, "sampler2DArrayShadow"),
+};
+/*@}*/
+
+/** \name Sampler types added by GL_EXT_texture_buffer_object
+ */
+/*@{*/
+
+const glsl_type glsl_type::builtin_EXT_texture_buffer_object_types[] = {
+ glsl_type(GL_SAMPLER_BUFFER,
+ GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT, "samplerBuffer"),
+ glsl_type(GL_INT_SAMPLER_BUFFER,
+ GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT, "isamplerBuffer"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_BUFFER,
+ GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT, "usamplerBuffer"),
+};
+/*@}*/
diff --git a/mesalib/src/glsl/glcpp/Makefile.am b/mesalib/src/glsl/glcpp/Makefile.am new file mode 100644 index 000000000..8a3e9b007 --- /dev/null +++ b/mesalib/src/glsl/glcpp/Makefile.am @@ -0,0 +1,44 @@ +# 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 \
+ pp.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)
diff --git a/mesalib/src/glsl/glcpp/glcpp-lex.c b/mesalib/src/glsl/glcpp/glcpp-lex.c index 0f99ea1bb..546225bbc 100644 --- a/mesalib/src/glsl/glcpp/glcpp-lex.c +++ b/mesalib/src/glsl/glcpp/glcpp-lex.c @@ -1,2691 +1,2677 @@ -#line 2 "glcpp/glcpp-lex.c" - -#line 4 "glcpp/glcpp-lex.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE glcpp_restart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via glcpp_restart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void glcpp_restart (FILE *input_file ,yyscan_t yyscanner ); -void glcpp__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE glcpp__create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void glcpp__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void glcpp__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void glcpp_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void glcpp_pop_buffer_state (yyscan_t yyscanner ); - -static void glcpp_ensure_buffer_stack (yyscan_t yyscanner ); -static void glcpp__load_buffer_state (yyscan_t yyscanner ); -static void glcpp__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER glcpp__flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE glcpp__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE glcpp__scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE glcpp__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *glcpp_alloc (yy_size_t ,yyscan_t yyscanner ); -void *glcpp_realloc (void *,yy_size_t ,yyscan_t yyscanner ); -void glcpp_free (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer glcpp__create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - glcpp_ensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - glcpp_ensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define glcpp_wrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 43 -#define YY_END_OF_BUFFER 44 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_acclist[137] = - { 0, - 3, 3, 44, 39, 43, 40, 43, 41, 43, 43, - 38, 43, 43, 38, 43, 38, 43, 38, 43, 25, - 39, 43, 24, 39, 43, 38, 43, 38, 43, 38, - 43, 37, 39, 43, 37, 39, 43, 38, 43, 40, - 43, 23, 43, 43, 3, 43, 4, 43, 5, 43, - 42, 43, 39, 18, 40, 32, 35, 33, 2, 1, - 25, 39, 25, 39, 39, 24, 39, 24, 39, 27, - 29, 31, 30, 28, 37, 39, 37, 39, 34, 40, - 23, 23, 3, 4, 5, 6, 5, 7, 1, 26, - 39, 37, 39,16398, 26, 39, 37, 39, 18, 37, - - 39,16399,16400, 8206, 18, 8206, 37, 39, 8207, 18, - 8208, 18,16401, 19,16396, 22, 36, 37, 39, 21, - 8209, 18, 19, 8204, 18,16397,16404, 8205, 18, 11, - 18, 9, 8, 8212, 10, 18 - } ; - -static yyconst flex_int16_t yy_accept[164] = - { 0, - 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, - 6, 8, 10, 11, 13, 14, 16, 18, 20, 23, - 26, 28, 30, 32, 35, 38, 40, 42, 44, 45, - 47, 49, 51, 53, 54, 54, 55, 56, 57, 58, - 59, 60, 61, 63, 65, 66, 68, 70, 71, 72, - 73, 74, 75, 77, 79, 80, 81, 82, 83, 83, - 83, 83, 83, 83, 83, 83, 84, 85, 86, 87, - 88, 89, 90, 92, 94, 94, 94, 94, 94, 94, - 95, 95, 95, 95, 95, 97, 99, 99, 99, 99, - 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, - - 100, 102, 102, 103, 104, 104, 104, 104, 104, 106, - 106, 107, 107, 107, 107, 107, 107, 107, 109, 109, - 109, 111, 111, 113, 114, 115, 115, 116, 116, 116, - 116, 117, 117, 120, 121, 121, 123, 124, 124, 124, - 126, 127, 127, 127, 127, 128, 128, 128, 130, 130, - 132, 132, 133, 134, 134, 134, 134, 135, 135, 135, - 137, 137, 137 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, - 7, 10, 7, 7, 7, 7, 11, 12, 13, 13, - 13, 13, 13, 13, 13, 14, 14, 1, 7, 15, - 16, 17, 1, 1, 18, 18, 18, 18, 18, 18, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 20, 19, 19, 21, 19, 19, - 7, 1, 7, 7, 19, 1, 22, 18, 18, 23, - - 24, 25, 26, 19, 27, 19, 19, 28, 29, 30, - 31, 32, 19, 33, 34, 35, 36, 37, 19, 38, - 19, 19, 7, 39, 7, 7, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[40] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int16_t yy_base[182] = - { 0, - 0, 38, 0, 0, 38, 39, 499, 498, 500, 48, - 43, 552, 496, 44, 63, 495, 59, 65, 87, 125, - 58, 67, 68, 164, 203, 40, 75, 241, 552, 494, - 552, 140, 552, 140, 493, 552, 144, 492, 491, 487, - 486, 485, 156, 179, 267, 0, 209, 472, 471, 470, - 469, 468, 446, 124, 466, 153, 462, 458, 154, 198, - 159, 155, 183, 160, 193, 460, 552, 222, 552, 227, - 552, 459, 204, 161, 231, 232, 238, 243, 236, 303, - 245, 180, 247, 249, 281, 56, 257, 271, 248, 259, - 252, 264, 455, 454, 297, 299, 312, 313, 320, 294, - - 407, 295, 427, 426, 321, 296, 324, 425, 552, 424, - 552, 327, 329, 195, 328, 331, 332, 230, 334, 378, - 552, 377, 552, 371, 370, 335, 365, 337, 358, 342, - 360, 344, 326, 255, 340, 552, 260, 338, 246, 552, - 197, 364, 192, 352, 382, 348, 186, 552, 420, 552, - 423, 184, 141, 437, 421, 447, 79, 476, 346, 552, - 453, 552, 515, 517, 519, 521, 523, 525, 71, 527, - 529, 531, 533, 535, 537, 539, 541, 543, 545, 547, - 549 - } ; - -static yyconst flex_int16_t yy_def[182] = - { 0, - 162, 1, 163, 163, 164, 164, 165, 165, 162, 166, - 167, 162, 167, 167, 167, 167, 167, 167, 162, 166, - 167, 167, 167, 168, 168, 167, 167, 167, 162, 169, - 162, 170, 162, 20, 167, 162, 167, 167, 167, 167, - 167, 171, 19, 20, 20, 20, 20, 167, 167, 167, - 167, 167, 25, 25, 167, 167, 28, 28, 167, 167, - 167, 167, 167, 167, 167, 169, 162, 170, 162, 170, - 162, 171, 45, 25, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 20, 25, 167, 167, 167, 167, - 167, 167, 172, 173, 167, 167, 167, 167, 167, 167, - - 25, 167, 174, 175, 167, 167, 167, 172, 162, 173, - 162, 167, 167, 167, 167, 167, 167, 25, 167, 174, - 162, 175, 162, 176, 177, 167, 178, 167, 167, 167, - 167, 167, 25, 167, 176, 162, 177, 167, 178, 162, - 179, 167, 180, 167, 162, 167, 179, 162, 167, 162, - 167, 180, 167, 181, 167, 167, 167, 181, 167, 162, - 167, 0, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162 - } ; - -static yyconst flex_int16_t yy_nxt[592] = - { 0, - 10, 11, 12, 13, 14, 15, 16, 17, 16, 16, - 18, 19, 20, 20, 21, 22, 23, 24, 24, 24, - 24, 24, 25, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 26, 27, - 31, 31, 36, 28, 37, 36, 36, 32, 32, 35, - 36, 35, 35, 35, 35, 35, 35, 35, 35, 38, - 36, 36, 35, 35, 35, 36, 40, 36, 39, 36, - 36, 66, 48, 49, 41, 42, 56, 36, 55, 53, - 57, 36, 50, 51, 52, 101, 35, 34, 35, 36, - 35, 35, 35, 35, 35, 35, 35, 35, 43, 43, - - 34, 35, 35, 35, 34, 34, 44, 45, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 44, 34, 45, 35, 35, 36, 35, 35, - 35, 35, 35, 35, 35, 35, 46, 46, 46, 35, - 35, 35, 69, 36, 47, 37, 36, 53, 74, 70, - 71, 34, 34, 34, 56, 36, 36, 36, 57, 34, - 47, 36, 36, 35, 34, 35, 36, 35, 35, 35, - 35, 35, 35, 35, 35, 34, 34, 75, 35, 35, - 35, 81, 36, 80, 53, 36, 36, 86, 148, 83, - 34, 34, 34, 34, 36, 36, 129, 36, 34, 148, - - 36, 98, 35, 34, 35, 36, 35, 35, 35, 35, - 35, 35, 35, 35, 34, 82, 84, 35, 35, 35, - 34, 34, 34, 85, 69, 76, 54, 77, 34, 69, - 78, 162, 162, 36, 36, 79, 70, 71, 36, 85, - 36, 35, 58, 36, 34, 36, 39, 36, 140, 36, - 36, 36, 133, 53, 36, 87, 145, 36, 88, 36, - 90, 36, 36, 59, 60, 89, 36, 61, 62, 99, - 92, 104, 63, 36, 97, 91, 64, 65, 73, 73, - 73, 100, 106, 102, 73, 105, 34, 107, 73, 73, - 73, 73, 34, 34, 34, 103, 36, 36, 36, 36, - - 34, 36, 34, 93, 93, 94, 93, 93, 93, 93, - 93, 93, 93, 93, 36, 36, 34, 93, 93, 93, - 112, 113, 36, 36, 119, 95, 36, 117, 125, 36, - 36, 36, 96, 36, 36, 114, 36, 36, 115, 36, - 36, 93, 136, 116, 36, 124, 36, 159, 160, 53, - 36, 127, 128, 126, 36, 131, 130, 134, 132, 129, - 36, 141, 36, 143, 146, 149, 150, 140, 138, 142, - 142, 142, 36, 136, 144, 151, 151, 151, 155, 123, - 121, 153, 35, 145, 36, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 154, - - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 35, 149, 150, 36, 149, 150, 111, 109, 123, 121, - 118, 156, 156, 156, 151, 151, 151, 35, 35, 36, - 35, 35, 35, 35, 35, 157, 35, 35, 159, 160, - 143, 35, 35, 35, 159, 160, 111, 109, 161, 161, - 161, 36, 67, 35, 161, 161, 161, 35, 36, 53, - 36, 36, 36, 36, 36, 35, 35, 35, 36, 35, - 35, 35, 35, 35, 157, 35, 35, 36, 36, 36, - 35, 35, 35, 36, 36, 36, 67, 36, 36, 162, - - 29, 29, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 35, 29, 29, 30, 30, 33, - 33, 34, 34, 35, 35, 53, 53, 68, 68, 72, - 72, 108, 108, 110, 110, 120, 120, 122, 122, 135, - 135, 137, 137, 139, 139, 147, 147, 152, 152, 158, - 158, 9, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162 - - } ; - -static yyconst flex_int16_t yy_chk[592] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 5, 6, 26, 2, 11, 11, 14, 5, 6, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 14, - 21, 17, 10, 10, 10, 15, 17, 18, 15, 22, - 23, 169, 21, 21, 18, 18, 27, 27, 26, 86, - 27, 157, 22, 23, 23, 86, 10, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 32, 153, 20, 37, 37, 54, 54, 32, - 32, 34, 34, 34, 56, 56, 59, 62, 56, 34, - 20, 61, 64, 20, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 34, 43, 59, 24, 24, - 24, 62, 82, 61, 74, 63, 152, 74, 147, 64, - 44, 44, 44, 43, 143, 65, 114, 114, 44, 141, - - 60, 82, 24, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 44, 63, 65, 25, 25, 25, - 47, 47, 47, 73, 68, 60, 25, 60, 47, 70, - 60, 68, 68, 75, 76, 60, 70, 70, 79, 73, - 77, 25, 28, 28, 47, 78, 28, 81, 139, 83, - 89, 84, 118, 118, 91, 75, 134, 134, 76, 87, - 77, 90, 137, 28, 28, 76, 92, 28, 28, 83, - 79, 89, 28, 88, 81, 78, 28, 28, 45, 45, - 45, 84, 91, 87, 45, 90, 45, 92, 45, 45, - 45, 45, 85, 85, 85, 88, 100, 102, 106, 95, - - 85, 96, 45, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 97, 98, 85, 80, 80, 80, - 95, 96, 99, 105, 102, 80, 107, 100, 106, 112, - 115, 113, 80, 116, 117, 97, 119, 126, 98, 128, - 138, 80, 135, 99, 130, 105, 132, 159, 159, 133, - 146, 112, 113, 107, 144, 116, 115, 119, 117, 129, - 129, 128, 131, 130, 138, 142, 142, 127, 126, 129, - 129, 129, 125, 124, 132, 142, 142, 142, 146, 122, - 120, 144, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 149, 149, 155, 151, 151, 110, 108, 104, 103, - 101, 149, 149, 149, 151, 151, 151, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 156, 156, - 155, 154, 154, 154, 161, 161, 94, 93, 156, 156, - 156, 72, 66, 58, 161, 161, 161, 57, 55, 53, - 52, 51, 50, 49, 48, 154, 158, 158, 158, 158, - 158, 158, 158, 158, 158, 158, 158, 42, 41, 40, - 158, 158, 158, 39, 38, 35, 30, 16, 13, 9, - - 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 158, 163, 163, 164, 164, 165, - 165, 166, 166, 167, 167, 168, 168, 170, 170, 171, - 171, 172, 172, 173, 173, 174, 174, 175, 175, 176, - 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, - 181, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162 - - } ; - -#define YY_TRAILING_MASK 0x2000 -#define YY_TRAILING_HEAD_MASK 0x4000 -#define REJECT \ -{ \ -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ \ -yy_cp = yyg->yy_full_match; /* restore poss. backed-over text */ \ -yyg->yy_lp = yyg->yy_full_lp; /* restore orig. accepting pos. */ \ -yyg->yy_state_ptr = yyg->yy_full_state; /* restore orig. state */ \ -yy_current_state = *yyg->yy_state_ptr; /* restore curr. state */ \ -++yyg->yy_lp; \ -goto find_rule; \ -} - -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "glcpp/glcpp-lex.l" -#line 2 "glcpp/glcpp-lex.l" -/* - * 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 <ctype.h> - -#include "glcpp.h" -#include "glcpp-parse.h" - -/* Flex annoyingly generates some functions without making them - * static. Let's declare them here. */ -int glcpp_get_column (yyscan_t yyscanner); -void glcpp_set_column (int column_no , yyscan_t yyscanner); - -#define YY_NO_INPUT - -#define YY_USER_ACTION \ - do { \ - yylloc->first_column = yycolumn + 1; \ - yylloc->first_line = yylineno; \ - yycolumn += yyleng; \ - } while(0); - -#define YY_USER_INIT \ - do { \ - yylineno = 1; \ - yycolumn = 1; \ - yylloc->source = 0; \ - } while(0) - -#line 709 "glcpp/glcpp-lex.c" - -#define INITIAL 0 -#define DONE 1 -#define COMMENT 2 -#define UNREACHABLE 3 - -#define YY_EXTRA_TYPE glcpp_parser_t * - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - yy_state_type *yy_state_buf; - yy_state_type *yy_state_ptr; - char *yy_full_match; - int yy_lp; - - /* These are only needed for trailing context rules, - * but there's no conditional variable for that yet. */ - int yy_looking_for_trail_begin; - int yy_full_lp; - int *yy_full_state; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int glcpp_lex_init (yyscan_t* scanner); - -int glcpp_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int glcpp_lex_destroy (yyscan_t yyscanner ); - -int glcpp_get_debug (yyscan_t yyscanner ); - -void glcpp_set_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE glcpp_get_extra (yyscan_t yyscanner ); - -void glcpp_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *glcpp_get_in (yyscan_t yyscanner ); - -void glcpp_set_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *glcpp_get_out (yyscan_t yyscanner ); - -void glcpp_set_out (FILE * out_str ,yyscan_t yyscanner ); - -int glcpp_get_leng (yyscan_t yyscanner ); - -char *glcpp_get_text (yyscan_t yyscanner ); - -int glcpp_get_lineno (yyscan_t yyscanner ); - -void glcpp_set_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * glcpp_get_lval (yyscan_t yyscanner ); - -void glcpp_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *glcpp_get_lloc (yyscan_t yyscanner ); - - void glcpp_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int glcpp_wrap (yyscan_t yyscanner ); -#else -extern int glcpp_wrap (yyscan_t yyscanner ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - - static void yy_push_state (int new_state ,yyscan_t yyscanner); - - static void yy_pop_state (yyscan_t yyscanner ); - - static int yy_top_state (yyscan_t yyscanner ); - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int glcpp_lex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int glcpp_lex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 76 "glcpp/glcpp-lex.l" - - - /* Single-line comments */ -#line 972 "glcpp/glcpp-lex.c" - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - /* Create the reject buffer large enough to save one state per allowed character. */ - if ( ! yyg->yy_state_buf ) - yyg->yy_state_buf = (yy_state_type *)glcpp_alloc(YY_STATE_BUF_SIZE ,yyscanner); - if ( ! yyg->yy_state_buf ) - YY_FATAL_ERROR( "out of dynamic memory in glcpp_lex()" ); - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - glcpp_ensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - glcpp__load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); - - yyg->yy_state_ptr = yyg->yy_state_buf; - *yyg->yy_state_ptr++ = yy_current_state; - -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 163 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - *yyg->yy_state_ptr++ = yy_current_state; - ++yy_cp; - } - while ( yy_current_state != 162 ); - -yy_find_action: - yy_current_state = *--yyg->yy_state_ptr; - yyg->yy_lp = yy_accept[yy_current_state]; -find_rule: /* we branch to this label when backing up */ - for ( ; ; ) /* until we find what rule we matched */ - { - if ( yyg->yy_lp && yyg->yy_lp < yy_accept[yy_current_state + 1] ) - { - yy_act = yy_acclist[yyg->yy_lp]; - if ( yy_act & YY_TRAILING_HEAD_MASK || - yyg->yy_looking_for_trail_begin ) - { - if ( yy_act == yyg->yy_looking_for_trail_begin ) - { - yyg->yy_looking_for_trail_begin = 0; - yy_act &= ~YY_TRAILING_HEAD_MASK; - break; - } - } - else if ( yy_act & YY_TRAILING_MASK ) - { - yyg->yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK; - yyg->yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK; - yyg->yy_full_match = yy_cp; - yyg->yy_full_state = yyg->yy_state_ptr; - yyg->yy_full_lp = yyg->yy_lp; - } - else - { - yyg->yy_full_match = yy_cp; - yyg->yy_full_state = yyg->yy_state_ptr; - yyg->yy_full_lp = yyg->yy_lp; - break; - } - ++yyg->yy_lp; - goto find_rule; - } - --yy_cp; - yy_current_state = *--yyg->yy_state_ptr; - yyg->yy_lp = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ -case 1: -YY_RULE_SETUP -#line 79 "glcpp/glcpp-lex.l" -{ -} - YY_BREAK -/* Multi-line comments */ -case 2: -YY_RULE_SETUP -#line 83 "glcpp/glcpp-lex.l" -{ yy_push_state(COMMENT, yyscanner); } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 84 "glcpp/glcpp-lex.l" - - YY_BREAK -case 4: -/* rule 4 can match eol */ -YY_RULE_SETUP -#line 85 "glcpp/glcpp-lex.l" -{ yylineno++; yycolumn = 0; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 86 "glcpp/glcpp-lex.l" - - YY_BREAK -case 6: -/* rule 6 can match eol */ -YY_RULE_SETUP -#line 87 "glcpp/glcpp-lex.l" -{ yylineno++; yycolumn = 0; } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 88 "glcpp/glcpp-lex.l" -{ - yy_pop_state(yyscanner); - if (yyextra->space_tokens) - return SPACE; -} - YY_BREAK -case 8: -YY_RULE_SETUP -#line 94 "glcpp/glcpp-lex.l" -{ - yylval->str = talloc_strdup (yyextra, yytext); - yyextra->space_tokens = 0; - return HASH_VERSION; -} - YY_BREAK -/* glcpp doesn't handle #extension, #version, or #pragma directives. - * Simply pass them through to the main compiler's lexer/parser. */ -case 9: -YY_RULE_SETUP -#line 102 "glcpp/glcpp-lex.l" -{ - yylval->str = talloc_strdup (yyextra, yytext); - yylineno++; - yycolumn = 0; - return OTHER; -} - YY_BREAK -case 10: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 109 "glcpp/glcpp-lex.l" -{ - /* 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); -} - YY_BREAK -case 11: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 125 "glcpp/glcpp-lex.l" -{ - /* 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; -} - YY_BREAK -case 12: -/* rule 12 can match eol */ -YY_RULE_SETUP -#line 140 "glcpp/glcpp-lex.l" -{ - yyextra->lexing_if = 1; - yyextra->space_tokens = 0; - return HASH_IFDEF; -} - YY_BREAK -case 13: -/* rule 13 can match eol */ -YY_RULE_SETUP -#line 146 "glcpp/glcpp-lex.l" -{ - yyextra->lexing_if = 1; - yyextra->space_tokens = 0; - return HASH_IFNDEF; -} - YY_BREAK -case 14: -/* rule 14 can match eol */ -YY_RULE_SETUP -#line 152 "glcpp/glcpp-lex.l" -{ - yyextra->lexing_if = 1; - yyextra->space_tokens = 0; - return HASH_IF; -} - YY_BREAK -case 15: -/* rule 15 can match eol */ -YY_RULE_SETUP -#line 158 "glcpp/glcpp-lex.l" -{ - yyextra->lexing_if = 1; - yyextra->space_tokens = 0; - return HASH_ELIF; -} - YY_BREAK -case 16: -/* rule 16 can match eol */ -YY_RULE_SETUP -#line 164 "glcpp/glcpp-lex.l" -{ - yyextra->space_tokens = 0; - return HASH_ELSE; -} - YY_BREAK -case 17: -/* rule 17 can match eol */ -YY_RULE_SETUP -#line 169 "glcpp/glcpp-lex.l" -{ - yyextra->space_tokens = 0; - return HASH_ENDIF; -} - YY_BREAK -/* When skipping (due to an #if 0 or similar) consume anything - * up to a newline. We do this with less priority 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. */ -case 18: -/* rule 18 can match eol */ -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 182 "glcpp/glcpp-lex.l" -{ - /* 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; - } -} - YY_BREAK -case 19: -YY_RULE_SETUP -#line 194 "glcpp/glcpp-lex.l" -{ - char *p; - for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */ - p += 5; /* skip "error" */ - glcpp_error(yylloc, yyextra, "#error%s", p); -} - YY_BREAK -case 20: -YY_RULE_SETUP -#line 201 "glcpp/glcpp-lex.l" -{ - yyextra->space_tokens = 0; - return HASH_DEFINE_FUNC; -} - YY_BREAK -case 21: -YY_RULE_SETUP -#line 206 "glcpp/glcpp-lex.l" -{ - yyextra->space_tokens = 0; - return HASH_DEFINE_OBJ; -} - YY_BREAK -case 22: -YY_RULE_SETUP -#line 211 "glcpp/glcpp-lex.l" -{ - yyextra->space_tokens = 0; - return HASH_UNDEF; -} - YY_BREAK -case 23: -YY_RULE_SETUP -#line 216 "glcpp/glcpp-lex.l" -{ - yyextra->space_tokens = 0; - return HASH; -} - YY_BREAK -case 24: -YY_RULE_SETUP -#line 221 "glcpp/glcpp-lex.l" -{ - yylval->str = talloc_strdup (yyextra, yytext); - return INTEGER_STRING; -} - YY_BREAK -case 25: -YY_RULE_SETUP -#line 226 "glcpp/glcpp-lex.l" -{ - yylval->str = talloc_strdup (yyextra, yytext); - return INTEGER_STRING; -} - YY_BREAK -case 26: -YY_RULE_SETUP -#line 231 "glcpp/glcpp-lex.l" -{ - yylval->str = talloc_strdup (yyextra, yytext); - return INTEGER_STRING; -} - YY_BREAK -case 27: -YY_RULE_SETUP -#line 236 "glcpp/glcpp-lex.l" -{ - return LEFT_SHIFT; -} - YY_BREAK -case 28: -YY_RULE_SETUP -#line 240 "glcpp/glcpp-lex.l" -{ - return RIGHT_SHIFT; -} - YY_BREAK -case 29: -YY_RULE_SETUP -#line 244 "glcpp/glcpp-lex.l" -{ - return LESS_OR_EQUAL; -} - YY_BREAK -case 30: -YY_RULE_SETUP -#line 248 "glcpp/glcpp-lex.l" -{ - return GREATER_OR_EQUAL; -} - YY_BREAK -case 31: -YY_RULE_SETUP -#line 252 "glcpp/glcpp-lex.l" -{ - return EQUAL; -} - YY_BREAK -case 32: -YY_RULE_SETUP -#line 256 "glcpp/glcpp-lex.l" -{ - return NOT_EQUAL; -} - YY_BREAK -case 33: -YY_RULE_SETUP -#line 260 "glcpp/glcpp-lex.l" -{ - return AND; -} - YY_BREAK -case 34: -YY_RULE_SETUP -#line 264 "glcpp/glcpp-lex.l" -{ - return OR; -} - YY_BREAK -case 35: -YY_RULE_SETUP -#line 268 "glcpp/glcpp-lex.l" -{ - return PASTE; -} - YY_BREAK -case 36: -YY_RULE_SETUP -#line 272 "glcpp/glcpp-lex.l" -{ - return DEFINED; -} - YY_BREAK -case 37: -YY_RULE_SETUP -#line 276 "glcpp/glcpp-lex.l" -{ - yylval->str = talloc_strdup (yyextra, yytext); - return IDENTIFIER; -} - YY_BREAK -case 38: -YY_RULE_SETUP -#line 281 "glcpp/glcpp-lex.l" -{ - return yytext[0]; -} - YY_BREAK -case 39: -YY_RULE_SETUP -#line 285 "glcpp/glcpp-lex.l" -{ - yylval->str = talloc_strdup (yyextra, yytext); - return OTHER; -} - YY_BREAK -case 40: -YY_RULE_SETUP -#line 290 "glcpp/glcpp-lex.l" -{ - if (yyextra->space_tokens) { - return SPACE; - } -} - YY_BREAK -case 41: -/* rule 41 can match eol */ -YY_RULE_SETUP -#line 296 "glcpp/glcpp-lex.l" -{ - yyextra->lexing_if = 0; - yylineno++; - yycolumn = 0; - return NEWLINE; -} - YY_BREAK -/* Handle missing newline at EOF. */ -case YY_STATE_EOF(INITIAL): -#line 304 "glcpp/glcpp-lex.l" -{ - BEGIN DONE; /* Don't keep matching this rule forever. */ - yyextra->lexing_if = 0; - return NEWLINE; -} - YY_BREAK -/* We don't actually use the UNREACHABLE start condition. We - only have this action here so that we can pretend to call some - generated functions, (to avoid "defined but not used" - warnings. */ -case 42: -YY_RULE_SETUP -#line 314 "glcpp/glcpp-lex.l" -{ - unput('.'); - yy_top_state(yyextra); -} - YY_BREAK -case 43: -YY_RULE_SETUP -#line 319 "glcpp/glcpp-lex.l" -ECHO; - YY_BREAK -#line 1489 "glcpp/glcpp-lex.c" - case YY_STATE_EOF(DONE): - case YY_STATE_EOF(COMMENT): - case YY_STATE_EOF(UNREACHABLE): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * glcpp_lex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( glcpp_wrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of glcpp_lex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - glcpp_restart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) glcpp_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); - - yyg->yy_state_ptr = yyg->yy_state_buf; - *yyg->yy_state_ptr++ = yy_current_state; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 163 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - *yyg->yy_state_ptr++ = yy_current_state; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - - register YY_CHAR yy_c = 1; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 163 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 162); - if ( ! yy_is_jam ) - *yyg->yy_state_ptr++ = yy_current_state; - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) -{ - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_cp = yyg->yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yyg->yy_hold_char; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yyg->yy_n_chars + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - yyg->yytext_ptr = yy_bp; - yyg->yy_hold_char = *yy_cp; - yyg->yy_c_buf_p = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - glcpp_restart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( glcpp_wrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void glcpp_restart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - glcpp_ensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - glcpp__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - glcpp__load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void glcpp__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * glcpp_pop_buffer_state(); - * glcpp_push_buffer_state(new_buffer); - */ - glcpp_ensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - glcpp__load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (glcpp_wrap()) processing, but the only time this flag - * is looked at is after glcpp_wrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void glcpp__load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE glcpp__create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) glcpp_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in glcpp__create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) glcpp_alloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in glcpp__create_buffer()" ); - - b->yy_is_our_buffer = 1; - - glcpp__init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with glcpp__create_buffer() - * @param yyscanner The scanner object. - */ - void glcpp__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - glcpp_free((void *) b->yy_ch_buf ,yyscanner ); - - glcpp_free((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a glcpp_restart() or at EOF. - */ - static void glcpp__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - glcpp__flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then glcpp__init_buffer was _probably_ - * called from glcpp_restart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void glcpp__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - glcpp__load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void glcpp_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - glcpp_ensure_buffer_stack(yyscanner); - - /* This block is copied from glcpp__switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from glcpp__switch_to_buffer. */ - glcpp__load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void glcpp_pop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - glcpp__delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - glcpp__load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void glcpp_ensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)glcpp_alloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in glcpp_ensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)glcpp_realloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in glcpp_ensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE glcpp__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) glcpp_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in glcpp__scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - glcpp__switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to glcpp_lex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * glcpp__scan_bytes() instead. - */ -YY_BUFFER_STATE glcpp__scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return glcpp__scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to glcpp_lex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE glcpp__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) glcpp_alloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in glcpp__scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = glcpp__scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in glcpp__scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - - static void yy_push_state (int new_state , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth ) - { - yy_size_t new_size; - - yyg->yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yyg->yy_start_stack_depth * sizeof( int ); - - if ( ! yyg->yy_start_stack ) - yyg->yy_start_stack = (int *) glcpp_alloc(new_size ,yyscanner ); - - else - yyg->yy_start_stack = (int *) glcpp_realloc((void *) yyg->yy_start_stack,new_size ,yyscanner ); - - if ( ! yyg->yy_start_stack ) - YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); - } - - yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); -} - - static void yy_pop_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( --yyg->yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]); -} - - static int yy_top_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1]; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE glcpp_get_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int glcpp_get_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int glcpp_get_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *glcpp_get_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *glcpp_get_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int glcpp_get_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *glcpp_get_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void glcpp_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void glcpp_set_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "glcpp_set_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void glcpp_set_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "glcpp_set_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see glcpp__switch_to_buffer - */ -void glcpp_set_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void glcpp_set_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int glcpp_get_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void glcpp_set_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * glcpp_get_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void glcpp_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *glcpp_get_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void glcpp_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* glcpp_lex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int glcpp_lex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) glcpp_alloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* glcpp_lex_init_extra has the same functionality as glcpp_lex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to glcpp_alloc in - * the yyextra field. - */ - -int glcpp_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - glcpp_set_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) glcpp_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - glcpp_set_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from glcpp_lex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - - yyg->yy_state_buf = 0; - yyg->yy_state_ptr = 0; - yyg->yy_full_match = 0; - yyg->yy_lp = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * glcpp_lex_init() - */ - return 0; -} - -/* glcpp_lex_destroy is for both reentrant and non-reentrant scanners. */ -int glcpp_lex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - glcpp__delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - glcpp_pop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - glcpp_free(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - glcpp_free(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - glcpp_free ( yyg->yy_state_buf , yyscanner); - yyg->yy_state_buf = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * glcpp_lex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - glcpp_free ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *glcpp_alloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *glcpp_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void glcpp_free (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see glcpp_realloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 319 "glcpp/glcpp-lex.l" - - - -void -glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader) -{ - glcpp__scan_string(shader,parser->scanner); -} - +#line 2 "glcpp/glcpp-lex.c"
+
+#line 4 "glcpp/glcpp-lex.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE glcpp_restart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via glcpp_restart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void glcpp_restart (FILE *input_file ,yyscan_t yyscanner );
+void glcpp__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE glcpp__create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void glcpp__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void glcpp__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void glcpp_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void glcpp_pop_buffer_state (yyscan_t yyscanner );
+
+static void glcpp_ensure_buffer_stack (yyscan_t yyscanner );
+static void glcpp__load_buffer_state (yyscan_t yyscanner );
+static void glcpp__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER glcpp__flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE glcpp__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE glcpp__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE glcpp__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *glcpp_alloc (yy_size_t ,yyscan_t yyscanner );
+void *glcpp_realloc (void *,yy_size_t ,yyscan_t yyscanner );
+void glcpp_free (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer glcpp__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ glcpp_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ glcpp_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define glcpp_wrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 43
+#define YY_END_OF_BUFFER 44
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_acclist[137] =
+ { 0,
+ 3, 3, 44, 39, 43, 40, 43, 41, 43, 43,
+ 38, 43, 43, 38, 43, 38, 43, 38, 43, 25,
+ 39, 43, 24, 39, 43, 38, 43, 38, 43, 38,
+ 43, 37, 39, 43, 37, 39, 43, 38, 43, 40,
+ 43, 23, 43, 43, 3, 43, 4, 43, 5, 43,
+ 42, 43, 39, 18, 40, 32, 35, 33, 2, 1,
+ 25, 39, 25, 39, 39, 24, 39, 24, 39, 27,
+ 29, 31, 30, 28, 37, 39, 37, 39, 34, 40,
+ 23, 23, 3, 4, 5, 6, 5, 7, 1, 26,
+ 39, 37, 39,16398, 26, 39, 37, 39, 18, 37,
+
+ 39,16399,16400, 8206, 18, 8206, 37, 39, 8207, 18,
+ 8208, 18,16401, 19,16396, 22, 36, 37, 39, 21,
+ 8209, 18, 19, 8204, 18,16397,16404, 8205, 18, 11,
+ 18, 9, 8, 8212, 10, 18
+ } ;
+
+static yyconst flex_int16_t yy_accept[164] =
+ { 0,
+ 1, 1, 1, 1, 1, 2, 3, 3, 3, 4,
+ 6, 8, 10, 11, 13, 14, 16, 18, 20, 23,
+ 26, 28, 30, 32, 35, 38, 40, 42, 44, 45,
+ 47, 49, 51, 53, 54, 54, 55, 56, 57, 58,
+ 59, 60, 61, 63, 65, 66, 68, 70, 71, 72,
+ 73, 74, 75, 77, 79, 80, 81, 82, 83, 83,
+ 83, 83, 83, 83, 83, 83, 84, 85, 86, 87,
+ 88, 89, 90, 92, 94, 94, 94, 94, 94, 94,
+ 95, 95, 95, 95, 95, 97, 99, 99, 99, 99,
+ 99, 99, 99, 99, 100, 100, 100, 100, 100, 100,
+
+ 100, 102, 102, 103, 104, 104, 104, 104, 104, 106,
+ 106, 107, 107, 107, 107, 107, 107, 107, 109, 109,
+ 109, 111, 111, 113, 114, 115, 115, 116, 116, 116,
+ 116, 117, 117, 120, 121, 121, 123, 124, 124, 124,
+ 126, 127, 127, 127, 127, 128, 128, 128, 130, 130,
+ 132, 132, 133, 134, 134, 134, 134, 135, 135, 135,
+ 137, 137, 137
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 1, 6, 1, 7, 8, 1, 9,
+ 7, 10, 7, 7, 7, 7, 11, 12, 13, 13,
+ 13, 13, 13, 13, 13, 14, 14, 1, 7, 15,
+ 16, 17, 1, 1, 18, 18, 18, 18, 18, 18,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 20, 19, 19, 21, 19, 19,
+ 7, 1, 7, 7, 19, 1, 22, 18, 18, 23,
+
+ 24, 25, 26, 19, 27, 19, 19, 28, 29, 30,
+ 31, 32, 19, 33, 34, 35, 36, 37, 19, 38,
+ 19, 19, 7, 39, 7, 7, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[40] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[182] =
+ { 0,
+ 0, 38, 0, 0, 38, 39, 499, 498, 500, 48,
+ 43, 552, 496, 44, 63, 495, 59, 65, 87, 125,
+ 58, 67, 68, 164, 203, 40, 75, 241, 552, 494,
+ 552, 140, 552, 140, 493, 552, 144, 492, 491, 487,
+ 486, 485, 156, 179, 267, 0, 209, 472, 471, 470,
+ 469, 468, 446, 124, 466, 153, 462, 458, 154, 198,
+ 159, 155, 183, 160, 193, 460, 552, 222, 552, 227,
+ 552, 459, 204, 161, 231, 232, 238, 243, 236, 303,
+ 245, 180, 247, 249, 281, 56, 257, 271, 248, 259,
+ 252, 264, 455, 454, 297, 299, 312, 313, 320, 294,
+
+ 407, 295, 427, 426, 321, 296, 324, 425, 552, 424,
+ 552, 327, 329, 195, 328, 331, 332, 230, 334, 378,
+ 552, 377, 552, 371, 370, 335, 365, 337, 358, 342,
+ 360, 344, 326, 255, 340, 552, 260, 338, 246, 552,
+ 197, 364, 192, 352, 382, 348, 186, 552, 420, 552,
+ 423, 184, 141, 437, 421, 447, 79, 476, 346, 552,
+ 453, 552, 515, 517, 519, 521, 523, 525, 71, 527,
+ 529, 531, 533, 535, 537, 539, 541, 543, 545, 547,
+ 549
+ } ;
+
+static yyconst flex_int16_t yy_def[182] =
+ { 0,
+ 162, 1, 163, 163, 164, 164, 165, 165, 162, 166,
+ 167, 162, 167, 167, 167, 167, 167, 167, 162, 166,
+ 167, 167, 167, 168, 168, 167, 167, 167, 162, 169,
+ 162, 170, 162, 20, 167, 162, 167, 167, 167, 167,
+ 167, 171, 19, 20, 20, 20, 20, 167, 167, 167,
+ 167, 167, 25, 25, 167, 167, 28, 28, 167, 167,
+ 167, 167, 167, 167, 167, 169, 162, 170, 162, 170,
+ 162, 171, 45, 25, 167, 167, 167, 167, 167, 167,
+ 167, 167, 167, 167, 20, 25, 167, 167, 167, 167,
+ 167, 167, 172, 173, 167, 167, 167, 167, 167, 167,
+
+ 25, 167, 174, 175, 167, 167, 167, 172, 162, 173,
+ 162, 167, 167, 167, 167, 167, 167, 25, 167, 174,
+ 162, 175, 162, 176, 177, 167, 178, 167, 167, 167,
+ 167, 167, 25, 167, 176, 162, 177, 167, 178, 162,
+ 179, 167, 180, 167, 162, 167, 179, 162, 167, 162,
+ 167, 180, 167, 181, 167, 167, 167, 181, 167, 162,
+ 167, 0, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162
+ } ;
+
+static yyconst flex_int16_t yy_nxt[592] =
+ { 0,
+ 10, 11, 12, 13, 14, 15, 16, 17, 16, 16,
+ 18, 19, 20, 20, 21, 22, 23, 24, 24, 24,
+ 24, 24, 25, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 26, 27,
+ 31, 31, 36, 28, 37, 36, 36, 32, 32, 35,
+ 36, 35, 35, 35, 35, 35, 35, 35, 35, 38,
+ 36, 36, 35, 35, 35, 36, 40, 36, 39, 36,
+ 36, 66, 48, 49, 41, 42, 56, 36, 55, 53,
+ 57, 36, 50, 51, 52, 101, 35, 34, 35, 36,
+ 35, 35, 35, 35, 35, 35, 35, 35, 43, 43,
+
+ 34, 35, 35, 35, 34, 34, 44, 45, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 44, 34, 45, 35, 35, 36, 35, 35,
+ 35, 35, 35, 35, 35, 35, 46, 46, 46, 35,
+ 35, 35, 69, 36, 47, 37, 36, 53, 74, 70,
+ 71, 34, 34, 34, 56, 36, 36, 36, 57, 34,
+ 47, 36, 36, 35, 34, 35, 36, 35, 35, 35,
+ 35, 35, 35, 35, 35, 34, 34, 75, 35, 35,
+ 35, 81, 36, 80, 53, 36, 36, 86, 148, 83,
+ 34, 34, 34, 34, 36, 36, 129, 36, 34, 148,
+
+ 36, 98, 35, 34, 35, 36, 35, 35, 35, 35,
+ 35, 35, 35, 35, 34, 82, 84, 35, 35, 35,
+ 34, 34, 34, 85, 69, 76, 54, 77, 34, 69,
+ 78, 162, 162, 36, 36, 79, 70, 71, 36, 85,
+ 36, 35, 58, 36, 34, 36, 39, 36, 140, 36,
+ 36, 36, 133, 53, 36, 87, 145, 36, 88, 36,
+ 90, 36, 36, 59, 60, 89, 36, 61, 62, 99,
+ 92, 104, 63, 36, 97, 91, 64, 65, 73, 73,
+ 73, 100, 106, 102, 73, 105, 34, 107, 73, 73,
+ 73, 73, 34, 34, 34, 103, 36, 36, 36, 36,
+
+ 34, 36, 34, 93, 93, 94, 93, 93, 93, 93,
+ 93, 93, 93, 93, 36, 36, 34, 93, 93, 93,
+ 112, 113, 36, 36, 119, 95, 36, 117, 125, 36,
+ 36, 36, 96, 36, 36, 114, 36, 36, 115, 36,
+ 36, 93, 136, 116, 36, 124, 36, 159, 160, 53,
+ 36, 127, 128, 126, 36, 131, 130, 134, 132, 129,
+ 36, 141, 36, 143, 146, 149, 150, 140, 138, 142,
+ 142, 142, 36, 136, 144, 151, 151, 151, 155, 123,
+ 121, 153, 35, 145, 36, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 154,
+
+ 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
+ 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
+ 35, 149, 150, 36, 149, 150, 111, 109, 123, 121,
+ 118, 156, 156, 156, 151, 151, 151, 35, 35, 36,
+ 35, 35, 35, 35, 35, 157, 35, 35, 159, 160,
+ 143, 35, 35, 35, 159, 160, 111, 109, 161, 161,
+ 161, 36, 67, 35, 161, 161, 161, 35, 36, 53,
+ 36, 36, 36, 36, 36, 35, 35, 35, 36, 35,
+ 35, 35, 35, 35, 157, 35, 35, 36, 36, 36,
+ 35, 35, 35, 36, 36, 36, 67, 36, 36, 162,
+
+ 29, 29, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 35, 29, 29, 30, 30, 33,
+ 33, 34, 34, 35, 35, 53, 53, 68, 68, 72,
+ 72, 108, 108, 110, 110, 120, 120, 122, 122, 135,
+ 135, 137, 137, 139, 139, 147, 147, 152, 152, 158,
+ 158, 9, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162
+
+ } ;
+
+static yyconst flex_int16_t yy_chk[592] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 5, 6, 26, 2, 11, 11, 14, 5, 6, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 14,
+ 21, 17, 10, 10, 10, 15, 17, 18, 15, 22,
+ 23, 169, 21, 21, 18, 18, 27, 27, 26, 86,
+ 27, 157, 22, 23, 23, 86, 10, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 32, 153, 20, 37, 37, 54, 54, 32,
+ 32, 34, 34, 34, 56, 56, 59, 62, 56, 34,
+ 20, 61, 64, 20, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 34, 43, 59, 24, 24,
+ 24, 62, 82, 61, 74, 63, 152, 74, 147, 64,
+ 44, 44, 44, 43, 143, 65, 114, 114, 44, 141,
+
+ 60, 82, 24, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 44, 63, 65, 25, 25, 25,
+ 47, 47, 47, 73, 68, 60, 25, 60, 47, 70,
+ 60, 68, 68, 75, 76, 60, 70, 70, 79, 73,
+ 77, 25, 28, 28, 47, 78, 28, 81, 139, 83,
+ 89, 84, 118, 118, 91, 75, 134, 134, 76, 87,
+ 77, 90, 137, 28, 28, 76, 92, 28, 28, 83,
+ 79, 89, 28, 88, 81, 78, 28, 28, 45, 45,
+ 45, 84, 91, 87, 45, 90, 45, 92, 45, 45,
+ 45, 45, 85, 85, 85, 88, 100, 102, 106, 95,
+
+ 85, 96, 45, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 97, 98, 85, 80, 80, 80,
+ 95, 96, 99, 105, 102, 80, 107, 100, 106, 112,
+ 115, 113, 80, 116, 117, 97, 119, 126, 98, 128,
+ 138, 80, 135, 99, 130, 105, 132, 159, 159, 133,
+ 146, 112, 113, 107, 144, 116, 115, 119, 117, 129,
+ 129, 128, 131, 130, 138, 142, 142, 127, 126, 129,
+ 129, 129, 125, 124, 132, 142, 142, 142, 146, 122,
+ 120, 144, 145, 145, 145, 145, 145, 145, 145, 145,
+ 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
+
+ 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
+ 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
+ 145, 149, 149, 155, 151, 151, 110, 108, 104, 103,
+ 101, 149, 149, 149, 151, 151, 151, 154, 154, 154,
+ 154, 154, 154, 154, 154, 154, 154, 154, 156, 156,
+ 155, 154, 154, 154, 161, 161, 94, 93, 156, 156,
+ 156, 72, 66, 58, 161, 161, 161, 57, 55, 53,
+ 52, 51, 50, 49, 48, 154, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 42, 41, 40,
+ 158, 158, 158, 39, 38, 35, 30, 16, 13, 9,
+
+ 8, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 158, 163, 163, 164, 164, 165,
+ 165, 166, 166, 167, 167, 168, 168, 170, 170, 171,
+ 171, 172, 172, 173, 173, 174, 174, 175, 175, 176,
+ 176, 177, 177, 178, 178, 179, 179, 180, 180, 181,
+ 181, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162
+
+ } ;
+
+#define YY_TRAILING_MASK 0x2000
+#define YY_TRAILING_HEAD_MASK 0x4000
+#define REJECT \
+{ \
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ \
+yy_cp = yyg->yy_full_match; /* restore poss. backed-over text */ \
+yyg->yy_lp = yyg->yy_full_lp; /* restore orig. accepting pos. */ \
+yyg->yy_state_ptr = yyg->yy_full_state; /* restore orig. state */ \
+yy_current_state = *yyg->yy_state_ptr; /* restore curr. state */ \
+++yyg->yy_lp; \
+goto find_rule; \
+}
+
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "glcpp/glcpp-lex.l"
+#line 2 "glcpp/glcpp-lex.l"
+/*
+ * 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 <ctype.h>
+
+#include "glcpp.h"
+#include "glcpp-parse.h"
+
+/* Flex annoyingly generates some functions without making them
+ * static. Let's declare them here. */
+int glcpp_get_column (yyscan_t yyscanner);
+void glcpp_set_column (int column_no , yyscan_t yyscanner);
+
+#define YY_NO_INPUT
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->first_column = yycolumn + 1; \
+ yylloc->first_line = yylineno; \
+ yycolumn += yyleng; \
+ } while(0);
+
+#define YY_USER_INIT \
+ do { \
+ yylineno = 1; \
+ yycolumn = 1; \
+ yylloc->source = 0; \
+ } while(0)
+
+#line 700 "glcpp/glcpp-lex.c"
+
+#define INITIAL 0
+#define DONE 1
+#define COMMENT 2
+#define UNREACHABLE 3
+
+#define YY_EXTRA_TYPE glcpp_parser_t *
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ yy_state_type *yy_state_buf;
+ yy_state_type *yy_state_ptr;
+ char *yy_full_match;
+ int yy_lp;
+
+ /* These are only needed for trailing context rules,
+ * but there's no conditional variable for that yet. */
+ int yy_looking_for_trail_begin;
+ int yy_full_lp;
+ int *yy_full_state;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ YYSTYPE * yylval_r;
+
+ YYLTYPE * yylloc_r;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+ /* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+ # define yylval yyg->yylval_r
+
+ # define yylloc yyg->yylloc_r
+
+int glcpp_lex_init (yyscan_t* scanner);
+
+int glcpp_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int glcpp_lex_destroy (yyscan_t yyscanner );
+
+int glcpp_get_debug (yyscan_t yyscanner );
+
+void glcpp_set_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE glcpp_get_extra (yyscan_t yyscanner );
+
+void glcpp_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *glcpp_get_in (yyscan_t yyscanner );
+
+void glcpp_set_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *glcpp_get_out (yyscan_t yyscanner );
+
+void glcpp_set_out (FILE * out_str ,yyscan_t yyscanner );
+
+int glcpp_get_leng (yyscan_t yyscanner );
+
+char *glcpp_get_text (yyscan_t yyscanner );
+
+int glcpp_get_lineno (yyscan_t yyscanner );
+
+void glcpp_set_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * glcpp_get_lval (yyscan_t yyscanner );
+
+void glcpp_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+ YYLTYPE *glcpp_get_lloc (yyscan_t yyscanner );
+
+ void glcpp_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int glcpp_wrap (yyscan_t yyscanner );
+#else
+extern int glcpp_wrap (yyscan_t yyscanner );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+ static void yy_push_state (int new_state ,yyscan_t yyscanner);
+
+ static void yy_pop_state (yyscan_t yyscanner );
+
+ static int yy_top_state (yyscan_t yyscanner );
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ unsigned n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int glcpp_lex \
+ (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int glcpp_lex \
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 76 "glcpp/glcpp-lex.l"
+
+
+ /* Single-line comments */
+#line 958 "glcpp/glcpp-lex.c"
+
+ yylval = yylval_param;
+
+ yylloc = yylloc_param;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ /* Create the reject buffer large enough to save one state per allowed character. */
+ if ( ! yyg->yy_state_buf )
+ yyg->yy_state_buf = (yy_state_type *)glcpp_alloc(YY_STATE_BUF_SIZE ,yyscanner);
+ if ( ! yyg->yy_state_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in glcpp_lex()" );
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ glcpp_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ glcpp__load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+ yy_current_state += YY_AT_BOL();
+
+ yyg->yy_state_ptr = yyg->yy_state_buf;
+ *yyg->yy_state_ptr++ = yy_current_state;
+
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 163 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *yyg->yy_state_ptr++ = yy_current_state;
+ ++yy_cp;
+ }
+ while ( yy_current_state != 162 );
+
+yy_find_action:
+ yy_current_state = *--yyg->yy_state_ptr;
+ yyg->yy_lp = yy_accept[yy_current_state];
+find_rule: /* we branch to this label when backing up */
+ for ( ; ; ) /* until we find what rule we matched */
+ {
+ if ( yyg->yy_lp && yyg->yy_lp < yy_accept[yy_current_state + 1] )
+ {
+ yy_act = yy_acclist[yyg->yy_lp];
+ if ( yy_act & YY_TRAILING_HEAD_MASK ||
+ yyg->yy_looking_for_trail_begin )
+ {
+ if ( yy_act == yyg->yy_looking_for_trail_begin )
+ {
+ yyg->yy_looking_for_trail_begin = 0;
+ yy_act &= ~YY_TRAILING_HEAD_MASK;
+ break;
+ }
+ }
+ else if ( yy_act & YY_TRAILING_MASK )
+ {
+ yyg->yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;
+ yyg->yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;
+ yyg->yy_full_match = yy_cp;
+ yyg->yy_full_state = yyg->yy_state_ptr;
+ yyg->yy_full_lp = yyg->yy_lp;
+ }
+ else
+ {
+ yyg->yy_full_match = yy_cp;
+ yyg->yy_full_state = yyg->yy_state_ptr;
+ yyg->yy_full_lp = yyg->yy_lp;
+ break;
+ }
+ ++yyg->yy_lp;
+ goto find_rule;
+ }
+ --yy_cp;
+ yy_current_state = *--yyg->yy_state_ptr;
+ yyg->yy_lp = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 79 "glcpp/glcpp-lex.l"
+{
+}
+ YY_BREAK
+/* Multi-line comments */
+case 2:
+YY_RULE_SETUP
+#line 83 "glcpp/glcpp-lex.l"
+{ yy_push_state(COMMENT, yyscanner); }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 84 "glcpp/glcpp-lex.l"
+
+ YY_BREAK
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+#line 85 "glcpp/glcpp-lex.l"
+{ yylineno++; yycolumn = 0; return NEWLINE; }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 86 "glcpp/glcpp-lex.l"
+
+ YY_BREAK
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+#line 87 "glcpp/glcpp-lex.l"
+{ yylineno++; yycolumn = 0; return NEWLINE; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 88 "glcpp/glcpp-lex.l"
+{
+ yy_pop_state(yyscanner);
+ if (yyextra->space_tokens)
+ return SPACE;
+}
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 94 "glcpp/glcpp-lex.l"
+{
+ yylval->str = talloc_strdup (yyextra, yytext);
+ yyextra->space_tokens = 0;
+ return HASH_VERSION;
+}
+ YY_BREAK
+/* glcpp doesn't handle #extension, #version, or #pragma directives.
+ * Simply pass them through to the main compiler's lexer/parser. */
+case 9:
+YY_RULE_SETUP
+#line 102 "glcpp/glcpp-lex.l"
+{
+ yylval->str = talloc_strdup (yyextra, yytext);
+ yylineno++;
+ yycolumn = 0;
+ return OTHER;
+}
+ YY_BREAK
+case 10:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 109 "glcpp/glcpp-lex.l"
+{
+ /* 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);
+}
+ YY_BREAK
+case 11:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 125 "glcpp/glcpp-lex.l"
+{
+ /* 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;
+}
+ YY_BREAK
+case 12:
+/* rule 12 can match eol */
+YY_RULE_SETUP
+#line 140 "glcpp/glcpp-lex.l"
+{
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IFDEF;
+}
+ YY_BREAK
+case 13:
+/* rule 13 can match eol */
+YY_RULE_SETUP
+#line 146 "glcpp/glcpp-lex.l"
+{
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IFNDEF;
+}
+ YY_BREAK
+case 14:
+/* rule 14 can match eol */
+YY_RULE_SETUP
+#line 152 "glcpp/glcpp-lex.l"
+{
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IF;
+}
+ YY_BREAK
+case 15:
+/* rule 15 can match eol */
+YY_RULE_SETUP
+#line 158 "glcpp/glcpp-lex.l"
+{
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_ELIF;
+}
+ YY_BREAK
+case 16:
+/* rule 16 can match eol */
+YY_RULE_SETUP
+#line 164 "glcpp/glcpp-lex.l"
+{
+ yyextra->space_tokens = 0;
+ return HASH_ELSE;
+}
+ YY_BREAK
+case 17:
+/* rule 17 can match eol */
+YY_RULE_SETUP
+#line 169 "glcpp/glcpp-lex.l"
+{
+ yyextra->space_tokens = 0;
+ return HASH_ENDIF;
+}
+ YY_BREAK
+/* When skipping (due to an #if 0 or similar) consume anything
+ * up to a newline. We do this with less priority 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. */
+case 18:
+/* rule 18 can match eol */
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 182 "glcpp/glcpp-lex.l"
+{
+ /* 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;
+ }
+}
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 194 "glcpp/glcpp-lex.l"
+{
+ char *p;
+ for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
+ p += 5; /* skip "error" */
+ glcpp_error(yylloc, yyextra, "#error%s", p);
+}
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 201 "glcpp/glcpp-lex.l"
+{
+ yyextra->space_tokens = 0;
+ return HASH_DEFINE_FUNC;
+}
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 206 "glcpp/glcpp-lex.l"
+{
+ yyextra->space_tokens = 0;
+ return HASH_DEFINE_OBJ;
+}
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 211 "glcpp/glcpp-lex.l"
+{
+ yyextra->space_tokens = 0;
+ return HASH_UNDEF;
+}
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 216 "glcpp/glcpp-lex.l"
+{
+ yyextra->space_tokens = 0;
+ return HASH;
+}
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 221 "glcpp/glcpp-lex.l"
+{
+ yylval->str = talloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 226 "glcpp/glcpp-lex.l"
+{
+ yylval->str = talloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 231 "glcpp/glcpp-lex.l"
+{
+ yylval->str = talloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 236 "glcpp/glcpp-lex.l"
+{
+ return LEFT_SHIFT;
+}
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 240 "glcpp/glcpp-lex.l"
+{
+ return RIGHT_SHIFT;
+}
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 244 "glcpp/glcpp-lex.l"
+{
+ return LESS_OR_EQUAL;
+}
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 248 "glcpp/glcpp-lex.l"
+{
+ return GREATER_OR_EQUAL;
+}
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 252 "glcpp/glcpp-lex.l"
+{
+ return EQUAL;
+}
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 256 "glcpp/glcpp-lex.l"
+{
+ return NOT_EQUAL;
+}
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 260 "glcpp/glcpp-lex.l"
+{
+ return AND;
+}
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 264 "glcpp/glcpp-lex.l"
+{
+ return OR;
+}
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 268 "glcpp/glcpp-lex.l"
+{
+ return PASTE;
+}
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 272 "glcpp/glcpp-lex.l"
+{
+ return DEFINED;
+}
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 276 "glcpp/glcpp-lex.l"
+{
+ yylval->str = talloc_strdup (yyextra, yytext);
+ return IDENTIFIER;
+}
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 281 "glcpp/glcpp-lex.l"
+{
+ return yytext[0];
+}
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 285 "glcpp/glcpp-lex.l"
+{
+ yylval->str = talloc_strdup (yyextra, yytext);
+ return OTHER;
+}
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 290 "glcpp/glcpp-lex.l"
+{
+ if (yyextra->space_tokens) {
+ return SPACE;
+ }
+}
+ YY_BREAK
+case 41:
+/* rule 41 can match eol */
+YY_RULE_SETUP
+#line 296 "glcpp/glcpp-lex.l"
+{
+ yyextra->lexing_if = 0;
+ yylineno++;
+ yycolumn = 0;
+ return NEWLINE;
+}
+ YY_BREAK
+/* Handle missing newline at EOF. */
+case YY_STATE_EOF(INITIAL):
+#line 304 "glcpp/glcpp-lex.l"
+{
+ BEGIN DONE; /* Don't keep matching this rule forever. */
+ yyextra->lexing_if = 0;
+ return NEWLINE;
+}
+ YY_BREAK
+/* We don't actually use the UNREACHABLE start condition. We
+ only have this action here so that we can pretend to call some
+ generated functions, (to avoid "defined but not used"
+ warnings. */
+case 42:
+YY_RULE_SETUP
+#line 314 "glcpp/glcpp-lex.l"
+{
+ unput('.');
+ yy_top_state(yyextra);
+}
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 319 "glcpp/glcpp-lex.l"
+ECHO;
+ YY_BREAK
+#line 1475 "glcpp/glcpp-lex.c"
+ case YY_STATE_EOF(DONE):
+ case YY_STATE_EOF(COMMENT):
+ case YY_STATE_EOF(UNREACHABLE):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * glcpp_lex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( glcpp_wrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of glcpp_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ glcpp_restart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) glcpp_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+ yy_current_state += YY_AT_BOL();
+
+ yyg->yy_state_ptr = yyg->yy_state_buf;
+ *yyg->yy_state_ptr++ = yy_current_state;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 163 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *yyg->yy_state_ptr++ = yy_current_state;
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+
+ register YY_CHAR yy_c = 1;
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 163 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 162);
+ if ( ! yy_is_jam )
+ *yyg->yy_state_ptr++ = yy_current_state;
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
+{
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yyg->yy_hold_char;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yyg->yy_n_chars + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ yyg->yytext_ptr = yy_bp;
+ yyg->yy_hold_char = *yy_cp;
+ yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ glcpp_restart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( glcpp_wrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void glcpp_restart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ glcpp_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ glcpp__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ glcpp__load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void glcpp__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * glcpp_pop_buffer_state();
+ * glcpp_push_buffer_state(new_buffer);
+ */
+ glcpp_ensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ glcpp__load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (glcpp_wrap()) processing, but the only time this flag
+ * is looked at is after glcpp_wrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void glcpp__load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE glcpp__create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) glcpp_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in glcpp__create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) glcpp_alloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in glcpp__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ glcpp__init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with glcpp__create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void glcpp__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ glcpp_free((void *) b->yy_ch_buf ,yyscanner );
+
+ glcpp_free((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a glcpp_restart() or at EOF.
+ */
+ static void glcpp__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ glcpp__flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then glcpp__init_buffer was _probably_
+ * called from glcpp_restart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void glcpp__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ glcpp__load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void glcpp_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ glcpp_ensure_buffer_stack(yyscanner);
+
+ /* This block is copied from glcpp__switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from glcpp__switch_to_buffer. */
+ glcpp__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void glcpp_pop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ glcpp__delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ glcpp__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void glcpp_ensure_buffer_stack (yyscan_t yyscanner)
+{
+ int num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)glcpp_alloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in glcpp_ensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)glcpp_realloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in glcpp_ensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE glcpp__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) glcpp_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in glcpp__scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ glcpp__switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to glcpp_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * glcpp__scan_bytes() instead.
+ */
+YY_BUFFER_STATE glcpp__scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return glcpp__scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to glcpp_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE glcpp__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) glcpp_alloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in glcpp__scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = glcpp__scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in glcpp__scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+ static void yy_push_state (int new_state , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yyg->yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yyg->yy_start_stack_depth * sizeof( int );
+
+ if ( ! yyg->yy_start_stack )
+ yyg->yy_start_stack = (int *) glcpp_alloc(new_size ,yyscanner );
+
+ else
+ yyg->yy_start_stack = (int *) glcpp_realloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
+
+ if ( ! yyg->yy_start_stack )
+ YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+ }
+
+ yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+}
+
+ static void yy_pop_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( --yyg->yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]);
+}
+
+ static int yy_top_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1];
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE glcpp_get_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int glcpp_get_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int glcpp_get_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *glcpp_get_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *glcpp_get_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int glcpp_get_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *glcpp_get_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void glcpp_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void glcpp_set_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "glcpp_set_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void glcpp_set_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "glcpp_set_column called with no buffer" , yyscanner);
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see glcpp__switch_to_buffer
+ */
+void glcpp_set_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void glcpp_set_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int glcpp_get_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void glcpp_set_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * glcpp_get_lval (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylval;
+}
+
+void glcpp_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *glcpp_get_lloc (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylloc;
+}
+
+void glcpp_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* glcpp_lex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int glcpp_lex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) glcpp_alloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* glcpp_lex_init_extra has the same functionality as glcpp_lex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to glcpp_alloc in
+ * the yyextra field.
+ */
+
+int glcpp_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ glcpp_set_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) glcpp_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ glcpp_set_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from glcpp_lex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+ yyg->yy_state_buf = 0;
+ yyg->yy_state_ptr = 0;
+ yyg->yy_full_match = 0;
+ yyg->yy_lp = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * glcpp_lex_init()
+ */
+ return 0;
+}
+
+/* glcpp_lex_destroy is for both reentrant and non-reentrant scanners. */
+int glcpp_lex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ glcpp__delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ glcpp_pop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ glcpp_free(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ glcpp_free(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ glcpp_free ( yyg->yy_state_buf , yyscanner);
+ yyg->yy_state_buf = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * glcpp_lex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ glcpp_free ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *glcpp_alloc (yy_size_t size , yyscan_t yyscanner)
+{
+ return (void *) malloc( size );
+}
+
+void *glcpp_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void glcpp_free (void * ptr , yyscan_t yyscanner)
+{
+ free( (char *) ptr ); /* see glcpp_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 319 "glcpp/glcpp-lex.l"
+
+
+
+void
+glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
+{
+ glcpp__scan_string(shader,parser->scanner);
+}
+
diff --git a/mesalib/src/glsl/glcpp/glcpp-lex.l b/mesalib/src/glsl/glcpp/glcpp-lex.l index 8eb84ed13..0df10c553 100644 --- a/mesalib/src/glsl/glcpp/glcpp-lex.l +++ b/mesalib/src/glsl/glcpp/glcpp-lex.l @@ -1,325 +1,325 @@ -%{ -/* - * 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 <ctype.h> - -#include "glcpp.h" -#include "glcpp-parse.h" - -/* Flex annoyingly generates some functions without making them - * static. Let's declare them here. */ -int glcpp_get_column (yyscan_t yyscanner); -void glcpp_set_column (int column_no , yyscan_t yyscanner); - -#define YY_NO_INPUT - -#define YY_USER_ACTION \ - do { \ - yylloc->first_column = yycolumn + 1; \ - yylloc->first_line = yylineno; \ - yycolumn += yyleng; \ - } while(0); - -#define YY_USER_INIT \ - do { \ - yylineno = 1; \ - yycolumn = 1; \ - yylloc->source = 0; \ - } while(0) -%} - -%option bison-bridge bison-locations reentrant noyywrap -%option extra-type="glcpp_parser_t *" -%option prefix="glcpp_" -%option stack -%option never-interactive - -%x DONE COMMENT UNREACHABLE - -SPACE [[:space:]] -NONSPACE [^[:space:]] -NEWLINE [\n] -HSPACE [ \t] -HASH ^{HSPACE}*#{HSPACE}* -IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* -PUNCTUATION [][(){}.&*~!/%<>^|;,=+-] -OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+ - -DIGITS [0-9][0-9]* -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]* { -} - - /* 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; -} - -{HASH}version { - yylval->str = talloc_strdup (yyextra, yytext); - yyextra->space_tokens = 0; - return HASH_VERSION; -} - - /* glcpp doesn't handle #extension, #version, or #pragma directives. - * Simply pass them through to the main compiler's lexer/parser. */ -{HASH}(extension|pragma)[^\n]+ { - yylval->str = talloc_strdup (yyextra, yytext); - yylineno++; - yycolumn = 0; - return OTHER; -} - -{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ { - /* 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{HSPACE}+{DIGITS}{HSPACE}*$ { - /* 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; -} - -{HASH}ifdef/.*\n { - yyextra->lexing_if = 1; - yyextra->space_tokens = 0; - return HASH_IFDEF; -} - -{HASH}ifndef/.*\n { - yyextra->lexing_if = 1; - yyextra->space_tokens = 0; - return HASH_IFNDEF; -} - -{HASH}if/[^_a-zA-Z0-9].*\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 with less priority 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}error.* { - char *p; - for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */ - p += 5; /* skip "error" */ - glcpp_error(yylloc, yyextra, "#error%s", p); -} - -{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 = talloc_strdup (yyextra, yytext); - return INTEGER_STRING; -} - -{OCTAL_INTEGER} { - yylval->str = talloc_strdup (yyextra, yytext); - return INTEGER_STRING; -} - -{HEXADECIMAL_INTEGER} { - yylval->str = talloc_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 = talloc_strdup (yyextra, yytext); - return IDENTIFIER; -} - -{PUNCTUATION} { - return yytext[0]; -} - -{OTHER}+ { - yylval->str = talloc_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; -} - - /* We don't actually use the UNREACHABLE start condition. We - only have this action here so that we can pretend to call some - generated functions, (to avoid "defined but not used" - warnings. */ -<UNREACHABLE>. { - unput('.'); - yy_top_state(yyextra); -} - -%% - -void -glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader) -{ - yy_scan_string(shader, parser->scanner); -} +%{
+/*
+ * 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 <ctype.h>
+
+#include "glcpp.h"
+#include "glcpp-parse.h"
+
+/* Flex annoyingly generates some functions without making them
+ * static. Let's declare them here. */
+int glcpp_get_column (yyscan_t yyscanner);
+void glcpp_set_column (int column_no , yyscan_t yyscanner);
+
+#define YY_NO_INPUT
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->first_column = yycolumn + 1; \
+ yylloc->first_line = yylineno; \
+ yycolumn += yyleng; \
+ } while(0);
+
+#define YY_USER_INIT \
+ do { \
+ yylineno = 1; \
+ yycolumn = 1; \
+ yylloc->source = 0; \
+ } while(0)
+%}
+
+%option bison-bridge bison-locations reentrant noyywrap
+%option extra-type="glcpp_parser_t *"
+%option prefix="glcpp_"
+%option stack
+%option never-interactive
+
+%x DONE COMMENT UNREACHABLE
+
+SPACE [[:space:]]
+NONSPACE [^[:space:]]
+NEWLINE [\n]
+HSPACE [ \t]
+HASH ^{HSPACE}*#{HSPACE}*
+IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
+PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
+OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
+
+DIGITS [0-9][0-9]*
+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]* {
+}
+
+ /* Multi-line comments */
+"/*" { yy_push_state(COMMENT, yyscanner); }
+<COMMENT>[^*\n]*
+<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
+<COMMENT>"*"+[^*/\n]*
+<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
+<COMMENT>"*"+"/" {
+ yy_pop_state(yyscanner);
+ if (yyextra->space_tokens)
+ return SPACE;
+}
+
+{HASH}version {
+ yylval->str = talloc_strdup (yyextra, yytext);
+ yyextra->space_tokens = 0;
+ return HASH_VERSION;
+}
+
+ /* glcpp doesn't handle #extension, #version, or #pragma directives.
+ * Simply pass them through to the main compiler's lexer/parser. */
+{HASH}(extension|pragma)[^\n]+ {
+ yylval->str = talloc_strdup (yyextra, yytext);
+ yylineno++;
+ yycolumn = 0;
+ return OTHER;
+}
+
+{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
+ /* 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{HSPACE}+{DIGITS}{HSPACE}*$ {
+ /* 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;
+}
+
+{HASH}ifdef/.*\n {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IFDEF;
+}
+
+{HASH}ifndef/.*\n {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IFNDEF;
+}
+
+{HASH}if/[^_a-zA-Z0-9].*\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 with less priority 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}error.* {
+ char *p;
+ for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
+ p += 5; /* skip "error" */
+ glcpp_error(yylloc, yyextra, "#error%s", p);
+}
+
+{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 = talloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+{OCTAL_INTEGER} {
+ yylval->str = talloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+{HEXADECIMAL_INTEGER} {
+ yylval->str = talloc_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 = talloc_strdup (yyextra, yytext);
+ return IDENTIFIER;
+}
+
+{PUNCTUATION} {
+ return yytext[0];
+}
+
+{OTHER}+ {
+ yylval->str = talloc_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;
+}
+
+ /* We don't actually use the UNREACHABLE start condition. We
+ only have this action here so that we can pretend to call some
+ generated functions, (to avoid "defined but not used"
+ warnings. */
+<UNREACHABLE>. {
+ unput('.');
+ yy_top_state(yyextra);
+}
+
+%%
+
+void
+glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
+{
+ yy_scan_string(shader, parser->scanner);
+}
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.c b/mesalib/src/glsl/glcpp/glcpp-parse.c index 1773ca5c1..507b7f97b 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.c +++ b/mesalib/src/glsl/glcpp/glcpp-parse.c @@ -1,4184 +1,4194 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2009, 2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 1 - - - -/* Copy the first part of user declarations. */ - -/* Line 189 of yacc.c */ -#line 1 "glcpp/glcpp-parse.y" - -/* - * 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 <string.h> -#include <assert.h> -#include <inttypes.h> - -#include "glcpp.h" -#include "main/core.h" /* for struct gl_extensions */ -#include "main/mtypes.h" /* for gl_api enum */ - -#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 int -_string_list_equal (string_list_t *a, string_list_t *b); - -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 int -_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b); - -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_if (glcpp_parser_t *parser, int type, token_list_t *list); - -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); - -static void -add_builtin_define(glcpp_parser_t *parser, const char *name, int value); - - - -/* Line 189 of yacc.c */ -#line 223 "glcpp/glcpp-parse.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - COMMA_FINAL = 258, - DEFINED = 259, - ELIF_EXPANDED = 260, - HASH = 261, - HASH_DEFINE_FUNC = 262, - HASH_DEFINE_OBJ = 263, - HASH_ELIF = 264, - HASH_ELSE = 265, - HASH_ENDIF = 266, - HASH_IF = 267, - HASH_IFDEF = 268, - HASH_IFNDEF = 269, - HASH_UNDEF = 270, - HASH_VERSION = 271, - IDENTIFIER = 272, - IF_EXPANDED = 273, - INTEGER = 274, - INTEGER_STRING = 275, - NEWLINE = 276, - OTHER = 277, - PLACEHOLDER = 278, - SPACE = 279, - PASTE = 280, - OR = 281, - AND = 282, - NOT_EQUAL = 283, - EQUAL = 284, - GREATER_OR_EQUAL = 285, - LESS_OR_EQUAL = 286, - RIGHT_SHIFT = 287, - LEFT_SHIFT = 288, - UNARY = 289 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -/* Copy the second part of user declarations. */ - - -/* Line 264 of yacc.c */ -#line 311 "glcpp/glcpp-parse.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 606 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 57 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 17 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 101 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 162 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 289 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 47, 2, 2, 2, 43, 30, 2, - 45, 46, 41, 39, 49, 40, 54, 42, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, - 33, 56, 34, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 50, 2, 51, 29, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 52, 28, 53, 48, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 31, 32, 35, 36, 37, 38, 44 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 4, 7, 9, 11, 13, 16, 20, - 24, 29, 36, 44, 48, 52, 55, 60, 65, 69, - 72, 75, 78, 82, 85, 87, 89, 91, 95, 99, - 103, 107, 111, 115, 119, 123, 127, 131, 135, 139, - 143, 147, 151, 155, 159, 163, 166, 169, 172, 175, - 179, 181, 185, 187, 190, 193, 194, 196, 197, 199, - 202, 207, 209, 211, 214, 216, 219, 221, 223, 225, - 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, - 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, - 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, - 287, 289 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 58, 0, -1, -1, 58, 59, -1, 61, -1, 65, - -1, 60, -1, 6, 66, -1, 18, 63, 21, -1, - 5, 63, 21, -1, 8, 17, 67, 21, -1, 7, - 17, 45, 46, 67, 21, -1, 7, 17, 45, 64, - 46, 67, 21, -1, 15, 17, 21, -1, 12, 70, - 21, -1, 12, 21, -1, 13, 17, 68, 21, -1, - 14, 17, 68, 21, -1, 9, 70, 21, -1, 9, - 21, -1, 10, 21, -1, 11, 21, -1, 16, 62, - 21, -1, 6, 21, -1, 20, -1, 19, -1, 62, - -1, 63, 26, 63, -1, 63, 27, 63, -1, 63, - 28, 63, -1, 63, 29, 63, -1, 63, 30, 63, - -1, 63, 31, 63, -1, 63, 32, 63, -1, 63, - 35, 63, -1, 63, 36, 63, -1, 63, 34, 63, - -1, 63, 33, 63, -1, 63, 37, 63, -1, 63, - 38, 63, -1, 63, 40, 63, -1, 63, 39, 63, - -1, 63, 43, 63, -1, 63, 42, 63, -1, 63, - 41, 63, -1, 47, 63, -1, 48, 63, -1, 40, - 63, -1, 39, 63, -1, 45, 63, 46, -1, 17, - -1, 64, 49, 17, -1, 21, -1, 71, 21, -1, - 71, 21, -1, -1, 71, -1, -1, 71, -1, 4, - 17, -1, 4, 45, 17, 46, -1, 72, -1, 69, - -1, 70, 69, -1, 72, -1, 71, 72, -1, 17, - -1, 20, -1, 73, -1, 22, -1, 24, -1, 50, - -1, 51, -1, 45, -1, 46, -1, 52, -1, 53, - -1, 54, -1, 30, -1, 41, -1, 39, -1, 40, - -1, 48, -1, 47, -1, 42, -1, 43, -1, 38, - -1, 37, -1, 33, -1, 34, -1, 36, -1, 35, - -1, 32, -1, 31, -1, 29, -1, 28, -1, 27, - -1, 26, -1, 55, -1, 49, -1, 56, -1, 25, - -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 188, 188, 190, 194, 197, 202, 203, 207, 210, - 216, 219, 222, 225, 233, 252, 262, 267, 272, 291, - 306, 309, 312, 325, 329, 338, 343, 344, 347, 350, - 353, 356, 359, 362, 365, 368, 371, 374, 377, 380, - 383, 386, 389, 392, 395, 398, 401, 404, 407, 410, - 416, 421, 429, 430, 434, 440, 441, 444, 446, 453, - 457, 461, 466, 472, 480, 486, 494, 498, 502, 506, - 510, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, - 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, - 546, 547 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "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", "HASH_VERSION", "IDENTIFIER", "IF_EXPANDED", - "INTEGER", "INTEGER_STRING", "NEWLINE", "OTHER", "PLACEHOLDER", "SPACE", - "PASTE", "OR", "AND", "'|'", "'^'", "'&'", "NOT_EQUAL", "EQUAL", "'<'", - "'>'", "GREATER_OR_EQUAL", "LESS_OR_EQUAL", "RIGHT_SHIFT", "LEFT_SHIFT", - "'+'", "'-'", "'*'", "'/'", "'%'", "UNARY", "'('", "')'", "'!'", "'~'", - "','", "'['", "']'", "'{'", "'}'", "'.'", "';'", "'='", "$accept", - "input", "line", "expanded_line", "control_line", "integer_constant", - "expression", "identifier_list", "text_line", "non_directive", - "replacement_list", "junk", "conditional_token", "conditional_tokens", - "pp_tokens", "preprocessing_token", "operator", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 124, 94, - 38, 283, 284, 60, 62, 285, 286, 287, 288, 43, - 45, 42, 47, 37, 289, 40, 41, 33, 126, 44, - 91, 93, 123, 125, 46, 59, 61 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 57, 58, 58, 59, 59, 59, 59, 60, 60, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 62, 62, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 64, 64, 65, 65, 66, 67, 67, 68, 68, 69, - 69, 69, 70, 70, 71, 71, 72, 72, 72, 72, - 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 0, 2, 1, 1, 1, 2, 3, 3, - 4, 6, 7, 3, 3, 2, 4, 4, 3, 2, - 2, 2, 3, 2, 1, 1, 1, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, - 1, 3, 1, 2, 2, 0, 1, 0, 1, 2, - 4, 1, 1, 2, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 66, 0, 67, 52, 69, - 70, 101, 97, 96, 95, 94, 78, 93, 92, 88, - 89, 91, 90, 87, 86, 80, 81, 79, 84, 85, - 73, 74, 83, 82, 99, 71, 72, 75, 76, 77, - 98, 100, 3, 6, 4, 5, 0, 64, 68, 25, - 24, 0, 0, 0, 0, 0, 26, 0, 23, 7, - 0, 0, 55, 0, 19, 62, 0, 61, 20, 21, - 15, 0, 57, 57, 0, 0, 0, 53, 65, 48, - 47, 0, 45, 46, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 0, 0, 56, 59, 0, 18, - 63, 14, 0, 58, 0, 13, 22, 8, 49, 27, - 28, 29, 30, 31, 32, 33, 37, 36, 34, 35, - 38, 39, 41, 40, 44, 43, 42, 50, 55, 0, - 10, 0, 16, 17, 0, 55, 0, 60, 11, 0, - 51, 12 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 1, 52, 53, 54, 66, 67, 149, 55, 69, - 115, 122, 75, 76, 116, 57, 58 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -147 -static const yytype_int16 yypact[] = -{ - -147, 112, -147, 28, -10, 55, 62, 152, -15, 59, - 192, 85, 86, 87, 51, -147, 28, -147, -147, -147, - -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, - -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, - -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, - -147, -147, -147, -147, -147, -147, 312, -147, -147, -147, - -147, 28, 28, 28, 28, 28, -147, 428, -147, -147, - 352, 63, 392, 17, -147, -147, 232, -147, -147, -147, - -147, 272, 392, 392, 84, 89, 451, -147, -147, -147, - -147, 469, -147, -147, -147, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, -147, 60, 90, 392, -147, 96, -147, - -147, -147, 93, 392, 94, -147, -147, -147, -147, 489, - 505, 520, 534, 547, 558, 558, 18, 18, 18, 18, - 563, 563, 23, 23, -147, -147, -147, -147, 392, 32, - -147, 61, -147, -147, 110, 392, 118, -147, -147, 149, - -147, -147 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -147, -147, -147, -147, -147, 157, -11, -147, -147, -147, - -146, 92, -68, 200, 0, -7, -147 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 77, 56, 154, 77, 70, 86, 78, 15, 120, 159, - 17, 68, 19, 120, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 117, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 59, 60, 88, - 89, 90, 91, 92, 93, 106, 107, 108, 109, 110, - 111, 112, 118, 88, 110, 111, 112, 61, 62, 77, - 59, 60, 71, 63, 77, 64, 65, 147, 155, 72, - 79, 156, 123, 123, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 82, 83, 84, 125, 148, 157, 114, 88, - 126, 150, 2, 151, 152, 153, 88, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 158, 17, 18, 19, 160, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 161, 85, 17, 74, 19, 124, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 81, 0, 17, 80, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 119, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 121, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 87, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 113, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 0, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 94, - 0, 0, 0, 0, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 127, 0, 0, 0, 0, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 0, 0, 128, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 108, 109, 110, 111, 112 -}; - -static const yytype_int16 yycheck[] = -{ - 7, 1, 148, 10, 4, 16, 21, 17, 76, 155, - 20, 21, 22, 81, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 17, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 19, 20, 56, - 61, 62, 63, 64, 65, 37, 38, 39, 40, 41, - 42, 43, 45, 70, 41, 42, 43, 39, 40, 76, - 19, 20, 17, 45, 81, 47, 48, 17, 46, 17, - 21, 49, 82, 83, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 17, 17, 17, 21, 46, 46, 45, 116, - 21, 21, 0, 17, 21, 21, 123, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 21, 20, 21, 22, 17, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - 21, 14, 20, 21, 22, 83, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - 10, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, -1, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 21, - -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 21, -1, -1, -1, -1, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, -1, -1, 46, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 39, 40, 41, 42, 43 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 58, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 59, 60, 61, 65, 71, 72, 73, 19, - 20, 39, 40, 45, 47, 48, 62, 63, 21, 66, - 71, 17, 17, 4, 21, 69, 70, 72, 21, 21, - 21, 70, 17, 17, 17, 62, 63, 21, 72, 63, - 63, 63, 63, 63, 21, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 21, 45, 67, 71, 17, 45, 21, - 69, 21, 68, 71, 68, 21, 21, 21, 46, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 17, 46, 64, - 21, 17, 21, 21, 67, 46, 49, 46, 21, 67, - 17, 21 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, parser, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, parser) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, parser); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - glcpp_parser_t *parser; -#endif -{ - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (parser); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parser) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - glcpp_parser_t *parser; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, glcpp_parser_t *parser) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, parser) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - glcpp_parser_t *parser; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , parser); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, parser); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, glcpp_parser_t *parser) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, parser) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - glcpp_parser_t *parser; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (parser); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (glcpp_parser_t *parser); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (glcpp_parser_t *parser) -#else -int -yyparse (parser) - glcpp_parser_t *parser; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - yylsp = yyls; - -#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 1; -#endif - -/* User initialization code. */ - -/* Line 1251 of yacc.c */ -#line 155 "glcpp/glcpp-parse.y" -{ - yylloc.first_line = 1; - yylloc.first_column = 1; - yylloc.last_line = 1; - yylloc.last_column = 1; - yylloc.source = 0; -} - -/* Line 1251 of yacc.c */ -#line 1625 "glcpp/glcpp-parse.c" - yylsp[0] = yylloc; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: - -/* Line 1464 of yacc.c */ -#line 194 "glcpp/glcpp-parse.y" - { - glcpp_print(parser->output, "\n"); - ;} - break; - - case 5: - -/* Line 1464 of yacc.c */ -#line 197 "glcpp/glcpp-parse.y" - { - _glcpp_parser_print_expanded_token_list (parser, (yyvsp[(1) - (1)].token_list)); - glcpp_print(parser->output, "\n"); - talloc_free ((yyvsp[(1) - (1)].token_list)); - ;} - break; - - case 8: - -/* Line 1464 of yacc.c */ -#line 207 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), (yyvsp[(2) - (3)].ival)); - ;} - break; - - case 9: - -/* Line 1464 of yacc.c */ -#line 210 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]), "elif", (yyvsp[(2) - (3)].ival)); - ;} - break; - - case 10: - -/* Line 1464 of yacc.c */ -#line 216 "glcpp/glcpp-parse.y" - { - _define_object_macro (parser, & (yylsp[(2) - (4)]), (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].token_list)); - ;} - break; - - case 11: - -/* Line 1464 of yacc.c */ -#line 219 "glcpp/glcpp-parse.y" - { - _define_function_macro (parser, & (yylsp[(2) - (6)]), (yyvsp[(2) - (6)].str), NULL, (yyvsp[(5) - (6)].token_list)); - ;} - break; - - case 12: - -/* Line 1464 of yacc.c */ -#line 222 "glcpp/glcpp-parse.y" - { - _define_function_macro (parser, & (yylsp[(2) - (7)]), (yyvsp[(2) - (7)].str), (yyvsp[(4) - (7)].string_list), (yyvsp[(6) - (7)].token_list)); - ;} - break; - - case 13: - -/* Line 1464 of yacc.c */ -#line 225 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (3)].str)); - if (macro) { - hash_table_remove (parser->defines, (yyvsp[(2) - (3)].str)); - talloc_free (macro); - } - talloc_free ((yyvsp[(2) - (3)].str)); - ;} - break; - - case 14: - -/* Line 1464 of yacc.c */ -#line 233 "glcpp/glcpp-parse.y" - { - /* Be careful to only evaluate the 'if' expression if - * we are not skipping. When we are skipping, we - * simply push a new 0-valued 'if' onto the skip - * stack. - * - * This avoids generating diagnostics for invalid - * expressions that are being skipped. */ - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - _glcpp_parser_expand_if (parser, IF_EXPANDED, (yyvsp[(2) - (3)].token_list)); - } - else - { - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), 0); - parser->skip_stack->type = SKIP_TO_ENDIF; - } - ;} - break; - - case 15: - -/* Line 1464 of yacc.c */ -#line 252 "glcpp/glcpp-parse.y" - { - /* #if without an expression is only an error if we - * are not skipping */ - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - glcpp_error(& (yylsp[(1) - (2)]), parser, "#if with no expression"); - } - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (2)]), 0); - ;} - break; - - case 16: - -/* Line 1464 of yacc.c */ -#line 262 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str)); - talloc_free ((yyvsp[(2) - (4)].str)); - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro != NULL); - ;} - break; - - case 17: - -/* Line 1464 of yacc.c */ -#line 267 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str)); - talloc_free ((yyvsp[(2) - (4)].str)); - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro == NULL); - ;} - break; - - case 18: - -/* Line 1464 of yacc.c */ -#line 272 "glcpp/glcpp-parse.y" - { - /* Be careful to only evaluate the 'elif' expression - * if we are not skipping. When we are skipping, we - * simply change to a 0-valued 'elif' on the skip - * stack. - * - * This avoids generating diagnostics for invalid - * expressions that are being skipped. */ - if (parser->skip_stack && - parser->skip_stack->type == SKIP_TO_ELSE) - { - _glcpp_parser_expand_if (parser, ELIF_EXPANDED, (yyvsp[(2) - (3)].token_list)); - } - else - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]), - "elif", 0); - } - ;} - break; - - case 19: - -/* Line 1464 of yacc.c */ -#line 291 "glcpp/glcpp-parse.y" - { - /* #elif without an expression is an error unless we - * are skipping. */ - if (parser->skip_stack && - parser->skip_stack->type == SKIP_TO_ELSE) - { - glcpp_error(& (yylsp[(1) - (2)]), parser, "#elif with no expression"); - } - else - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]), - "elif", 0); - glcpp_warning(& (yylsp[(1) - (2)]), parser, "ignoring illegal #elif without expression"); - } - ;} - break; - - case 20: - -/* Line 1464 of yacc.c */ -#line 306 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]), "else", 1); - ;} - break; - - case 21: - -/* Line 1464 of yacc.c */ -#line 309 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_pop (parser, & (yylsp[(1) - (2)])); - ;} - break; - - case 22: - -/* Line 1464 of yacc.c */ -#line 312 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, "__VERSION__"); - if (macro) { - hash_table_remove (parser->defines, "__VERSION__"); - talloc_free (macro); - } - add_builtin_define (parser, "__VERSION__", (yyvsp[(2) - (3)].ival)); - - if ((yyvsp[(2) - (3)].ival) == 100) - add_builtin_define (parser, "GL_ES", 1); - - glcpp_printf(parser->output, "#version %" PRIiMAX, (yyvsp[(2) - (3)].ival)); - ;} - break; - - case 24: - -/* Line 1464 of yacc.c */ -#line 329 "glcpp/glcpp-parse.y" - { - if (strlen ((yyvsp[(1) - (1)].str)) >= 3 && strncmp ((yyvsp[(1) - (1)].str), "0x", 2) == 0) { - (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str) + 2, NULL, 16); - } else if ((yyvsp[(1) - (1)].str)[0] == '0') { - (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 8); - } else { - (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 10); - } - ;} - break; - - case 25: - -/* Line 1464 of yacc.c */ -#line 338 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (1)].ival); - ;} - break; - - case 27: - -/* Line 1464 of yacc.c */ -#line 344 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) || (yyvsp[(3) - (3)].ival); - ;} - break; - - case 28: - -/* Line 1464 of yacc.c */ -#line 347 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) && (yyvsp[(3) - (3)].ival); - ;} - break; - - case 29: - -/* Line 1464 of yacc.c */ -#line 350 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); - ;} - break; - - case 30: - -/* Line 1464 of yacc.c */ -#line 353 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) ^ (yyvsp[(3) - (3)].ival); - ;} - break; - - case 31: - -/* Line 1464 of yacc.c */ -#line 356 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) & (yyvsp[(3) - (3)].ival); - ;} - break; - - case 32: - -/* Line 1464 of yacc.c */ -#line 359 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) != (yyvsp[(3) - (3)].ival); - ;} - break; - - case 33: - -/* Line 1464 of yacc.c */ -#line 362 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) == (yyvsp[(3) - (3)].ival); - ;} - break; - - case 34: - -/* Line 1464 of yacc.c */ -#line 365 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) >= (yyvsp[(3) - (3)].ival); - ;} - break; - - case 35: - -/* Line 1464 of yacc.c */ -#line 368 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) <= (yyvsp[(3) - (3)].ival); - ;} - break; - - case 36: - -/* Line 1464 of yacc.c */ -#line 371 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) > (yyvsp[(3) - (3)].ival); - ;} - break; - - case 37: - -/* Line 1464 of yacc.c */ -#line 374 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) < (yyvsp[(3) - (3)].ival); - ;} - break; - - case 38: - -/* Line 1464 of yacc.c */ -#line 377 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) >> (yyvsp[(3) - (3)].ival); - ;} - break; - - case 39: - -/* Line 1464 of yacc.c */ -#line 380 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) << (yyvsp[(3) - (3)].ival); - ;} - break; - - case 40: - -/* Line 1464 of yacc.c */ -#line 383 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) - (yyvsp[(3) - (3)].ival); - ;} - break; - - case 41: - -/* Line 1464 of yacc.c */ -#line 386 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) + (yyvsp[(3) - (3)].ival); - ;} - break; - - case 42: - -/* Line 1464 of yacc.c */ -#line 389 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) % (yyvsp[(3) - (3)].ival); - ;} - break; - - case 43: - -/* Line 1464 of yacc.c */ -#line 392 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) / (yyvsp[(3) - (3)].ival); - ;} - break; - - case 44: - -/* Line 1464 of yacc.c */ -#line 395 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) * (yyvsp[(3) - (3)].ival); - ;} - break; - - case 45: - -/* Line 1464 of yacc.c */ -#line 398 "glcpp/glcpp-parse.y" - { - (yyval.ival) = ! (yyvsp[(2) - (2)].ival); - ;} - break; - - case 46: - -/* Line 1464 of yacc.c */ -#line 401 "glcpp/glcpp-parse.y" - { - (yyval.ival) = ~ (yyvsp[(2) - (2)].ival); - ;} - break; - - case 47: - -/* Line 1464 of yacc.c */ -#line 404 "glcpp/glcpp-parse.y" - { - (yyval.ival) = - (yyvsp[(2) - (2)].ival); - ;} - break; - - case 48: - -/* Line 1464 of yacc.c */ -#line 407 "glcpp/glcpp-parse.y" - { - (yyval.ival) = + (yyvsp[(2) - (2)].ival); - ;} - break; - - case 49: - -/* Line 1464 of yacc.c */ -#line 410 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(2) - (3)].ival); - ;} - break; - - case 50: - -/* Line 1464 of yacc.c */ -#line 416 "glcpp/glcpp-parse.y" - { - (yyval.string_list) = _string_list_create (parser); - _string_list_append_item ((yyval.string_list), (yyvsp[(1) - (1)].str)); - talloc_steal ((yyval.string_list), (yyvsp[(1) - (1)].str)); - ;} - break; - - case 51: - -/* Line 1464 of yacc.c */ -#line 421 "glcpp/glcpp-parse.y" - { - (yyval.string_list) = (yyvsp[(1) - (3)].string_list); - _string_list_append_item ((yyval.string_list), (yyvsp[(3) - (3)].str)); - talloc_steal ((yyval.string_list), (yyvsp[(3) - (3)].str)); - ;} - break; - - case 52: - -/* Line 1464 of yacc.c */ -#line 429 "glcpp/glcpp-parse.y" - { (yyval.token_list) = NULL; ;} - break; - - case 54: - -/* Line 1464 of yacc.c */ -#line 434 "glcpp/glcpp-parse.y" - { - yyerror (& (yylsp[(1) - (2)]), parser, "Invalid tokens after #"); - ;} - break; - - case 55: - -/* Line 1464 of yacc.c */ -#line 440 "glcpp/glcpp-parse.y" - { (yyval.token_list) = NULL; ;} - break; - - case 58: - -/* Line 1464 of yacc.c */ -#line 446 "glcpp/glcpp-parse.y" - { - glcpp_warning(&(yylsp[(1) - (1)]), parser, "extra tokens at end of directive"); - ;} - break; - - case 59: - -/* Line 1464 of yacc.c */ -#line 453 "glcpp/glcpp-parse.y" - { - int v = hash_table_find (parser->defines, (yyvsp[(2) - (2)].str)) ? 1 : 0; - (yyval.token) = _token_create_ival (parser, INTEGER, v); - ;} - break; - - case 60: - -/* Line 1464 of yacc.c */ -#line 457 "glcpp/glcpp-parse.y" - { - int v = hash_table_find (parser->defines, (yyvsp[(3) - (4)].str)) ? 1 : 0; - (yyval.token) = _token_create_ival (parser, INTEGER, v); - ;} - break; - - case 62: - -/* Line 1464 of yacc.c */ -#line 466 "glcpp/glcpp-parse.y" - { - parser->space_tokens = 1; - (yyval.token_list) = _token_list_create (parser); - _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token)); - talloc_unlink (parser, (yyvsp[(1) - (1)].token)); - ;} - break; - - case 63: - -/* Line 1464 of yacc.c */ -#line 472 "glcpp/glcpp-parse.y" - { - (yyval.token_list) = (yyvsp[(1) - (2)].token_list); - _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token)); - talloc_unlink (parser, (yyvsp[(2) - (2)].token)); - ;} - break; - - case 64: - -/* Line 1464 of yacc.c */ -#line 480 "glcpp/glcpp-parse.y" - { - parser->space_tokens = 1; - (yyval.token_list) = _token_list_create (parser); - _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token)); - talloc_unlink (parser, (yyvsp[(1) - (1)].token)); - ;} - break; - - case 65: - -/* Line 1464 of yacc.c */ -#line 486 "glcpp/glcpp-parse.y" - { - (yyval.token_list) = (yyvsp[(1) - (2)].token_list); - _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token)); - talloc_unlink (parser, (yyvsp[(2) - (2)].token)); - ;} - break; - - case 66: - -/* Line 1464 of yacc.c */ -#line 494 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_str (parser, IDENTIFIER, (yyvsp[(1) - (1)].str)); - (yyval.token)->location = yylloc; - ;} - break; - - case 67: - -/* Line 1464 of yacc.c */ -#line 498 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_str (parser, INTEGER_STRING, (yyvsp[(1) - (1)].str)); - (yyval.token)->location = yylloc; - ;} - break; - - case 68: - -/* Line 1464 of yacc.c */ -#line 502 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_ival (parser, (yyvsp[(1) - (1)].ival), (yyvsp[(1) - (1)].ival)); - (yyval.token)->location = yylloc; - ;} - break; - - case 69: - -/* Line 1464 of yacc.c */ -#line 506 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_str (parser, OTHER, (yyvsp[(1) - (1)].str)); - (yyval.token)->location = yylloc; - ;} - break; - - case 70: - -/* Line 1464 of yacc.c */ -#line 510 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_ival (parser, SPACE, SPACE); - (yyval.token)->location = yylloc; - ;} - break; - - case 71: - -/* Line 1464 of yacc.c */ -#line 517 "glcpp/glcpp-parse.y" - { (yyval.ival) = '['; ;} - break; - - case 72: - -/* Line 1464 of yacc.c */ -#line 518 "glcpp/glcpp-parse.y" - { (yyval.ival) = ']'; ;} - break; - - case 73: - -/* Line 1464 of yacc.c */ -#line 519 "glcpp/glcpp-parse.y" - { (yyval.ival) = '('; ;} - break; - - case 74: - -/* Line 1464 of yacc.c */ -#line 520 "glcpp/glcpp-parse.y" - { (yyval.ival) = ')'; ;} - break; - - case 75: - -/* Line 1464 of yacc.c */ -#line 521 "glcpp/glcpp-parse.y" - { (yyval.ival) = '{'; ;} - break; - - case 76: - -/* Line 1464 of yacc.c */ -#line 522 "glcpp/glcpp-parse.y" - { (yyval.ival) = '}'; ;} - break; - - case 77: - -/* Line 1464 of yacc.c */ -#line 523 "glcpp/glcpp-parse.y" - { (yyval.ival) = '.'; ;} - break; - - case 78: - -/* Line 1464 of yacc.c */ -#line 524 "glcpp/glcpp-parse.y" - { (yyval.ival) = '&'; ;} - break; - - case 79: - -/* Line 1464 of yacc.c */ -#line 525 "glcpp/glcpp-parse.y" - { (yyval.ival) = '*'; ;} - break; - - case 80: - -/* Line 1464 of yacc.c */ -#line 526 "glcpp/glcpp-parse.y" - { (yyval.ival) = '+'; ;} - break; - - case 81: - -/* Line 1464 of yacc.c */ -#line 527 "glcpp/glcpp-parse.y" - { (yyval.ival) = '-'; ;} - break; - - case 82: - -/* Line 1464 of yacc.c */ -#line 528 "glcpp/glcpp-parse.y" - { (yyval.ival) = '~'; ;} - break; - - case 83: - -/* Line 1464 of yacc.c */ -#line 529 "glcpp/glcpp-parse.y" - { (yyval.ival) = '!'; ;} - break; - - case 84: - -/* Line 1464 of yacc.c */ -#line 530 "glcpp/glcpp-parse.y" - { (yyval.ival) = '/'; ;} - break; - - case 85: - -/* Line 1464 of yacc.c */ -#line 531 "glcpp/glcpp-parse.y" - { (yyval.ival) = '%'; ;} - break; - - case 86: - -/* Line 1464 of yacc.c */ -#line 532 "glcpp/glcpp-parse.y" - { (yyval.ival) = LEFT_SHIFT; ;} - break; - - case 87: - -/* Line 1464 of yacc.c */ -#line 533 "glcpp/glcpp-parse.y" - { (yyval.ival) = RIGHT_SHIFT; ;} - break; - - case 88: - -/* Line 1464 of yacc.c */ -#line 534 "glcpp/glcpp-parse.y" - { (yyval.ival) = '<'; ;} - break; - - case 89: - -/* Line 1464 of yacc.c */ -#line 535 "glcpp/glcpp-parse.y" - { (yyval.ival) = '>'; ;} - break; - - case 90: - -/* Line 1464 of yacc.c */ -#line 536 "glcpp/glcpp-parse.y" - { (yyval.ival) = LESS_OR_EQUAL; ;} - break; - - case 91: - -/* Line 1464 of yacc.c */ -#line 537 "glcpp/glcpp-parse.y" - { (yyval.ival) = GREATER_OR_EQUAL; ;} - break; - - case 92: - -/* Line 1464 of yacc.c */ -#line 538 "glcpp/glcpp-parse.y" - { (yyval.ival) = EQUAL; ;} - break; - - case 93: - -/* Line 1464 of yacc.c */ -#line 539 "glcpp/glcpp-parse.y" - { (yyval.ival) = NOT_EQUAL; ;} - break; - - case 94: - -/* Line 1464 of yacc.c */ -#line 540 "glcpp/glcpp-parse.y" - { (yyval.ival) = '^'; ;} - break; - - case 95: - -/* Line 1464 of yacc.c */ -#line 541 "glcpp/glcpp-parse.y" - { (yyval.ival) = '|'; ;} - break; - - case 96: - -/* Line 1464 of yacc.c */ -#line 542 "glcpp/glcpp-parse.y" - { (yyval.ival) = AND; ;} - break; - - case 97: - -/* Line 1464 of yacc.c */ -#line 543 "glcpp/glcpp-parse.y" - { (yyval.ival) = OR; ;} - break; - - case 98: - -/* Line 1464 of yacc.c */ -#line 544 "glcpp/glcpp-parse.y" - { (yyval.ival) = ';'; ;} - break; - - case 99: - -/* Line 1464 of yacc.c */ -#line 545 "glcpp/glcpp-parse.y" - { (yyval.ival) = ','; ;} - break; - - case 100: - -/* Line 1464 of yacc.c */ -#line 546 "glcpp/glcpp-parse.y" - { (yyval.ival) = '='; ;} - break; - - case 101: - -/* Line 1464 of yacc.c */ -#line 547 "glcpp/glcpp-parse.y" - { (yyval.ival) = PASTE; ;} - break; - - - -/* Line 1464 of yacc.c */ -#line 2656 "glcpp/glcpp-parse.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, parser, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, parser, yymsg); - } - else - { - yyerror (&yylloc, parser, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, parser); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, parser); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, parser, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, parser); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, parser); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - -/* Line 1684 of yacc.c */ -#line 550 "glcpp/glcpp-parse.y" - - -string_list_t * -_string_list_create (void *ctx) -{ - string_list_t *list; - - list = talloc (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 = talloc (list, string_node_t); - node->str = talloc_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; -} - -int -_string_list_equal (string_list_t *a, string_list_t *b) -{ - string_node_t *node_a, *node_b; - - if (a == NULL && b == NULL) - return 1; - - if (a == NULL || b == NULL) - return 0; - - for (node_a = a->head, node_b = b->head; - node_a && node_b; - node_a = node_a->next, node_b = node_b->next) - { - if (strcmp (node_a->str, node_b->str)) - return 0; - } - - /* Catch the case of lists being different lengths, (which - * would cause the loop above to terminate after the shorter - * list). */ - return node_a == node_b; -} - -argument_list_t * -_argument_list_create (void *ctx) -{ - argument_list_t *list; - - list = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (list, token_node_t); - node->token = talloc_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; -} - -static 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; -} - -static 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; - } - } -} - -int -_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b) -{ - token_node_t *node_a, *node_b; - - node_a = a->head; - node_b = b->head; - - while (1) - { - if (node_a == NULL && node_b == NULL) - break; - - if (node_a == NULL || node_b == NULL) - return 0; - - if (node_a->token->type == SPACE) { - node_a = node_a->next; - continue; - } - - if (node_b->token->type == SPACE) { - node_b = node_b->next; - continue; - } - - if (node_a->token->type != node_b->token->type) - return 0; - - switch (node_a->token->type) { - case INTEGER: - if (node_a->token->value.ival != - node_b->token->value.ival) - { - return 0; - } - break; - case IDENTIFIER: - case INTEGER_STRING: - case OTHER: - if (strcmp (node_a->token->value.str, - node_b->token->value.str)) - { - return 0; - } - break; - } - - node_a = node_a->next; - node_b = node_b->next; - } - - return 1; -} - -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, "%" PRIiMAX, 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 = talloc_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); -} - -static void add_builtin_define(glcpp_parser_t *parser, - const char *name, int value) -{ - token_t *tok; - token_list_t *list; - - tok = _token_create_ival (parser, INTEGER, value); - - list = _token_list_create(parser); - _token_list_append(list, tok); - _define_object_macro(parser, NULL, name, list); - - talloc_unlink(parser, tok); -} - -glcpp_parser_t * -glcpp_parser_create (const struct gl_extensions *extensions, int api) -{ - glcpp_parser_t *parser; - int language_version; - - parser = talloc (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; - - /* Add pre-defined macros. */ - add_builtin_define(parser, "GL_ARB_draw_buffers", 1); - add_builtin_define(parser, "GL_ARB_texture_rectangle", 1); - - if (api == API_OPENGLES2) - add_builtin_define(parser, "GL_ES", 1); - - if (extensions != NULL) { - if (extensions->EXT_texture_array) { - add_builtin_define(parser, "GL_EXT_texture_array", 1); - } - - if (extensions->ARB_fragment_coord_conventions) - add_builtin_define(parser, "GL_ARB_fragment_coord_conventions", - 1); - } - - language_version = 110; - add_builtin_define(parser, "__VERSION__", language_version); - - return parser; -} - -int -glcpp_parser_parse (glcpp_parser_t *parser) -{ - return yyparse (parser); -} - -void -glcpp_parser_destroy (glcpp_parser_t *parser) -{ - 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; -} - -static token_list_t * -_token_list_create_with_one_space (void *ctx) -{ - token_list_t *list; - token_t *space; - - list = _token_list_create (ctx); - space = _token_create_ival (list, SPACE, SPACE); - _token_list_append (list, space); - - return list; -} - -static void -_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list) -{ - token_list_t *expanded; - token_t *token; - - expanded = _token_list_create (parser); - token = _token_create_ival (parser, type, type); - _token_list_append (expanded, token); - _glcpp_parser_expand_token_list (parser, list); - _token_list_append_list (expanded, list); - glcpp_parser_lex_from (parser, expanded); -} - -/* 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. Specifically, *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; - } - - /* Replace a macro defined as empty with a SPACE token. */ - if (macro->replacements == NULL) { - talloc_free (arguments); - return _token_list_create_with_one_space (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) { - token_list_t *expanded_argument; - expanded_argument = _token_list_copy (parser, - argument); - _glcpp_parser_expand_token_list (parser, - expanded_argument); - _token_list_append_list (substituted, - expanded_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. Specifically, *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 = talloc_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; - - /* Replace a macro defined as empty with a SPACE token. */ - if (macro->replacements == NULL) - return _token_list_create_with_one_space (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 = talloc (list, active_list_t); - node->identifier = talloc_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); -} - -static 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"); - } -} - -static int -_macro_equal (macro_t *a, macro_t *b) -{ - if (a->is_function != b->is_function) - return 0; - - if (a->is_function) { - if (! _string_list_equal (a->parameters, b->parameters)) - return 0; - } - - return _token_list_equal_ignoring_space (a->replacements, - b->replacements); -} - -void -_define_object_macro (glcpp_parser_t *parser, - YYLTYPE *loc, - const char *identifier, - token_list_t *replacements) -{ - macro_t *macro, *previous; - - if (loc != NULL) - _check_for_reserved_macro_name(parser, loc, identifier); - - macro = talloc (parser, macro_t); - - macro->is_function = 0; - macro->parameters = NULL; - macro->identifier = talloc_strdup (macro, identifier); - macro->replacements = talloc_steal (macro, replacements); - - previous = hash_table_find (parser->defines, identifier); - if (previous) { - if (_macro_equal (macro, previous)) { - talloc_free (macro); - return; - } - glcpp_error (loc, parser, "Redefinition of macro %s\n", - identifier); - } - - 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, *previous; - - _check_for_reserved_macro_name(parser, loc, identifier); - - macro = talloc (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); - - previous = hash_table_find (parser->defines, identifier); - if (previous) { - if (_macro_equal (macro, previous)) { - talloc_free (macro); - return; - } - glcpp_error (loc, parser, "Redefinition of macro %s\n", - identifier); - } - - 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 = talloc (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); -} - +/* A Bison parser, made by GNU Bison 2.4.3. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.4.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+
+
+/* Copy the first part of user declarations. */
+
+/* Line 189 of yacc.c */
+#line 1 "glcpp/glcpp-parse.y"
+
+/*
+ * 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 <string.h>
+#include <assert.h>
+#include <inttypes.h>
+
+#include "glcpp.h"
+#include "main/core.h" /* for struct gl_extensions */
+#include "main/mtypes.h" /* for gl_api enum */
+
+#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 int
+_string_list_equal (string_list_t *a, string_list_t *b);
+
+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 int
+_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b);
+
+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_if (glcpp_parser_t *parser, int type, token_list_t *list);
+
+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);
+
+static void
+add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
+
+
+
+/* Line 189 of yacc.c */
+#line 223 "glcpp/glcpp-parse.c"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ COMMA_FINAL = 258,
+ DEFINED = 259,
+ ELIF_EXPANDED = 260,
+ HASH = 261,
+ HASH_DEFINE_FUNC = 262,
+ HASH_DEFINE_OBJ = 263,
+ HASH_ELIF = 264,
+ HASH_ELSE = 265,
+ HASH_ENDIF = 266,
+ HASH_IF = 267,
+ HASH_IFDEF = 268,
+ HASH_IFNDEF = 269,
+ HASH_UNDEF = 270,
+ HASH_VERSION = 271,
+ IDENTIFIER = 272,
+ IF_EXPANDED = 273,
+ INTEGER = 274,
+ INTEGER_STRING = 275,
+ NEWLINE = 276,
+ OTHER = 277,
+ PLACEHOLDER = 278,
+ SPACE = 279,
+ PASTE = 280,
+ OR = 281,
+ AND = 282,
+ NOT_EQUAL = 283,
+ EQUAL = 284,
+ GREATER_OR_EQUAL = 285,
+ LESS_OR_EQUAL = 286,
+ RIGHT_SHIFT = 287,
+ LEFT_SHIFT = 288,
+ UNARY = 289
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 264 of yacc.c */
+#line 311 "glcpp/glcpp-parse.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 606
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 57
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 17
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 101
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 162
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 289
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 47, 2, 2, 2, 43, 30, 2,
+ 45, 46, 41, 39, 49, 40, 54, 42, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 55,
+ 33, 56, 34, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 50, 2, 51, 29, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 52, 28, 53, 48, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 31, 32, 35, 36, 37, 38, 44
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 4, 7, 9, 11, 13, 16, 20,
+ 24, 29, 36, 44, 48, 52, 55, 60, 65, 69,
+ 72, 75, 78, 82, 85, 87, 89, 91, 95, 99,
+ 103, 107, 111, 115, 119, 123, 127, 131, 135, 139,
+ 143, 147, 151, 155, 159, 163, 166, 169, 172, 175,
+ 179, 181, 185, 187, 190, 193, 194, 196, 197, 199,
+ 202, 207, 209, 211, 214, 216, 219, 221, 223, 225,
+ 227, 229, 231, 233, 235, 237, 239, 241, 243, 245,
+ 247, 249, 251, 253, 255, 257, 259, 261, 263, 265,
+ 267, 269, 271, 273, 275, 277, 279, 281, 283, 285,
+ 287, 289
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
+{
+ 58, 0, -1, -1, 58, 59, -1, 61, -1, 65,
+ -1, 60, -1, 6, 66, -1, 18, 63, 21, -1,
+ 5, 63, 21, -1, 8, 17, 67, 21, -1, 7,
+ 17, 45, 46, 67, 21, -1, 7, 17, 45, 64,
+ 46, 67, 21, -1, 15, 17, 21, -1, 12, 70,
+ 21, -1, 12, 21, -1, 13, 17, 68, 21, -1,
+ 14, 17, 68, 21, -1, 9, 70, 21, -1, 9,
+ 21, -1, 10, 21, -1, 11, 21, -1, 16, 62,
+ 21, -1, 6, 21, -1, 20, -1, 19, -1, 62,
+ -1, 63, 26, 63, -1, 63, 27, 63, -1, 63,
+ 28, 63, -1, 63, 29, 63, -1, 63, 30, 63,
+ -1, 63, 31, 63, -1, 63, 32, 63, -1, 63,
+ 35, 63, -1, 63, 36, 63, -1, 63, 34, 63,
+ -1, 63, 33, 63, -1, 63, 37, 63, -1, 63,
+ 38, 63, -1, 63, 40, 63, -1, 63, 39, 63,
+ -1, 63, 43, 63, -1, 63, 42, 63, -1, 63,
+ 41, 63, -1, 47, 63, -1, 48, 63, -1, 40,
+ 63, -1, 39, 63, -1, 45, 63, 46, -1, 17,
+ -1, 64, 49, 17, -1, 21, -1, 71, 21, -1,
+ 71, 21, -1, -1, 71, -1, -1, 71, -1, 4,
+ 17, -1, 4, 45, 17, 46, -1, 72, -1, 69,
+ -1, 70, 69, -1, 72, -1, 71, 72, -1, 17,
+ -1, 20, -1, 73, -1, 22, -1, 24, -1, 50,
+ -1, 51, -1, 45, -1, 46, -1, 52, -1, 53,
+ -1, 54, -1, 30, -1, 41, -1, 39, -1, 40,
+ -1, 48, -1, 47, -1, 42, -1, 43, -1, 38,
+ -1, 37, -1, 33, -1, 34, -1, 36, -1, 35,
+ -1, 32, -1, 31, -1, 29, -1, 28, -1, 27,
+ -1, 26, -1, 55, -1, 49, -1, 56, -1, 25,
+ -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 188, 188, 190, 194, 197, 202, 203, 207, 210,
+ 216, 219, 222, 225, 233, 252, 262, 267, 272, 291,
+ 306, 309, 312, 333, 337, 346, 351, 352, 355, 358,
+ 361, 364, 367, 370, 373, 376, 379, 382, 385, 388,
+ 391, 394, 397, 400, 403, 406, 409, 412, 415, 418,
+ 424, 429, 437, 438, 442, 448, 449, 452, 454, 461,
+ 465, 469, 474, 479, 487, 493, 501, 505, 509, 513,
+ 517, 524, 525, 526, 527, 528, 529, 530, 531, 532,
+ 533, 534, 535, 536, 537, 538, 539, 540, 541, 542,
+ 543, 544, 545, 546, 547, 548, 549, 550, 551, 552,
+ 553, 554
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "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", "HASH_VERSION", "IDENTIFIER", "IF_EXPANDED",
+ "INTEGER", "INTEGER_STRING", "NEWLINE", "OTHER", "PLACEHOLDER", "SPACE",
+ "PASTE", "OR", "AND", "'|'", "'^'", "'&'", "NOT_EQUAL", "EQUAL", "'<'",
+ "'>'", "GREATER_OR_EQUAL", "LESS_OR_EQUAL", "RIGHT_SHIFT", "LEFT_SHIFT",
+ "'+'", "'-'", "'*'", "'/'", "'%'", "UNARY", "'('", "')'", "'!'", "'~'",
+ "','", "'['", "']'", "'{'", "'}'", "'.'", "';'", "'='", "$accept",
+ "input", "line", "expanded_line", "control_line", "integer_constant",
+ "expression", "identifier_list", "text_line", "non_directive",
+ "replacement_list", "junk", "conditional_token", "conditional_tokens",
+ "pp_tokens", "preprocessing_token", "operator", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 124, 94,
+ 38, 283, 284, 60, 62, 285, 286, 287, 288, 43,
+ 45, 42, 47, 37, 289, 40, 41, 33, 126, 44,
+ 91, 93, 123, 125, 46, 59, 61
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 57, 58, 58, 59, 59, 59, 59, 60, 60,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 62, 62, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 64, 64, 65, 65, 66, 67, 67, 68, 68, 69,
+ 69, 69, 70, 70, 71, 71, 72, 72, 72, 72,
+ 72, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 1, 2, 3, 3,
+ 4, 6, 7, 3, 3, 2, 4, 4, 3, 2,
+ 2, 2, 3, 2, 1, 1, 1, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 2, 2, 2, 2, 3,
+ 1, 3, 1, 2, 2, 0, 1, 0, 1, 2,
+ 4, 1, 1, 2, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 2, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 66, 0, 67, 52, 69,
+ 70, 101, 97, 96, 95, 94, 78, 93, 92, 88,
+ 89, 91, 90, 87, 86, 80, 81, 79, 84, 85,
+ 73, 74, 83, 82, 99, 71, 72, 75, 76, 77,
+ 98, 100, 3, 6, 4, 5, 0, 64, 68, 25,
+ 24, 0, 0, 0, 0, 0, 26, 0, 23, 7,
+ 0, 0, 55, 0, 19, 62, 0, 61, 20, 21,
+ 15, 0, 57, 57, 0, 0, 0, 53, 65, 48,
+ 47, 0, 45, 46, 9, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 56, 59, 0, 18,
+ 63, 14, 0, 58, 0, 13, 22, 8, 49, 27,
+ 28, 29, 30, 31, 32, 33, 37, 36, 34, 35,
+ 38, 39, 41, 40, 44, 43, 42, 50, 55, 0,
+ 10, 0, 16, 17, 0, 55, 0, 60, 11, 0,
+ 51, 12
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 1, 52, 53, 54, 66, 67, 149, 55, 69,
+ 115, 122, 75, 76, 116, 57, 58
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -147
+static const yytype_int16 yypact[] =
+{
+ -147, 112, -147, 28, -10, 55, 62, 152, -15, 59,
+ 192, 85, 86, 87, 51, -147, 28, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, -147, -147, -147, 312, -147, -147, -147,
+ -147, 28, 28, 28, 28, 28, -147, 428, -147, -147,
+ 352, 63, 392, 17, -147, -147, 232, -147, -147, -147,
+ -147, 272, 392, 392, 84, 89, 451, -147, -147, -147,
+ -147, 469, -147, -147, -147, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, -147, 60, 90, 392, -147, 96, -147,
+ -147, -147, 93, 392, 94, -147, -147, -147, -147, 489,
+ 505, 520, 534, 547, 558, 558, 18, 18, 18, 18,
+ 563, 563, 23, 23, -147, -147, -147, -147, 392, 32,
+ -147, 61, -147, -147, 110, 392, 118, -147, -147, 149,
+ -147, -147
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -147, -147, -147, -147, -147, 157, -11, -147, -147, -147,
+ -146, 92, -68, 200, 0, -7, -147
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+ 77, 56, 154, 77, 70, 86, 78, 15, 120, 159,
+ 17, 68, 19, 120, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 117, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 59, 60, 88,
+ 89, 90, 91, 92, 93, 106, 107, 108, 109, 110,
+ 111, 112, 118, 88, 110, 111, 112, 61, 62, 77,
+ 59, 60, 71, 63, 77, 64, 65, 147, 155, 72,
+ 79, 156, 123, 123, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 82, 83, 84, 125, 148, 157, 114, 88,
+ 126, 150, 2, 151, 152, 153, 88, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 158, 17, 18, 19, 160, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 73, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 15,
+ 161, 85, 17, 74, 19, 124, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 73, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 15,
+ 81, 0, 17, 80, 19, 0, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 73, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 15,
+ 0, 0, 17, 119, 19, 0, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 73, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 15,
+ 0, 0, 17, 121, 19, 0, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 0, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 15,
+ 0, 0, 17, 87, 19, 0, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 0, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 15,
+ 0, 0, 17, 113, 19, 0, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 0, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 15,
+ 0, 0, 17, 0, 19, 0, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 0, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 94,
+ 0, 0, 0, 0, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 127, 0, 0, 0, 0, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+ 108, 109, 110, 111, 112, 95, 96, 97, 98, 99,
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 0, 0, 128, 96, 97, 98, 99,
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 98,
+ 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 108, 109, 110, 111, 112
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 7, 1, 148, 10, 4, 16, 21, 17, 76, 155,
+ 20, 21, 22, 81, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 17, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 19, 20, 56,
+ 61, 62, 63, 64, 65, 37, 38, 39, 40, 41,
+ 42, 43, 45, 70, 41, 42, 43, 39, 40, 76,
+ 19, 20, 17, 45, 81, 47, 48, 17, 46, 17,
+ 21, 49, 82, 83, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 17, 17, 17, 21, 46, 46, 45, 116,
+ 21, 21, 0, 17, 21, 21, 123, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 21, 20, 21, 22, 17, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 4, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 17,
+ 21, 14, 20, 21, 22, 83, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 4, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 17,
+ 10, -1, 20, 21, 22, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 4, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 17,
+ -1, -1, 20, 21, 22, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 4, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 17,
+ -1, -1, 20, 21, 22, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, -1, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 17,
+ -1, -1, 20, 21, 22, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, -1, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 17,
+ -1, -1, 20, 21, 22, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, -1, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 17,
+ -1, -1, 20, -1, 22, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, -1, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 21,
+ -1, -1, -1, -1, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 21, -1, -1, -1, -1, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, -1, -1, 46, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 39, 40, 41, 42, 43
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 58, 0, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 20, 21, 22,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 59, 60, 61, 65, 71, 72, 73, 19,
+ 20, 39, 40, 45, 47, 48, 62, 63, 21, 66,
+ 71, 17, 17, 4, 21, 69, 70, 72, 21, 21,
+ 21, 70, 17, 17, 17, 62, 63, 21, 72, 63,
+ 63, 63, 63, 63, 21, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 21, 45, 67, 71, 17, 45, 21,
+ 69, 21, 68, 71, 68, 21, 21, 21, 46, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 17, 46, 64,
+ 21, 17, 21, 21, 67, 46, 49, 46, 21, 67,
+ 17, 21
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. However,
+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated
+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+ discussed. */
+
+#define YYFAIL goto yyerrlab
+#if defined YYFAIL
+ /* This is here to suppress warnings from the GCC cpp's
+ -Wunused-macros. Normally we don't worry about that warning, but
+ some users do, and we want to make it easy for users to remove
+ YYFAIL uses, which will produce warnings from Bison 2.5. */
+#endif
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, parser, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, parser)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location, parser); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ glcpp_parser_t *parser;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+ YYUSE (parser);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parser)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ glcpp_parser_t *parser;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, glcpp_parser_t *parser)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, parser)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+ glcpp_parser_t *parser;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) , parser);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule, parser); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, glcpp_parser_t *parser)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, parser)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+ glcpp_parser_t *parser;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ YYUSE (parser);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+/* Prevent warnings from -Wmissing-prototypes. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (glcpp_parser_t *parser);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse. |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (glcpp_parser_t *parser)
+#else
+int
+yyparse (parser)
+ glcpp_parser_t *parser;
+#endif
+#endif
+{
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc;
+
+ /* Number of syntax errors so far. */
+ int yynerrs;
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[3];
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yyls = yylsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+ yyssp = yyss;
+ yyvsp = yyvs;
+ yylsp = yyls;
+
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+/* User initialization code. */
+
+/* Line 1251 of yacc.c */
+#line 155 "glcpp/glcpp-parse.y"
+{
+ yylloc.first_line = 1;
+ yylloc.first_column = 1;
+ yylloc.last_line = 1;
+ yylloc.last_column = 1;
+ yylloc.source = 0;
+}
+
+/* Line 1251 of yacc.c */
+#line 1625 "glcpp/glcpp-parse.c"
+ yylsp[0] = yylloc;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 4:
+
+/* Line 1464 of yacc.c */
+#line 194 "glcpp/glcpp-parse.y"
+ {
+ glcpp_print(parser->output, "\n");
+ ;}
+ break;
+
+ case 5:
+
+/* Line 1464 of yacc.c */
+#line 197 "glcpp/glcpp-parse.y"
+ {
+ _glcpp_parser_print_expanded_token_list (parser, (yyvsp[(1) - (1)].token_list));
+ glcpp_print(parser->output, "\n");
+ talloc_free ((yyvsp[(1) - (1)].token_list));
+ ;}
+ break;
+
+ case 8:
+
+/* Line 1464 of yacc.c */
+#line 207 "glcpp/glcpp-parse.y"
+ {
+ _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), (yyvsp[(2) - (3)].ival));
+ ;}
+ break;
+
+ case 9:
+
+/* Line 1464 of yacc.c */
+#line 210 "glcpp/glcpp-parse.y"
+ {
+ _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]), "elif", (yyvsp[(2) - (3)].ival));
+ ;}
+ break;
+
+ case 10:
+
+/* Line 1464 of yacc.c */
+#line 216 "glcpp/glcpp-parse.y"
+ {
+ _define_object_macro (parser, & (yylsp[(2) - (4)]), (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].token_list));
+ ;}
+ break;
+
+ case 11:
+
+/* Line 1464 of yacc.c */
+#line 219 "glcpp/glcpp-parse.y"
+ {
+ _define_function_macro (parser, & (yylsp[(2) - (6)]), (yyvsp[(2) - (6)].str), NULL, (yyvsp[(5) - (6)].token_list));
+ ;}
+ break;
+
+ case 12:
+
+/* Line 1464 of yacc.c */
+#line 222 "glcpp/glcpp-parse.y"
+ {
+ _define_function_macro (parser, & (yylsp[(2) - (7)]), (yyvsp[(2) - (7)].str), (yyvsp[(4) - (7)].string_list), (yyvsp[(6) - (7)].token_list));
+ ;}
+ break;
+
+ case 13:
+
+/* Line 1464 of yacc.c */
+#line 225 "glcpp/glcpp-parse.y"
+ {
+ macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (3)].str));
+ if (macro) {
+ hash_table_remove (parser->defines, (yyvsp[(2) - (3)].str));
+ talloc_free (macro);
+ }
+ talloc_free ((yyvsp[(2) - (3)].str));
+ ;}
+ break;
+
+ case 14:
+
+/* Line 1464 of yacc.c */
+#line 233 "glcpp/glcpp-parse.y"
+ {
+ /* Be careful to only evaluate the 'if' expression if
+ * we are not skipping. When we are skipping, we
+ * simply push a new 0-valued 'if' onto the skip
+ * stack.
+ *
+ * This avoids generating diagnostics for invalid
+ * expressions that are being skipped. */
+ if (parser->skip_stack == NULL ||
+ parser->skip_stack->type == SKIP_NO_SKIP)
+ {
+ _glcpp_parser_expand_if (parser, IF_EXPANDED, (yyvsp[(2) - (3)].token_list));
+ }
+ else
+ {
+ _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), 0);
+ parser->skip_stack->type = SKIP_TO_ENDIF;
+ }
+ ;}
+ break;
+
+ case 15:
+
+/* Line 1464 of yacc.c */
+#line 252 "glcpp/glcpp-parse.y"
+ {
+ /* #if without an expression is only an error if we
+ * are not skipping */
+ if (parser->skip_stack == NULL ||
+ parser->skip_stack->type == SKIP_NO_SKIP)
+ {
+ glcpp_error(& (yylsp[(1) - (2)]), parser, "#if with no expression");
+ }
+ _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (2)]), 0);
+ ;}
+ break;
+
+ case 16:
+
+/* Line 1464 of yacc.c */
+#line 262 "glcpp/glcpp-parse.y"
+ {
+ macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str));
+ talloc_free ((yyvsp[(2) - (4)].str));
+ _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro != NULL);
+ ;}
+ break;
+
+ case 17:
+
+/* Line 1464 of yacc.c */
+#line 267 "glcpp/glcpp-parse.y"
+ {
+ macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str));
+ talloc_free ((yyvsp[(2) - (4)].str));
+ _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro == NULL);
+ ;}
+ break;
+
+ case 18:
+
+/* Line 1464 of yacc.c */
+#line 272 "glcpp/glcpp-parse.y"
+ {
+ /* Be careful to only evaluate the 'elif' expression
+ * if we are not skipping. When we are skipping, we
+ * simply change to a 0-valued 'elif' on the skip
+ * stack.
+ *
+ * This avoids generating diagnostics for invalid
+ * expressions that are being skipped. */
+ if (parser->skip_stack &&
+ parser->skip_stack->type == SKIP_TO_ELSE)
+ {
+ _glcpp_parser_expand_if (parser, ELIF_EXPANDED, (yyvsp[(2) - (3)].token_list));
+ }
+ else
+ {
+ _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]),
+ "elif", 0);
+ }
+ ;}
+ break;
+
+ case 19:
+
+/* Line 1464 of yacc.c */
+#line 291 "glcpp/glcpp-parse.y"
+ {
+ /* #elif without an expression is an error unless we
+ * are skipping. */
+ if (parser->skip_stack &&
+ parser->skip_stack->type == SKIP_TO_ELSE)
+ {
+ glcpp_error(& (yylsp[(1) - (2)]), parser, "#elif with no expression");
+ }
+ else
+ {
+ _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]),
+ "elif", 0);
+ glcpp_warning(& (yylsp[(1) - (2)]), parser, "ignoring illegal #elif without expression");
+ }
+ ;}
+ break;
+
+ case 20:
+
+/* Line 1464 of yacc.c */
+#line 306 "glcpp/glcpp-parse.y"
+ {
+ _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]), "else", 1);
+ ;}
+ break;
+
+ case 21:
+
+/* Line 1464 of yacc.c */
+#line 309 "glcpp/glcpp-parse.y"
+ {
+ _glcpp_parser_skip_stack_pop (parser, & (yylsp[(1) - (2)]));
+ ;}
+ break;
+
+ case 22:
+
+/* Line 1464 of yacc.c */
+#line 312 "glcpp/glcpp-parse.y"
+ {
+ macro_t *macro = hash_table_find (parser->defines, "__VERSION__");
+ if (macro) {
+ hash_table_remove (parser->defines, "__VERSION__");
+ talloc_free (macro);
+ }
+ add_builtin_define (parser, "__VERSION__", (yyvsp[(2) - (3)].ival));
+
+ if ((yyvsp[(2) - (3)].ival) == 100)
+ add_builtin_define (parser, "GL_ES", 1);
+
+ /* Currently, all ES2 implementations support highp in the
+ * fragment shader, so we always define this macro in ES2.
+ * If we ever get a driver that doesn't support highp, we'll
+ * need to add a flag to the gl_context and check that here.
+ */
+ if ((yyvsp[(2) - (3)].ival) >= 130 || (yyvsp[(2) - (3)].ival) == 100)
+ add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
+
+ glcpp_printf(parser->output, "#version %" PRIiMAX, (yyvsp[(2) - (3)].ival));
+ ;}
+ break;
+
+ case 24:
+
+/* Line 1464 of yacc.c */
+#line 337 "glcpp/glcpp-parse.y"
+ {
+ if (strlen ((yyvsp[(1) - (1)].str)) >= 3 && strncmp ((yyvsp[(1) - (1)].str), "0x", 2) == 0) {
+ (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str) + 2, NULL, 16);
+ } else if ((yyvsp[(1) - (1)].str)[0] == '0') {
+ (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 8);
+ } else {
+ (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 10);
+ }
+ ;}
+ break;
+
+ case 25:
+
+/* Line 1464 of yacc.c */
+#line 346 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (1)].ival);
+ ;}
+ break;
+
+ case 27:
+
+/* Line 1464 of yacc.c */
+#line 352 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) || (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 28:
+
+/* Line 1464 of yacc.c */
+#line 355 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) && (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 29:
+
+/* Line 1464 of yacc.c */
+#line 358 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 30:
+
+/* Line 1464 of yacc.c */
+#line 361 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) ^ (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 31:
+
+/* Line 1464 of yacc.c */
+#line 364 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) & (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 32:
+
+/* Line 1464 of yacc.c */
+#line 367 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) != (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 33:
+
+/* Line 1464 of yacc.c */
+#line 370 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) == (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 34:
+
+/* Line 1464 of yacc.c */
+#line 373 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) >= (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 35:
+
+/* Line 1464 of yacc.c */
+#line 376 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) <= (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 36:
+
+/* Line 1464 of yacc.c */
+#line 379 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) > (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 37:
+
+/* Line 1464 of yacc.c */
+#line 382 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) < (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 38:
+
+/* Line 1464 of yacc.c */
+#line 385 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) >> (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 39:
+
+/* Line 1464 of yacc.c */
+#line 388 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) << (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 40:
+
+/* Line 1464 of yacc.c */
+#line 391 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) - (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 41:
+
+/* Line 1464 of yacc.c */
+#line 394 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) + (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 42:
+
+/* Line 1464 of yacc.c */
+#line 397 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) % (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 43:
+
+/* Line 1464 of yacc.c */
+#line 400 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) / (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 44:
+
+/* Line 1464 of yacc.c */
+#line 403 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(1) - (3)].ival) * (yyvsp[(3) - (3)].ival);
+ ;}
+ break;
+
+ case 45:
+
+/* Line 1464 of yacc.c */
+#line 406 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = ! (yyvsp[(2) - (2)].ival);
+ ;}
+ break;
+
+ case 46:
+
+/* Line 1464 of yacc.c */
+#line 409 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = ~ (yyvsp[(2) - (2)].ival);
+ ;}
+ break;
+
+ case 47:
+
+/* Line 1464 of yacc.c */
+#line 412 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = - (yyvsp[(2) - (2)].ival);
+ ;}
+ break;
+
+ case 48:
+
+/* Line 1464 of yacc.c */
+#line 415 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = + (yyvsp[(2) - (2)].ival);
+ ;}
+ break;
+
+ case 49:
+
+/* Line 1464 of yacc.c */
+#line 418 "glcpp/glcpp-parse.y"
+ {
+ (yyval.ival) = (yyvsp[(2) - (3)].ival);
+ ;}
+ break;
+
+ case 50:
+
+/* Line 1464 of yacc.c */
+#line 424 "glcpp/glcpp-parse.y"
+ {
+ (yyval.string_list) = _string_list_create (parser);
+ _string_list_append_item ((yyval.string_list), (yyvsp[(1) - (1)].str));
+ talloc_steal ((yyval.string_list), (yyvsp[(1) - (1)].str));
+ ;}
+ break;
+
+ case 51:
+
+/* Line 1464 of yacc.c */
+#line 429 "glcpp/glcpp-parse.y"
+ {
+ (yyval.string_list) = (yyvsp[(1) - (3)].string_list);
+ _string_list_append_item ((yyval.string_list), (yyvsp[(3) - (3)].str));
+ talloc_steal ((yyval.string_list), (yyvsp[(3) - (3)].str));
+ ;}
+ break;
+
+ case 52:
+
+/* Line 1464 of yacc.c */
+#line 437 "glcpp/glcpp-parse.y"
+ { (yyval.token_list) = NULL; ;}
+ break;
+
+ case 54:
+
+/* Line 1464 of yacc.c */
+#line 442 "glcpp/glcpp-parse.y"
+ {
+ yyerror (& (yylsp[(1) - (2)]), parser, "Invalid tokens after #");
+ ;}
+ break;
+
+ case 55:
+
+/* Line 1464 of yacc.c */
+#line 448 "glcpp/glcpp-parse.y"
+ { (yyval.token_list) = NULL; ;}
+ break;
+
+ case 58:
+
+/* Line 1464 of yacc.c */
+#line 454 "glcpp/glcpp-parse.y"
+ {
+ glcpp_warning(&(yylsp[(1) - (1)]), parser, "extra tokens at end of directive");
+ ;}
+ break;
+
+ case 59:
+
+/* Line 1464 of yacc.c */
+#line 461 "glcpp/glcpp-parse.y"
+ {
+ int v = hash_table_find (parser->defines, (yyvsp[(2) - (2)].str)) ? 1 : 0;
+ (yyval.token) = _token_create_ival (parser, INTEGER, v);
+ ;}
+ break;
+
+ case 60:
+
+/* Line 1464 of yacc.c */
+#line 465 "glcpp/glcpp-parse.y"
+ {
+ int v = hash_table_find (parser->defines, (yyvsp[(3) - (4)].str)) ? 1 : 0;
+ (yyval.token) = _token_create_ival (parser, INTEGER, v);
+ ;}
+ break;
+
+ case 62:
+
+/* Line 1464 of yacc.c */
+#line 474 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token_list) = _token_list_create (parser);
+ _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token));
+ talloc_unlink (parser, (yyvsp[(1) - (1)].token));
+ ;}
+ break;
+
+ case 63:
+
+/* Line 1464 of yacc.c */
+#line 479 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token_list) = (yyvsp[(1) - (2)].token_list);
+ _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token));
+ talloc_unlink (parser, (yyvsp[(2) - (2)].token));
+ ;}
+ break;
+
+ case 64:
+
+/* Line 1464 of yacc.c */
+#line 487 "glcpp/glcpp-parse.y"
+ {
+ parser->space_tokens = 1;
+ (yyval.token_list) = _token_list_create (parser);
+ _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token));
+ talloc_unlink (parser, (yyvsp[(1) - (1)].token));
+ ;}
+ break;
+
+ case 65:
+
+/* Line 1464 of yacc.c */
+#line 493 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token_list) = (yyvsp[(1) - (2)].token_list);
+ _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token));
+ talloc_unlink (parser, (yyvsp[(2) - (2)].token));
+ ;}
+ break;
+
+ case 66:
+
+/* Line 1464 of yacc.c */
+#line 501 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token) = _token_create_str (parser, IDENTIFIER, (yyvsp[(1) - (1)].str));
+ (yyval.token)->location = yylloc;
+ ;}
+ break;
+
+ case 67:
+
+/* Line 1464 of yacc.c */
+#line 505 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token) = _token_create_str (parser, INTEGER_STRING, (yyvsp[(1) - (1)].str));
+ (yyval.token)->location = yylloc;
+ ;}
+ break;
+
+ case 68:
+
+/* Line 1464 of yacc.c */
+#line 509 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token) = _token_create_ival (parser, (yyvsp[(1) - (1)].ival), (yyvsp[(1) - (1)].ival));
+ (yyval.token)->location = yylloc;
+ ;}
+ break;
+
+ case 69:
+
+/* Line 1464 of yacc.c */
+#line 513 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token) = _token_create_str (parser, OTHER, (yyvsp[(1) - (1)].str));
+ (yyval.token)->location = yylloc;
+ ;}
+ break;
+
+ case 70:
+
+/* Line 1464 of yacc.c */
+#line 517 "glcpp/glcpp-parse.y"
+ {
+ (yyval.token) = _token_create_ival (parser, SPACE, SPACE);
+ (yyval.token)->location = yylloc;
+ ;}
+ break;
+
+ case 71:
+
+/* Line 1464 of yacc.c */
+#line 524 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '['; ;}
+ break;
+
+ case 72:
+
+/* Line 1464 of yacc.c */
+#line 525 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = ']'; ;}
+ break;
+
+ case 73:
+
+/* Line 1464 of yacc.c */
+#line 526 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '('; ;}
+ break;
+
+ case 74:
+
+/* Line 1464 of yacc.c */
+#line 527 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = ')'; ;}
+ break;
+
+ case 75:
+
+/* Line 1464 of yacc.c */
+#line 528 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '{'; ;}
+ break;
+
+ case 76:
+
+/* Line 1464 of yacc.c */
+#line 529 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '}'; ;}
+ break;
+
+ case 77:
+
+/* Line 1464 of yacc.c */
+#line 530 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '.'; ;}
+ break;
+
+ case 78:
+
+/* Line 1464 of yacc.c */
+#line 531 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '&'; ;}
+ break;
+
+ case 79:
+
+/* Line 1464 of yacc.c */
+#line 532 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '*'; ;}
+ break;
+
+ case 80:
+
+/* Line 1464 of yacc.c */
+#line 533 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '+'; ;}
+ break;
+
+ case 81:
+
+/* Line 1464 of yacc.c */
+#line 534 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '-'; ;}
+ break;
+
+ case 82:
+
+/* Line 1464 of yacc.c */
+#line 535 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '~'; ;}
+ break;
+
+ case 83:
+
+/* Line 1464 of yacc.c */
+#line 536 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '!'; ;}
+ break;
+
+ case 84:
+
+/* Line 1464 of yacc.c */
+#line 537 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '/'; ;}
+ break;
+
+ case 85:
+
+/* Line 1464 of yacc.c */
+#line 538 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '%'; ;}
+ break;
+
+ case 86:
+
+/* Line 1464 of yacc.c */
+#line 539 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = LEFT_SHIFT; ;}
+ break;
+
+ case 87:
+
+/* Line 1464 of yacc.c */
+#line 540 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = RIGHT_SHIFT; ;}
+ break;
+
+ case 88:
+
+/* Line 1464 of yacc.c */
+#line 541 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '<'; ;}
+ break;
+
+ case 89:
+
+/* Line 1464 of yacc.c */
+#line 542 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '>'; ;}
+ break;
+
+ case 90:
+
+/* Line 1464 of yacc.c */
+#line 543 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = LESS_OR_EQUAL; ;}
+ break;
+
+ case 91:
+
+/* Line 1464 of yacc.c */
+#line 544 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = GREATER_OR_EQUAL; ;}
+ break;
+
+ case 92:
+
+/* Line 1464 of yacc.c */
+#line 545 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = EQUAL; ;}
+ break;
+
+ case 93:
+
+/* Line 1464 of yacc.c */
+#line 546 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = NOT_EQUAL; ;}
+ break;
+
+ case 94:
+
+/* Line 1464 of yacc.c */
+#line 547 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '^'; ;}
+ break;
+
+ case 95:
+
+/* Line 1464 of yacc.c */
+#line 548 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '|'; ;}
+ break;
+
+ case 96:
+
+/* Line 1464 of yacc.c */
+#line 549 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = AND; ;}
+ break;
+
+ case 97:
+
+/* Line 1464 of yacc.c */
+#line 550 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = OR; ;}
+ break;
+
+ case 98:
+
+/* Line 1464 of yacc.c */
+#line 551 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = ';'; ;}
+ break;
+
+ case 99:
+
+/* Line 1464 of yacc.c */
+#line 552 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = ','; ;}
+ break;
+
+ case 100:
+
+/* Line 1464 of yacc.c */
+#line 553 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = '='; ;}
+ break;
+
+ case 101:
+
+/* Line 1464 of yacc.c */
+#line 554 "glcpp/glcpp-parse.y"
+ { (yyval.ival) = PASTE; ;}
+ break;
+
+
+
+/* Line 1464 of yacc.c */
+#line 2663 "glcpp/glcpp-parse.c"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, parser, YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (&yylloc, parser, yymsg);
+ }
+ else
+ {
+ yyerror (&yylloc, parser, YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+ yyerror_range[1] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc, parser);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[1] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp, parser);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+ yyerror_range[2] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, parser, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc, parser);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp, parser);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
+/* Line 1684 of yacc.c */
+#line 557 "glcpp/glcpp-parse.y"
+
+
+string_list_t *
+_string_list_create (void *ctx)
+{
+ string_list_t *list;
+
+ list = talloc (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 = talloc (list, string_node_t);
+ node->str = talloc_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;
+}
+
+int
+_string_list_equal (string_list_t *a, string_list_t *b)
+{
+ string_node_t *node_a, *node_b;
+
+ if (a == NULL && b == NULL)
+ return 1;
+
+ if (a == NULL || b == NULL)
+ return 0;
+
+ for (node_a = a->head, node_b = b->head;
+ node_a && node_b;
+ node_a = node_a->next, node_b = node_b->next)
+ {
+ if (strcmp (node_a->str, node_b->str))
+ return 0;
+ }
+
+ /* Catch the case of lists being different lengths, (which
+ * would cause the loop above to terminate after the shorter
+ * list). */
+ return node_a == node_b;
+}
+
+argument_list_t *
+_argument_list_create (void *ctx)
+{
+ argument_list_t *list;
+
+ list = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (list, token_node_t);
+ node->token = talloc_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;
+}
+
+static 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;
+}
+
+static 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;
+ }
+ }
+}
+
+int
+_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
+{
+ token_node_t *node_a, *node_b;
+
+ node_a = a->head;
+ node_b = b->head;
+
+ while (1)
+ {
+ if (node_a == NULL && node_b == NULL)
+ break;
+
+ if (node_a == NULL || node_b == NULL)
+ return 0;
+
+ if (node_a->token->type == SPACE) {
+ node_a = node_a->next;
+ continue;
+ }
+
+ if (node_b->token->type == SPACE) {
+ node_b = node_b->next;
+ continue;
+ }
+
+ if (node_a->token->type != node_b->token->type)
+ return 0;
+
+ switch (node_a->token->type) {
+ case INTEGER:
+ if (node_a->token->value.ival !=
+ node_b->token->value.ival)
+ {
+ return 0;
+ }
+ break;
+ case IDENTIFIER:
+ case INTEGER_STRING:
+ case OTHER:
+ if (strcmp (node_a->token->value.str,
+ node_b->token->value.str))
+ {
+ return 0;
+ }
+ break;
+ }
+
+ node_a = node_a->next;
+ node_b = node_b->next;
+ }
+
+ return 1;
+}
+
+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, "%" PRIiMAX, 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 = talloc_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);
+}
+
+static void add_builtin_define(glcpp_parser_t *parser,
+ const char *name, int value)
+{
+ token_t *tok;
+ token_list_t *list;
+
+ tok = _token_create_ival (parser, INTEGER, value);
+
+ list = _token_list_create(parser);
+ _token_list_append(list, tok);
+ _define_object_macro(parser, NULL, name, list);
+
+ talloc_unlink(parser, tok);
+}
+
+glcpp_parser_t *
+glcpp_parser_create (const struct gl_extensions *extensions, int api)
+{
+ glcpp_parser_t *parser;
+ int language_version;
+
+ parser = talloc (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;
+
+ /* Add pre-defined macros. */
+ add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
+ add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
+
+ if (api == API_OPENGLES2)
+ add_builtin_define(parser, "GL_ES", 1);
+
+ if (extensions != NULL) {
+ if (extensions->EXT_texture_array) {
+ add_builtin_define(parser, "GL_EXT_texture_array", 1);
+ }
+
+ if (extensions->ARB_fragment_coord_conventions)
+ add_builtin_define(parser, "GL_ARB_fragment_coord_conventions",
+ 1);
+
+ if (extensions->ARB_explicit_attrib_location)
+ add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1);
+ }
+
+ language_version = 110;
+ add_builtin_define(parser, "__VERSION__", language_version);
+
+ return parser;
+}
+
+int
+glcpp_parser_parse (glcpp_parser_t *parser)
+{
+ return yyparse (parser);
+}
+
+void
+glcpp_parser_destroy (glcpp_parser_t *parser)
+{
+ 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;
+}
+
+static token_list_t *
+_token_list_create_with_one_space (void *ctx)
+{
+ token_list_t *list;
+ token_t *space;
+
+ list = _token_list_create (ctx);
+ space = _token_create_ival (list, SPACE, SPACE);
+ _token_list_append (list, space);
+
+ return list;
+}
+
+static void
+_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list)
+{
+ token_list_t *expanded;
+ token_t *token;
+
+ expanded = _token_list_create (parser);
+ token = _token_create_ival (parser, type, type);
+ _token_list_append (expanded, token);
+ _glcpp_parser_expand_token_list (parser, list);
+ _token_list_append_list (expanded, list);
+ glcpp_parser_lex_from (parser, expanded);
+}
+
+/* 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. Specifically, *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;
+ }
+
+ /* Replace a macro defined as empty with a SPACE token. */
+ if (macro->replacements == NULL) {
+ talloc_free (arguments);
+ return _token_list_create_with_one_space (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) {
+ token_list_t *expanded_argument;
+ expanded_argument = _token_list_copy (parser,
+ argument);
+ _glcpp_parser_expand_token_list (parser,
+ expanded_argument);
+ _token_list_append_list (substituted,
+ expanded_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. Specifically, *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 = talloc_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;
+
+ /* Replace a macro defined as empty with a SPACE token. */
+ if (macro->replacements == NULL)
+ return _token_list_create_with_one_space (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 = talloc (list, active_list_t);
+ node->identifier = talloc_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);
+}
+
+static 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");
+ }
+}
+
+static int
+_macro_equal (macro_t *a, macro_t *b)
+{
+ if (a->is_function != b->is_function)
+ return 0;
+
+ if (a->is_function) {
+ if (! _string_list_equal (a->parameters, b->parameters))
+ return 0;
+ }
+
+ return _token_list_equal_ignoring_space (a->replacements,
+ b->replacements);
+}
+
+void
+_define_object_macro (glcpp_parser_t *parser,
+ YYLTYPE *loc,
+ const char *identifier,
+ token_list_t *replacements)
+{
+ macro_t *macro, *previous;
+
+ if (loc != NULL)
+ _check_for_reserved_macro_name(parser, loc, identifier);
+
+ macro = talloc (parser, macro_t);
+
+ macro->is_function = 0;
+ macro->parameters = NULL;
+ macro->identifier = talloc_strdup (macro, identifier);
+ macro->replacements = talloc_steal (macro, replacements);
+
+ previous = hash_table_find (parser->defines, identifier);
+ if (previous) {
+ if (_macro_equal (macro, previous)) {
+ talloc_free (macro);
+ return;
+ }
+ glcpp_error (loc, parser, "Redefinition of macro %s\n",
+ identifier);
+ }
+
+ 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, *previous;
+
+ _check_for_reserved_macro_name(parser, loc, identifier);
+
+ macro = talloc (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);
+
+ previous = hash_table_find (parser->defines, identifier);
+ if (previous) {
+ if (_macro_equal (macro, previous)) {
+ talloc_free (macro);
+ return;
+ }
+ glcpp_error (loc, parser, "Redefinition of macro %s\n",
+ identifier);
+ }
+
+ 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 = talloc (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);
+}
+
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index 43513ebb6..e88e48057 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1,1858 +1,1868 @@ -%{ -/* - * 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 <string.h> -#include <assert.h> -#include <inttypes.h> - -#include "glcpp.h" -#include "main/core.h" /* for struct gl_extensions */ -#include "main/mtypes.h" /* for gl_api enum */ - -#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 int -_string_list_equal (string_list_t *a, string_list_t *b); - -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 int -_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b); - -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_if (glcpp_parser_t *parser, int type, token_list_t *list); - -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); - -static void -add_builtin_define(glcpp_parser_t *parser, const char *name, int value); - -%} - -%pure-parser -%error-verbose - -%locations -%initial-action { - @$.first_line = 1; - @$.first_column = 1; - @$.last_line = 1; - @$.last_column = 1; - @$.source = 0; -} - -%parse-param {glcpp_parser_t *parser} -%lex-param {glcpp_parser_t *parser} - -%expect 0 -%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 HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING NEWLINE OTHER PLACEHOLDER SPACE -%token PASTE -%type <ival> expression INTEGER operator SPACE integer_constant -%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) { - hash_table_remove (parser->defines, $2); - talloc_free (macro); - } - talloc_free ($2); - } -| HASH_IF conditional_tokens NEWLINE { - /* Be careful to only evaluate the 'if' expression if - * we are not skipping. When we are skipping, we - * simply push a new 0-valued 'if' onto the skip - * stack. - * - * This avoids generating diagnostics for invalid - * expressions that are being skipped. */ - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - _glcpp_parser_expand_if (parser, IF_EXPANDED, $2); - } - else - { - _glcpp_parser_skip_stack_push_if (parser, & @1, 0); - parser->skip_stack->type = SKIP_TO_ENDIF; - } - } -| HASH_IF NEWLINE { - /* #if without an expression is only an error if we - * are not skipping */ - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - glcpp_error(& @1, parser, "#if with no expression"); - } - _glcpp_parser_skip_stack_push_if (parser, & @1, 0); - } -| 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 { - /* Be careful to only evaluate the 'elif' expression - * if we are not skipping. When we are skipping, we - * simply change to a 0-valued 'elif' on the skip - * stack. - * - * This avoids generating diagnostics for invalid - * expressions that are being skipped. */ - if (parser->skip_stack && - parser->skip_stack->type == SKIP_TO_ELSE) - { - _glcpp_parser_expand_if (parser, ELIF_EXPANDED, $2); - } - else - { - _glcpp_parser_skip_stack_change_if (parser, & @1, - "elif", 0); - } - } -| HASH_ELIF NEWLINE { - /* #elif without an expression is an error unless we - * are skipping. */ - if (parser->skip_stack && - parser->skip_stack->type == SKIP_TO_ELSE) - { - glcpp_error(& @1, parser, "#elif with no expression"); - } - else - { - _glcpp_parser_skip_stack_change_if (parser, & @1, - "elif", 0); - glcpp_warning(& @1, parser, "ignoring illegal #elif without 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_VERSION integer_constant NEWLINE { - macro_t *macro = hash_table_find (parser->defines, "__VERSION__"); - if (macro) { - hash_table_remove (parser->defines, "__VERSION__"); - talloc_free (macro); - } - add_builtin_define (parser, "__VERSION__", $2); - - if ($2 == 100) - add_builtin_define (parser, "GL_ES", 1); - - glcpp_printf(parser->output, "#version %" PRIiMAX, $2); - } -| HASH NEWLINE -; - -integer_constant: - 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: - integer_constant -| 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; } -; - -%% - -string_list_t * -_string_list_create (void *ctx) -{ - string_list_t *list; - - list = talloc (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 = talloc (list, string_node_t); - node->str = talloc_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; -} - -int -_string_list_equal (string_list_t *a, string_list_t *b) -{ - string_node_t *node_a, *node_b; - - if (a == NULL && b == NULL) - return 1; - - if (a == NULL || b == NULL) - return 0; - - for (node_a = a->head, node_b = b->head; - node_a && node_b; - node_a = node_a->next, node_b = node_b->next) - { - if (strcmp (node_a->str, node_b->str)) - return 0; - } - - /* Catch the case of lists being different lengths, (which - * would cause the loop above to terminate after the shorter - * list). */ - return node_a == node_b; -} - -argument_list_t * -_argument_list_create (void *ctx) -{ - argument_list_t *list; - - list = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (list, token_node_t); - node->token = talloc_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; -} - -static 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; -} - -static 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; - } - } -} - -int -_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b) -{ - token_node_t *node_a, *node_b; - - node_a = a->head; - node_b = b->head; - - while (1) - { - if (node_a == NULL && node_b == NULL) - break; - - if (node_a == NULL || node_b == NULL) - return 0; - - if (node_a->token->type == SPACE) { - node_a = node_a->next; - continue; - } - - if (node_b->token->type == SPACE) { - node_b = node_b->next; - continue; - } - - if (node_a->token->type != node_b->token->type) - return 0; - - switch (node_a->token->type) { - case INTEGER: - if (node_a->token->value.ival != - node_b->token->value.ival) - { - return 0; - } - break; - case IDENTIFIER: - case INTEGER_STRING: - case OTHER: - if (strcmp (node_a->token->value.str, - node_b->token->value.str)) - { - return 0; - } - break; - } - - node_a = node_a->next; - node_b = node_b->next; - } - - return 1; -} - -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, "%" PRIiMAX, 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 = talloc_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); -} - -static void add_builtin_define(glcpp_parser_t *parser, - const char *name, int value) -{ - token_t *tok; - token_list_t *list; - - tok = _token_create_ival (parser, INTEGER, value); - - list = _token_list_create(parser); - _token_list_append(list, tok); - _define_object_macro(parser, NULL, name, list); - - talloc_unlink(parser, tok); -} - -glcpp_parser_t * -glcpp_parser_create (const struct gl_extensions *extensions, int api) -{ - glcpp_parser_t *parser; - int language_version; - - parser = talloc (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; - - /* Add pre-defined macros. */ - add_builtin_define(parser, "GL_ARB_draw_buffers", 1); - add_builtin_define(parser, "GL_ARB_texture_rectangle", 1); - - if (api == API_OPENGLES2) - add_builtin_define(parser, "GL_ES", 1); - - if (extensions != NULL) { - if (extensions->EXT_texture_array) { - add_builtin_define(parser, "GL_EXT_texture_array", 1); - } - - if (extensions->ARB_fragment_coord_conventions) - add_builtin_define(parser, "GL_ARB_fragment_coord_conventions", - 1); - } - - language_version = 110; - add_builtin_define(parser, "__VERSION__", language_version); - - return parser; -} - -int -glcpp_parser_parse (glcpp_parser_t *parser) -{ - return yyparse (parser); -} - -void -glcpp_parser_destroy (glcpp_parser_t *parser) -{ - 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; -} - -static token_list_t * -_token_list_create_with_one_space (void *ctx) -{ - token_list_t *list; - token_t *space; - - list = _token_list_create (ctx); - space = _token_create_ival (list, SPACE, SPACE); - _token_list_append (list, space); - - return list; -} - -static void -_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list) -{ - token_list_t *expanded; - token_t *token; - - expanded = _token_list_create (parser); - token = _token_create_ival (parser, type, type); - _token_list_append (expanded, token); - _glcpp_parser_expand_token_list (parser, list); - _token_list_append_list (expanded, list); - glcpp_parser_lex_from (parser, expanded); -} - -/* 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. Specifically, *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; - } - - /* Replace a macro defined as empty with a SPACE token. */ - if (macro->replacements == NULL) { - talloc_free (arguments); - return _token_list_create_with_one_space (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) { - token_list_t *expanded_argument; - expanded_argument = _token_list_copy (parser, - argument); - _glcpp_parser_expand_token_list (parser, - expanded_argument); - _token_list_append_list (substituted, - expanded_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. Specifically, *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 = talloc_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; - - /* Replace a macro defined as empty with a SPACE token. */ - if (macro->replacements == NULL) - return _token_list_create_with_one_space (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 = talloc (list, active_list_t); - node->identifier = talloc_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); -} - -static 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"); - } -} - -static int -_macro_equal (macro_t *a, macro_t *b) -{ - if (a->is_function != b->is_function) - return 0; - - if (a->is_function) { - if (! _string_list_equal (a->parameters, b->parameters)) - return 0; - } - - return _token_list_equal_ignoring_space (a->replacements, - b->replacements); -} - -void -_define_object_macro (glcpp_parser_t *parser, - YYLTYPE *loc, - const char *identifier, - token_list_t *replacements) -{ - macro_t *macro, *previous; - - if (loc != NULL) - _check_for_reserved_macro_name(parser, loc, identifier); - - macro = talloc (parser, macro_t); - - macro->is_function = 0; - macro->parameters = NULL; - macro->identifier = talloc_strdup (macro, identifier); - macro->replacements = talloc_steal (macro, replacements); - - previous = hash_table_find (parser->defines, identifier); - if (previous) { - if (_macro_equal (macro, previous)) { - talloc_free (macro); - return; - } - glcpp_error (loc, parser, "Redefinition of macro %s\n", - identifier); - } - - 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, *previous; - - _check_for_reserved_macro_name(parser, loc, identifier); - - macro = talloc (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); - - previous = hash_table_find (parser->defines, identifier); - if (previous) { - if (_macro_equal (macro, previous)) { - talloc_free (macro); - return; - } - glcpp_error (loc, parser, "Redefinition of macro %s\n", - identifier); - } - - 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 = talloc (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); -} +%{
+/*
+ * 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 <string.h>
+#include <assert.h>
+#include <inttypes.h>
+
+#include "glcpp.h"
+#include "main/core.h" /* for struct gl_extensions */
+#include "main/mtypes.h" /* for gl_api enum */
+
+#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 int
+_string_list_equal (string_list_t *a, string_list_t *b);
+
+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 int
+_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b);
+
+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_if (glcpp_parser_t *parser, int type, token_list_t *list);
+
+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);
+
+static void
+add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
+
+%}
+
+%pure-parser
+%error-verbose
+
+%locations
+%initial-action {
+ @$.first_line = 1;
+ @$.first_column = 1;
+ @$.last_line = 1;
+ @$.last_column = 1;
+ @$.source = 0;
+}
+
+%parse-param {glcpp_parser_t *parser}
+%lex-param {glcpp_parser_t *parser}
+
+%expect 0
+%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 HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING NEWLINE OTHER PLACEHOLDER SPACE
+%token PASTE
+%type <ival> expression INTEGER operator SPACE integer_constant
+%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) {
+ hash_table_remove (parser->defines, $2);
+ talloc_free (macro);
+ }
+ talloc_free ($2);
+ }
+| HASH_IF conditional_tokens NEWLINE {
+ /* Be careful to only evaluate the 'if' expression if
+ * we are not skipping. When we are skipping, we
+ * simply push a new 0-valued 'if' onto the skip
+ * stack.
+ *
+ * This avoids generating diagnostics for invalid
+ * expressions that are being skipped. */
+ if (parser->skip_stack == NULL ||
+ parser->skip_stack->type == SKIP_NO_SKIP)
+ {
+ _glcpp_parser_expand_if (parser, IF_EXPANDED, $2);
+ }
+ else
+ {
+ _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
+ parser->skip_stack->type = SKIP_TO_ENDIF;
+ }
+ }
+| HASH_IF NEWLINE {
+ /* #if without an expression is only an error if we
+ * are not skipping */
+ if (parser->skip_stack == NULL ||
+ parser->skip_stack->type == SKIP_NO_SKIP)
+ {
+ glcpp_error(& @1, parser, "#if with no expression");
+ }
+ _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
+ }
+| 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 {
+ /* Be careful to only evaluate the 'elif' expression
+ * if we are not skipping. When we are skipping, we
+ * simply change to a 0-valued 'elif' on the skip
+ * stack.
+ *
+ * This avoids generating diagnostics for invalid
+ * expressions that are being skipped. */
+ if (parser->skip_stack &&
+ parser->skip_stack->type == SKIP_TO_ELSE)
+ {
+ _glcpp_parser_expand_if (parser, ELIF_EXPANDED, $2);
+ }
+ else
+ {
+ _glcpp_parser_skip_stack_change_if (parser, & @1,
+ "elif", 0);
+ }
+ }
+| HASH_ELIF NEWLINE {
+ /* #elif without an expression is an error unless we
+ * are skipping. */
+ if (parser->skip_stack &&
+ parser->skip_stack->type == SKIP_TO_ELSE)
+ {
+ glcpp_error(& @1, parser, "#elif with no expression");
+ }
+ else
+ {
+ _glcpp_parser_skip_stack_change_if (parser, & @1,
+ "elif", 0);
+ glcpp_warning(& @1, parser, "ignoring illegal #elif without 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_VERSION integer_constant NEWLINE {
+ macro_t *macro = hash_table_find (parser->defines, "__VERSION__");
+ if (macro) {
+ hash_table_remove (parser->defines, "__VERSION__");
+ talloc_free (macro);
+ }
+ add_builtin_define (parser, "__VERSION__", $2);
+
+ if ($2 == 100)
+ add_builtin_define (parser, "GL_ES", 1);
+
+ /* Currently, all ES2 implementations support highp in the
+ * fragment shader, so we always define this macro in ES2.
+ * If we ever get a driver that doesn't support highp, we'll
+ * need to add a flag to the gl_context and check that here.
+ */
+ if ($2 >= 130 || $2 == 100)
+ add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
+
+ glcpp_printf(parser->output, "#version %" PRIiMAX, $2);
+ }
+| HASH NEWLINE
+;
+
+integer_constant:
+ 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:
+ integer_constant
+| 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 {
+ $$ = _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; }
+;
+
+%%
+
+string_list_t *
+_string_list_create (void *ctx)
+{
+ string_list_t *list;
+
+ list = talloc (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 = talloc (list, string_node_t);
+ node->str = talloc_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;
+}
+
+int
+_string_list_equal (string_list_t *a, string_list_t *b)
+{
+ string_node_t *node_a, *node_b;
+
+ if (a == NULL && b == NULL)
+ return 1;
+
+ if (a == NULL || b == NULL)
+ return 0;
+
+ for (node_a = a->head, node_b = b->head;
+ node_a && node_b;
+ node_a = node_a->next, node_b = node_b->next)
+ {
+ if (strcmp (node_a->str, node_b->str))
+ return 0;
+ }
+
+ /* Catch the case of lists being different lengths, (which
+ * would cause the loop above to terminate after the shorter
+ * list). */
+ return node_a == node_b;
+}
+
+argument_list_t *
+_argument_list_create (void *ctx)
+{
+ argument_list_t *list;
+
+ list = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (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 = talloc (list, token_node_t);
+ node->token = talloc_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;
+}
+
+static 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;
+}
+
+static 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;
+ }
+ }
+}
+
+int
+_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
+{
+ token_node_t *node_a, *node_b;
+
+ node_a = a->head;
+ node_b = b->head;
+
+ while (1)
+ {
+ if (node_a == NULL && node_b == NULL)
+ break;
+
+ if (node_a == NULL || node_b == NULL)
+ return 0;
+
+ if (node_a->token->type == SPACE) {
+ node_a = node_a->next;
+ continue;
+ }
+
+ if (node_b->token->type == SPACE) {
+ node_b = node_b->next;
+ continue;
+ }
+
+ if (node_a->token->type != node_b->token->type)
+ return 0;
+
+ switch (node_a->token->type) {
+ case INTEGER:
+ if (node_a->token->value.ival !=
+ node_b->token->value.ival)
+ {
+ return 0;
+ }
+ break;
+ case IDENTIFIER:
+ case INTEGER_STRING:
+ case OTHER:
+ if (strcmp (node_a->token->value.str,
+ node_b->token->value.str))
+ {
+ return 0;
+ }
+ break;
+ }
+
+ node_a = node_a->next;
+ node_b = node_b->next;
+ }
+
+ return 1;
+}
+
+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, "%" PRIiMAX, 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 = talloc_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);
+}
+
+static void add_builtin_define(glcpp_parser_t *parser,
+ const char *name, int value)
+{
+ token_t *tok;
+ token_list_t *list;
+
+ tok = _token_create_ival (parser, INTEGER, value);
+
+ list = _token_list_create(parser);
+ _token_list_append(list, tok);
+ _define_object_macro(parser, NULL, name, list);
+
+ talloc_unlink(parser, tok);
+}
+
+glcpp_parser_t *
+glcpp_parser_create (const struct gl_extensions *extensions, int api)
+{
+ glcpp_parser_t *parser;
+ int language_version;
+
+ parser = talloc (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;
+
+ /* Add pre-defined macros. */
+ add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
+ add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
+
+ if (api == API_OPENGLES2)
+ add_builtin_define(parser, "GL_ES", 1);
+
+ if (extensions != NULL) {
+ if (extensions->EXT_texture_array) {
+ add_builtin_define(parser, "GL_EXT_texture_array", 1);
+ }
+
+ if (extensions->ARB_fragment_coord_conventions)
+ add_builtin_define(parser, "GL_ARB_fragment_coord_conventions",
+ 1);
+
+ if (extensions->ARB_explicit_attrib_location)
+ add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1);
+ }
+
+ language_version = 110;
+ add_builtin_define(parser, "__VERSION__", language_version);
+
+ return parser;
+}
+
+int
+glcpp_parser_parse (glcpp_parser_t *parser)
+{
+ return yyparse (parser);
+}
+
+void
+glcpp_parser_destroy (glcpp_parser_t *parser)
+{
+ 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;
+}
+
+static token_list_t *
+_token_list_create_with_one_space (void *ctx)
+{
+ token_list_t *list;
+ token_t *space;
+
+ list = _token_list_create (ctx);
+ space = _token_create_ival (list, SPACE, SPACE);
+ _token_list_append (list, space);
+
+ return list;
+}
+
+static void
+_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list)
+{
+ token_list_t *expanded;
+ token_t *token;
+
+ expanded = _token_list_create (parser);
+ token = _token_create_ival (parser, type, type);
+ _token_list_append (expanded, token);
+ _glcpp_parser_expand_token_list (parser, list);
+ _token_list_append_list (expanded, list);
+ glcpp_parser_lex_from (parser, expanded);
+}
+
+/* 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. Specifically, *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;
+ }
+
+ /* Replace a macro defined as empty with a SPACE token. */
+ if (macro->replacements == NULL) {
+ talloc_free (arguments);
+ return _token_list_create_with_one_space (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) {
+ token_list_t *expanded_argument;
+ expanded_argument = _token_list_copy (parser,
+ argument);
+ _glcpp_parser_expand_token_list (parser,
+ expanded_argument);
+ _token_list_append_list (substituted,
+ expanded_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. Specifically, *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 = talloc_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;
+
+ /* Replace a macro defined as empty with a SPACE token. */
+ if (macro->replacements == NULL)
+ return _token_list_create_with_one_space (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 = talloc (list, active_list_t);
+ node->identifier = talloc_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);
+}
+
+static 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");
+ }
+}
+
+static int
+_macro_equal (macro_t *a, macro_t *b)
+{
+ if (a->is_function != b->is_function)
+ return 0;
+
+ if (a->is_function) {
+ if (! _string_list_equal (a->parameters, b->parameters))
+ return 0;
+ }
+
+ return _token_list_equal_ignoring_space (a->replacements,
+ b->replacements);
+}
+
+void
+_define_object_macro (glcpp_parser_t *parser,
+ YYLTYPE *loc,
+ const char *identifier,
+ token_list_t *replacements)
+{
+ macro_t *macro, *previous;
+
+ if (loc != NULL)
+ _check_for_reserved_macro_name(parser, loc, identifier);
+
+ macro = talloc (parser, macro_t);
+
+ macro->is_function = 0;
+ macro->parameters = NULL;
+ macro->identifier = talloc_strdup (macro, identifier);
+ macro->replacements = talloc_steal (macro, replacements);
+
+ previous = hash_table_find (parser->defines, identifier);
+ if (previous) {
+ if (_macro_equal (macro, previous)) {
+ talloc_free (macro);
+ return;
+ }
+ glcpp_error (loc, parser, "Redefinition of macro %s\n",
+ identifier);
+ }
+
+ 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, *previous;
+
+ _check_for_reserved_macro_name(parser, loc, identifier);
+
+ macro = talloc (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);
+
+ previous = hash_table_find (parser->defines, identifier);
+ if (previous) {
+ if (_macro_equal (macro, previous)) {
+ talloc_free (macro);
+ return;
+ }
+ glcpp_error (loc, parser, "Redefinition of macro %s\n",
+ identifier);
+ }
+
+ 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 = talloc (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);
+}
diff --git a/mesalib/src/glsl/glcpp/glcpp.c b/mesalib/src/glsl/glcpp/glcpp.c index 419b1fc25..016d7f97e 100644 --- a/mesalib/src/glsl/glcpp/glcpp.c +++ b/mesalib/src/glsl/glcpp/glcpp.c @@ -1,131 +1,139 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include "glcpp.h" -#include "main/mtypes.h" - -#ifdef _MSC_VER -#include <io.h> -#define STDIN_FILENO 0 -#define read _read -#define open _open -#define close _close -#endif - -extern int yydebug; - -/* Read from fd until EOF and return a string of everything read. - */ -static char * -load_text_fd (void *ctx, int fd) -{ -#define CHUNK 4096 - char *text = NULL; - ssize_t text_size = 0; - ssize_t total_read = 0; - ssize_t bytes; - - while (1) { - if (total_read + CHUNK + 1 > text_size) { - text_size = text_size ? text_size * 2 : CHUNK + 1; - text = talloc_realloc_size (ctx, text, text_size); - if (text == NULL) { - fprintf (stderr, "Out of memory\n"); - return NULL; - } - } - bytes = read (fd, text + total_read, CHUNK); - if (bytes < 0) { - fprintf (stderr, "Error while reading: %s\n", - strerror (errno)); - talloc_free (text); - return NULL; - } - - if (bytes == 0) { - break; - } - - total_read += bytes; - } - - text[total_read] = '\0'; - - return text; -} - -static char * -load_text_file(void *ctx, const char *filename) -{ - char *text; - int fd; - - if (filename == NULL || strcmp (filename, "-") == 0) - return load_text_fd (ctx, STDIN_FILENO); - - fd = open (filename, O_RDONLY); - if (fd < 0) { - fprintf (stderr, "Failed to open file %s: %s\n", - filename, strerror (errno)); - return NULL; - } - - text = load_text_fd (ctx, fd); - - close(fd); - - return text; -} - -int -main (int argc, char *argv[]) -{ - char *filename = NULL; - void *ctx = talloc(NULL, void*); - char *info_log = talloc_strdup(ctx, ""); - const char *shader; - int ret; - - if (argc) { - filename = argv[1]; - } - - shader = load_text_file (ctx, filename); - if (shader == NULL) - return 1; - - ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL); - - printf("%s", shader); - fprintf(stderr, "%s", info_log); - - talloc_free(ctx); - - return ret; -} +/*
+ * 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 <string.h>
+#include <errno.h>
+#include "glcpp.h"
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
+
+#ifdef _MSC_VER
+#include <io.h>
+#define STDIN_FILENO 0
+#define read _read
+#define open _open
+#define close _close
+#endif
+
+extern int yydebug;
+
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh)
+{
+ *ptr = sh;
+}
+
+/* Read from fd until EOF and return a string of everything read.
+ */
+static char *
+load_text_fd (void *ctx, int fd)
+{
+#define CHUNK 4096
+ char *text = NULL;
+ ssize_t text_size = 0;
+ ssize_t total_read = 0;
+ ssize_t bytes;
+
+ while (1) {
+ if (total_read + CHUNK + 1 > text_size) {
+ text_size = text_size ? text_size * 2 : CHUNK + 1;
+ text = talloc_realloc_size (ctx, text, text_size);
+ if (text == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ return NULL;
+ }
+ }
+ bytes = read (fd, text + total_read, CHUNK);
+ if (bytes < 0) {
+ fprintf (stderr, "Error while reading: %s\n",
+ strerror (errno));
+ talloc_free (text);
+ return NULL;
+ }
+
+ if (bytes == 0) {
+ break;
+ }
+
+ total_read += bytes;
+ }
+
+ text[total_read] = '\0';
+
+ return text;
+}
+
+static char *
+load_text_file(void *ctx, const char *filename)
+{
+ char *text;
+ int fd;
+
+ if (filename == NULL || strcmp (filename, "-") == 0)
+ return load_text_fd (ctx, STDIN_FILENO);
+
+ fd = open (filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf (stderr, "Failed to open file %s: %s\n",
+ filename, strerror (errno));
+ return NULL;
+ }
+
+ text = load_text_fd (ctx, fd);
+
+ close(fd);
+
+ return text;
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *filename = NULL;
+ void *ctx = talloc(NULL, void*);
+ char *info_log = talloc_strdup(ctx, "");
+ const char *shader;
+ int ret;
+
+ if (argc) {
+ filename = argv[1];
+ }
+
+ shader = load_text_file (ctx, filename);
+ if (shader == NULL)
+ return 1;
+
+ ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL);
+
+ printf("%s", shader);
+ fprintf(stderr, "%s", info_log);
+
+ talloc_free(ctx);
+
+ return ret;
+}
diff --git a/mesalib/src/glsl/glsl_lexer.cpp b/mesalib/src/glsl/glsl_lexer.cpp index 7661bbe98..79956e076 100644 --- a/mesalib/src/glsl/glsl_lexer.cpp +++ b/mesalib/src/glsl/glsl_lexer.cpp @@ -1,3488 +1,3688 @@ -#line 2 "glsl_lexer.cpp" - -#line 4 "glsl_lexer.cpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE _mesa_glsl_restart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via _mesa_glsl_restart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void _mesa_glsl_restart (FILE *input_file ,yyscan_t yyscanner ); -void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner ); - -static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner ); -static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner ); -static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER _mesa_glsl__flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE _mesa_glsl__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *_mesa_glsl_alloc (yy_size_t ,yyscan_t yyscanner ); -void *_mesa_glsl_realloc (void *,yy_size_t ,yyscan_t yyscanner ); -void _mesa_glsl_free (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer _mesa_glsl__create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - _mesa_glsl_ensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - _mesa_glsl_ensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define _mesa_glsl_wrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 183 -#define YY_END_OF_BUFFER 184 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[708] = - { 0, - 0, 0, 15, 15, 0, 0, 184, 182, 1, 20, - 182, 182, 182, 182, 182, 182, 182, 182, 96, 94, - 182, 182, 182, 181, 182, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 182, 1, 182, 91, 183, - 15, 19, 183, 18, 16, 17, 13, 12, 1, 80, - 87, 81, 90, 84, 75, 86, 76, 93, 98, 85, - 99, 96, 0, 0, 101, 0, 94, 0, 77, 79, - 78, 0, 181, 83, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 28, 181, 181, 181, - - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 32, 181, 181, 56, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 92, 82, 1, 0, 0, - 2, 0, 0, 0, 0, 15, 14, 18, 17, 0, - 98, 97, 0, 99, 0, 100, 95, 88, 89, 181, - 104, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 31, 181, 181, 181, 181, 181, 181, 181, - - 181, 181, 181, 25, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 57, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 0, 0, 0, 0, 14, 0, 98, 0, - 97, 0, 99, 100, 181, 181, 23, 181, 181, 144, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 30, - 107, 181, 181, 181, 181, 63, 181, 181, 112, 126, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 123, 147, 44, 45, 46, 181, 181, 181, 181, - - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 110, 102, 181, 181, - 181, 181, 181, 181, 181, 41, 42, 43, 73, 181, - 181, 0, 0, 0, 0, 0, 97, 181, 181, 26, - 35, 36, 37, 181, 105, 181, 22, 181, 181, 181, - 181, 134, 135, 136, 181, 103, 181, 127, 24, 137, - 138, 139, 149, 131, 132, 133, 181, 181, 181, 58, - 129, 181, 181, 38, 39, 40, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 124, 181, 181, 181, 181, 181, 181, 181, - - 181, 181, 181, 106, 181, 146, 181, 181, 29, 0, - 0, 0, 0, 153, 181, 181, 151, 181, 181, 181, - 125, 120, 156, 181, 181, 181, 181, 181, 181, 115, - 181, 181, 74, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 181, 181, 181, 181, 130, 111, 181, 181, - 118, 34, 181, 181, 143, 64, 119, 72, 154, 113, - 181, 181, 181, 181, 181, 181, 181, 0, 0, 0, - 0, 181, 181, 181, 114, 33, 181, 181, 181, 181, - 181, 181, 157, 158, 159, 181, 181, 181, 181, 148, - 181, 181, 181, 181, 181, 181, 181, 181, 108, 181, - - 181, 181, 181, 181, 59, 181, 60, 181, 0, 0, - 0, 0, 0, 181, 61, 27, 121, 161, 162, 163, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 116, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 109, 165, 166, 167, 181, 181, 128, 117, 0, - 0, 6, 0, 0, 0, 11, 3, 21, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 160, 122, 62, - 145, 181, 152, 150, 180, 66, 67, 68, 181, 181, - 181, 181, 181, 181, 0, 0, 0, 0, 0, 0, - 181, 181, 181, 164, 181, 181, 181, 181, 181, 181, - - 181, 181, 181, 181, 181, 181, 181, 181, 181, 168, - 4, 0, 5, 0, 0, 0, 0, 0, 181, 181, - 181, 181, 181, 181, 181, 177, 181, 181, 181, 181, - 181, 181, 69, 181, 181, 181, 0, 0, 0, 181, - 181, 178, 169, 181, 170, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 179, 0, 0, 171, 172, 175, - 176, 65, 181, 140, 181, 141, 155, 173, 174, 0, - 0, 181, 181, 181, 0, 0, 0, 70, 181, 71, - 0, 0, 0, 181, 0, 0, 0, 181, 0, 0, - 7, 0, 0, 181, 0, 8, 0, 0, 142, 0, - - 0, 0, 0, 9, 0, 10, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, - 10, 11, 12, 1, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 21, 21, 22, 22, 23, 1, 24, - 25, 26, 1, 1, 27, 28, 29, 30, 31, 32, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 34, 35, 33, 33, 33, 33, 36, 33, 33, - 1, 1, 1, 37, 38, 1, 39, 40, 41, 42, - - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 33, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 1, 64, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[65] = - { 0, - 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, - 4, 5, 1, 1, 1, 1, 6, 6, 6, 6, - 5, 5, 7, 7, 7, 8, 1, 7, 6, 6, - 6, 6, 5, 5, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 7, 7, 1 - } ; - -static yyconst flex_int16_t yy_base[719] = - { 0, - 0, 63, 88, 0, 1076, 1075, 1077, 1080, 64, 1080, - 1051, 1050, 59, 1049, 58, 60, 58, 1048, 139, 187, - 47, 1047, 56, 0, 1034, 121, 110, 137, 138, 134, - 163, 1017, 173, 177, 115, 149, 140, 1011, 159, 121, - 187, 194, 194, 172, 1022, 171, 249, 240, 1042, 1080, - 250, 1080, 1051, 241, 1080, 0, 1080, 1080, 262, 1080, - 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 236, 1080, - 238, 187, 286, 303, 1080, 0, 0, 1040, 1080, 1080, - 1080, 1039, 0, 1080, 1006, 1011, 1004, 1007, 1016, 1015, - 1001, 1004, 1016, 35, 1010, 997, 994, 1008, 994, 991, - - 991, 997, 215, 232, 991, 1002, 987, 993, 997, 998, - 0, 989, 1000, 234, 995, 975, 226, 979, 993, 983, - 119, 976, 234, 989, 991, 973, 969, 977, 974, 963, - 972, 256, 970, 976, 971, 974, 962, 965, 967, 245, - 970, 961, 974, 227, 967, 1080, 1080, 308, 294, 324, - 1080, 952, 965, 956, 967, 329, 0, 338, 0, 368, - 1080, 303, 379, 1080, 386, 393, 0, 1080, 1080, 962, - 0, 953, 957, 967, 964, 947, 946, 946, 950, 216, - 961, 958, 958, 956, 953, 944, 951, 937, 935, 948, - 933, 950, 0, 947, 934, 942, 939, 943, 944, 937, - - 934, 922, 921, 935, 938, 935, 922, 929, 919, 320, - 925, 928, 918, 926, 914, 918, 909, 924, 914, 905, - 924, 907, 905, 916, 905, 900, 898, 912, 897, 899, - 896, 908, 907, 910, 288, 901, 895, 884, 331, 903, - 905, 893, 885, 889, 901, 884, 0, 400, 410, 427, - 1080, 439, 446, 1080, 879, 890, 0, 887, 343, 0, - 880, 878, 880, 875, 884, 872, 890, 878, 346, 0, - 0, 872, 883, 882, 882, 0, 866, 350, 0, 0, - 868, 353, 876, 877, 867, 861, 860, 861, 860, 357, - 856, 0, 0, 852, 851, 850, 852, 853, 858, 852, - - 848, 862, 857, 856, 855, 846, 849, 849, 841, 844, - 839, 848, 853, 838, 851, 841, 0, 0, 848, 844, - 835, 835, 841, 840, 837, 0, 0, 0, 0, 826, - 839, 838, 837, 834, 822, 453, 463, 834, 836, 0, - 0, 0, 0, 822, 0, 822, 0, 821, 822, 816, - 827, 0, 0, 0, 817, 0, 813, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 824, 469, 823, 0, - 0, 821, 817, 0, 0, 0, 806, 415, 432, 473, - 811, 807, 813, 803, 801, 815, 799, 799, 813, 801, - 813, 808, 0, 806, 803, 807, 790, 792, 799, 805, - - 800, 799, 786, 0, 788, 0, 787, 791, 0, 785, - 834, 784, 787, 0, 775, 785, 0, 773, 773, 787, - 0, 789, 0, 482, 797, 796, 795, 766, 765, 0, - 783, 782, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 766, 780, 766, 763, 0, 0, 769, 768, - 0, 0, 766, 758, 0, 0, 0, 0, 0, 0, - 755, 767, 485, 759, 766, 763, 757, 750, 503, 766, - 751, 746, 760, 758, 0, 0, 750, 769, 768, 767, - 738, 737, 301, 481, 0, 750, 753, 751, 739, 0, - 749, 746, 745, 734, 733, 732, 509, 741, 0, 753, - - 752, 751, 722, 721, 0, 736, 0, 734, 729, 515, - 527, 773, 722, 730, 0, 0, 0, 745, 744, 0, - 726, 729, 713, 721, 711, 719, 720, 720, 719, 704, - 717, 0, 718, 706, 705, 701, 725, 724, 723, 694, - 693, 0, 723, 722, 0, 704, 707, 0, 0, 693, - 537, 1080, 561, 0, 567, 340, 1080, 0, 690, 689, - 699, 699, 686, 701, 684, 699, 694, 0, 0, 0, - 0, 679, 0, 0, 0, 700, 389, 700, 689, 692, - 676, 675, 685, 685, 675, 529, 589, 474, 683, 671, - 669, 668, 679, 0, 682, 678, 680, 676, 662, 669, - - 669, 671, 667, 669, 667, 667, 654, 653, 664, 0, - 1080, 531, 1080, 596, 0, 616, 666, 648, 665, 664, - 647, 635, 643, 633, 634, 0, 627, 646, 635, 607, - 604, 601, 0, 604, 603, 586, 533, 572, 580, 564, - 563, 0, 0, 564, 0, 540, 554, 552, 516, 530, - 505, 486, 453, 450, 0, 461, 443, 0, 0, 0, - 0, 0, 400, 406, 385, 0, 0, 0, 0, 343, - 389, 319, 267, 249, 487, 341, 235, 0, 200, 0, - 507, 498, 184, 157, 150, 564, 559, 136, 565, 591, - 1080, 593, 550, 112, 594, 1080, 569, 576, 0, 123, - - 619, 621, 637, 1080, 638, 1080, 1080, 648, 653, 658, - 663, 665, 667, 673, 680, 685, 690, 695 - } ; - -static yyconst flex_int16_t yy_def[719] = - { 0, - 707, 1, 707, 3, 708, 708, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 709, 707, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 710, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 711, 707, - 712, 19, 707, 707, 707, 713, 20, 707, 707, 707, - 707, 707, 709, 707, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 714, 707, 710, 707, - 707, 712, 707, 707, 707, 707, 713, 707, 707, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 707, 707, 707, 707, 714, 707, 707, 707, - 707, 707, 707, 707, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 707, 707, 707, 707, 707, 707, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 709, 709, 707, - 707, 707, 707, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 707, 707, 707, - 707, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 709, 707, 715, - 707, 707, 707, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 707, - 707, 707, 707, 716, 707, 707, 707, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 707, 717, 707, 716, 707, 707, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 707, 707, 707, 707, 718, 707, 707, 707, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 718, 707, 707, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 707, 707, 709, 709, 709, - 709, 709, 709, 709, 709, 709, 709, 709, 709, 707, - 707, 709, 709, 709, 707, 707, 707, 709, 709, 709, - 707, 707, 707, 709, 707, 707, 707, 709, 707, 707, - 707, 707, 707, 709, 707, 707, 707, 707, 709, 707, - - 707, 707, 707, 707, 707, 707, 0, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707 - } ; - -static yyconst flex_int16_t yy_nxt[1145] = - { 0, - 8, 9, 10, 9, 11, 8, 12, 13, 8, 8, - 14, 15, 16, 17, 18, 19, 20, 20, 20, 20, - 20, 20, 8, 21, 22, 23, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 25, 24, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 24, 24, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 24, 24, 24, 46, 47, 59, 62, 59, 48, 65, - 78, 79, 67, 69, 69, 69, 69, 69, 69, 69, - 81, 82, 66, 63, 68, 179, 180, 49, 50, 51, - 52, 51, 50, 50, 50, 50, 50, 50, 50, 50, - - 50, 50, 53, 50, 54, 54, 54, 54, 54, 54, - 55, 50, 50, 50, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 50, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 50, 71, 116, 72, 72, 72, 72, 72, 72, - 73, 85, 88, 126, 89, 213, 702, 117, 90, 74, - 75, 699, 214, 127, 76, 91, 86, 87, 120, 92, - 95, 74, 75, 99, 96, 100, 93, 118, 694, 94, - 97, 119, 121, 689, 101, 146, 98, 123, 688, 76, - - 71, 102, 77, 77, 77, 77, 77, 77, 77, 103, - 142, 108, 104, 124, 143, 105, 125, 74, 75, 109, - 111, 106, 707, 112, 144, 128, 687, 113, 114, 74, - 75, 110, 129, 130, 147, 115, 135, 131, 684, 136, - 139, 150, 151, 132, 133, 140, 134, 707, 137, 141, - 148, 156, 59, 156, 149, 138, 158, 158, 158, 158, - 158, 158, 158, 59, 189, 59, 160, 161, 163, 164, - 191, 264, 265, 240, 216, 190, 241, 208, 160, 161, - 163, 164, 152, 201, 192, 209, 202, 203, 217, 153, - 204, 235, 205, 154, 226, 150, 151, 683, 155, 71, - - 236, 73, 73, 73, 73, 73, 73, 73, 680, 148, - 227, 59, 679, 149, 165, 165, 74, 75, 166, 166, - 166, 166, 166, 166, 166, 150, 151, 523, 74, 75, - 156, 321, 156, 250, 251, 524, 152, 294, 295, 296, - 322, 556, 681, 153, 675, 250, 251, 154, 326, 327, - 328, 676, 155, 158, 158, 158, 158, 158, 158, 158, - 341, 342, 343, 352, 353, 354, 152, 360, 361, 362, - 364, 365, 366, 153, 374, 375, 376, 154, 678, 248, - 248, 589, 155, 249, 249, 249, 249, 249, 249, 249, - 252, 252, 590, 682, 253, 253, 253, 253, 253, 253, - - 253, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 249, 249, 249, 249, 249, - 249, 249, 602, 603, 254, 249, 249, 249, 249, 249, - 249, 249, 434, 435, 436, 677, 254, 674, 336, 336, - 673, 161, 337, 337, 337, 337, 337, 337, 337, 437, - 438, 439, 672, 161, 253, 253, 253, 253, 253, 253, - 253, 253, 253, 253, 253, 253, 253, 253, 337, 337, - 337, 337, 337, 337, 337, 551, 552, 164, 337, 337, - 337, 337, 337, 337, 337, 425, 426, 427, 675, 164, - 440, 441, 442, 671, 251, 676, 428, 429, 478, 479, - - 480, 500, 501, 502, 469, 670, 251, 525, 681, 481, - 482, 669, 503, 504, 668, 526, 551, 552, 510, 511, - 511, 511, 511, 511, 511, 537, 538, 539, 551, 552, - 612, 613, 612, 613, 612, 613, 540, 541, 551, 552, - 667, 685, 555, 555, 555, 555, 555, 555, 555, 686, - 554, 697, 586, 587, 587, 587, 587, 587, 587, 682, - 692, 666, 551, 552, 615, 690, 695, 693, 551, 552, - 697, 665, 664, 691, 696, 554, 553, 553, 553, 553, - 553, 553, 555, 555, 555, 555, 555, 555, 555, 615, - 612, 613, 690, 663, 692, 695, 662, 612, 613, 661, - - 691, 693, 698, 696, 616, 616, 616, 616, 616, 616, - 616, 614, 614, 614, 614, 614, 614, 612, 613, 700, - 703, 698, 705, 660, 659, 658, 657, 701, 704, 656, - 706, 616, 616, 616, 616, 616, 616, 616, 703, 705, - 655, 654, 653, 652, 651, 650, 704, 706, 57, 57, - 57, 57, 57, 57, 57, 57, 83, 83, 83, 83, - 83, 159, 159, 159, 159, 159, 69, 69, 162, 162, - 167, 167, 167, 247, 247, 649, 247, 247, 247, 247, - 247, 553, 553, 553, 648, 647, 646, 553, 588, 588, - 588, 614, 614, 614, 645, 644, 643, 614, 637, 637, - - 637, 642, 641, 640, 639, 638, 636, 635, 634, 633, - 632, 631, 630, 629, 628, 627, 626, 625, 624, 623, - 622, 621, 620, 619, 618, 617, 611, 610, 609, 608, - 607, 606, 605, 604, 601, 600, 599, 598, 597, 596, - 595, 594, 593, 592, 591, 585, 584, 583, 582, 581, - 580, 579, 578, 577, 576, 575, 574, 573, 572, 571, - 570, 569, 568, 567, 566, 565, 564, 563, 562, 561, - 560, 559, 558, 557, 556, 550, 549, 548, 547, 546, - 545, 544, 543, 542, 536, 535, 534, 533, 532, 531, - 530, 529, 528, 527, 522, 521, 520, 519, 518, 517, - - 516, 515, 514, 513, 512, 509, 508, 507, 506, 505, - 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, - 489, 488, 487, 486, 485, 484, 483, 477, 476, 475, - 474, 473, 472, 471, 470, 469, 468, 467, 466, 465, - 464, 463, 462, 461, 460, 459, 458, 457, 456, 455, - 454, 453, 452, 451, 450, 449, 448, 447, 446, 445, - 444, 443, 433, 432, 431, 430, 424, 423, 422, 421, - 420, 419, 418, 417, 416, 415, 414, 413, 412, 411, - 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, - 400, 399, 398, 397, 396, 395, 394, 393, 392, 391, - - 390, 389, 388, 387, 386, 385, 384, 383, 382, 381, - 380, 379, 378, 377, 373, 372, 371, 370, 369, 368, - 367, 363, 359, 358, 357, 356, 355, 351, 350, 349, - 348, 347, 346, 345, 344, 340, 339, 338, 335, 334, - 333, 332, 331, 330, 329, 325, 324, 323, 320, 319, - 318, 317, 316, 315, 314, 313, 312, 311, 310, 309, - 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, - 298, 297, 293, 292, 291, 290, 289, 288, 287, 286, - 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, - 275, 274, 273, 272, 271, 270, 269, 268, 267, 266, - - 263, 262, 261, 260, 259, 258, 257, 256, 255, 246, - 245, 244, 243, 242, 239, 238, 237, 234, 233, 232, - 231, 230, 229, 228, 225, 224, 223, 222, 221, 220, - 219, 218, 215, 212, 211, 210, 207, 206, 200, 199, - 198, 197, 196, 195, 194, 193, 188, 187, 186, 185, - 184, 183, 182, 181, 178, 177, 176, 175, 174, 173, - 172, 171, 170, 169, 168, 157, 80, 145, 122, 107, - 84, 80, 70, 64, 61, 60, 707, 58, 58, 7, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707 - } ; - -static yyconst flex_int16_t yy_chk[1145] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 9, 13, 9, 2, 15, - 21, 21, 16, 17, 17, 17, 17, 17, 17, 17, - 23, 23, 15, 13, 16, 94, 94, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 19, 35, 19, 19, 19, 19, 19, 19, - 19, 26, 27, 40, 27, 121, 700, 35, 27, 19, - 19, 694, 121, 40, 19, 28, 26, 26, 37, 28, - 29, 19, 19, 30, 29, 30, 28, 36, 688, 28, - 29, 36, 37, 685, 30, 46, 29, 39, 684, 19, - - 20, 31, 20, 20, 20, 20, 20, 20, 20, 31, - 44, 33, 31, 39, 44, 31, 39, 20, 20, 33, - 34, 31, 72, 34, 44, 41, 683, 34, 34, 20, - 20, 33, 41, 41, 46, 34, 42, 41, 679, 42, - 43, 48, 48, 41, 41, 43, 41, 72, 42, 43, - 47, 51, 47, 51, 47, 42, 54, 54, 54, 54, - 54, 54, 54, 59, 103, 59, 69, 69, 71, 71, - 104, 180, 180, 144, 123, 103, 144, 117, 69, 69, - 71, 71, 48, 114, 104, 117, 114, 114, 123, 48, - 114, 140, 114, 48, 132, 149, 149, 677, 48, 73, - - 140, 73, 73, 73, 73, 73, 73, 73, 674, 148, - 132, 148, 673, 148, 74, 74, 73, 73, 74, 74, - 74, 74, 74, 74, 74, 150, 150, 483, 73, 73, - 156, 235, 156, 162, 162, 483, 149, 210, 210, 210, - 235, 556, 676, 149, 670, 162, 162, 149, 239, 239, - 239, 670, 149, 158, 158, 158, 158, 158, 158, 158, - 259, 259, 259, 269, 269, 269, 150, 278, 278, 278, - 282, 282, 282, 150, 290, 290, 290, 150, 672, 160, - 160, 556, 150, 160, 160, 160, 160, 160, 160, 160, - 163, 163, 556, 676, 163, 163, 163, 163, 163, 163, - - 163, 165, 165, 165, 165, 165, 165, 165, 166, 166, - 166, 166, 166, 166, 166, 248, 248, 248, 248, 248, - 248, 248, 577, 577, 166, 249, 249, 249, 249, 249, - 249, 249, 378, 378, 378, 671, 166, 665, 250, 250, - 664, 249, 250, 250, 250, 250, 250, 250, 250, 379, - 379, 379, 663, 249, 252, 252, 252, 252, 252, 252, - 252, 253, 253, 253, 253, 253, 253, 253, 336, 336, - 336, 336, 336, 336, 336, 588, 588, 253, 337, 337, - 337, 337, 337, 337, 337, 368, 368, 368, 675, 253, - 380, 380, 380, 657, 337, 675, 368, 368, 424, 424, - - 424, 463, 463, 463, 469, 656, 337, 484, 681, 424, - 424, 654, 463, 463, 653, 484, 510, 510, 469, 469, - 469, 469, 469, 469, 469, 497, 497, 497, 511, 511, - 586, 586, 612, 612, 637, 637, 497, 497, 551, 551, - 652, 682, 511, 511, 511, 511, 511, 511, 511, 682, - 510, 693, 551, 551, 551, 551, 551, 551, 551, 681, - 687, 651, 553, 553, 586, 686, 689, 687, 555, 555, - 697, 650, 649, 686, 689, 510, 553, 553, 553, 553, - 553, 553, 555, 555, 555, 555, 555, 555, 555, 586, - 587, 587, 690, 648, 692, 695, 647, 614, 614, 646, - - 690, 692, 693, 695, 587, 587, 587, 587, 587, 587, - 587, 614, 614, 614, 614, 614, 614, 616, 616, 698, - 701, 697, 702, 644, 641, 640, 639, 698, 701, 638, - 702, 616, 616, 616, 616, 616, 616, 616, 703, 705, - 636, 635, 634, 632, 631, 630, 703, 705, 708, 708, - 708, 708, 708, 708, 708, 708, 709, 709, 709, 709, - 709, 710, 710, 710, 710, 710, 711, 711, 712, 712, - 713, 713, 713, 714, 714, 629, 714, 714, 714, 714, - 714, 715, 715, 715, 628, 627, 625, 715, 716, 716, - 716, 717, 717, 717, 624, 623, 622, 717, 718, 718, - - 718, 621, 620, 619, 618, 617, 609, 608, 607, 606, - 605, 604, 603, 602, 601, 600, 599, 598, 597, 596, - 595, 593, 592, 591, 590, 589, 585, 584, 583, 582, - 581, 580, 579, 578, 576, 572, 567, 566, 565, 564, - 563, 562, 561, 560, 559, 550, 547, 546, 544, 543, - 541, 540, 539, 538, 537, 536, 535, 534, 533, 531, - 530, 529, 528, 527, 526, 525, 524, 523, 522, 521, - 519, 518, 514, 513, 512, 509, 508, 506, 504, 503, - 502, 501, 500, 498, 496, 495, 494, 493, 492, 491, - 489, 488, 487, 486, 482, 481, 480, 479, 478, 477, - - 474, 473, 472, 471, 470, 468, 467, 466, 465, 464, - 462, 461, 454, 453, 450, 449, 446, 445, 444, 443, - 432, 431, 429, 428, 427, 426, 425, 422, 420, 419, - 418, 416, 415, 413, 412, 411, 410, 408, 407, 405, - 403, 402, 401, 400, 399, 398, 397, 396, 395, 394, - 392, 391, 390, 389, 388, 387, 386, 385, 384, 383, - 382, 381, 377, 373, 372, 369, 367, 357, 355, 351, - 350, 349, 348, 346, 344, 339, 338, 335, 334, 333, - 332, 331, 330, 325, 324, 323, 322, 321, 320, 319, - 316, 315, 314, 313, 312, 311, 310, 309, 308, 307, - - 306, 305, 304, 303, 302, 301, 300, 299, 298, 297, - 296, 295, 294, 291, 289, 288, 287, 286, 285, 284, - 283, 281, 277, 275, 274, 273, 272, 268, 267, 266, - 265, 264, 263, 262, 261, 258, 256, 255, 246, 245, - 244, 243, 242, 241, 240, 238, 237, 236, 234, 233, - 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, - 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, - 212, 211, 209, 208, 207, 206, 205, 204, 203, 202, - 201, 200, 199, 198, 197, 196, 195, 194, 192, 191, - 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, - - 179, 178, 177, 176, 175, 174, 173, 172, 170, 155, - 154, 153, 152, 145, 143, 142, 141, 139, 138, 137, - 136, 135, 134, 133, 131, 130, 129, 128, 127, 126, - 125, 124, 122, 120, 119, 118, 116, 115, 113, 112, - 110, 109, 108, 107, 106, 105, 102, 101, 100, 99, - 98, 97, 96, 95, 93, 92, 91, 90, 89, 88, - 87, 86, 85, 82, 78, 53, 49, 45, 38, 32, - 25, 22, 18, 14, 12, 11, 7, 6, 5, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "glsl_lexer.lpp" -#line 2 "glsl_lexer.lpp" -/* - * 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); - -#define YY_USER_INIT yylineno = 0; yycolumn = 0; - -#define TOKEN_OR_IDENTIFIER(version, token) \ - do { \ - if (yyextra->language_version >= version) { \ - return token; \ - } else { \ - yylval->identifier = strdup(yytext); \ - return IDENTIFIER; \ - } \ - } while (0) - -/* Handle reserved words in GLSL ES (version 100) */ -#define TOKEN_OR_IDENTIFIER_ES(version, token) \ - do { \ - if (yyextra->es_shader) { \ - return token; \ - } else { \ - TOKEN_OR_IDENTIFIER(version, token); \ - } \ - } while (0) - -#define RESERVED_WORD(version, token) \ - do { \ - if (yyextra->language_version >= version) { \ - return token; \ - } else { \ - _mesa_glsl_error(yylloc, yyextra, \ - "Illegal use of reserved word `%s'", yytext); \ - return ERROR_TOK; \ - } \ - } while (0) - -#line 990 "glsl_lexer.cpp" - -#define INITIAL 0 -#define PP 1 -#define PRAGMA 2 - -#define YY_EXTRA_TYPE struct _mesa_glsl_parse_state * - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int _mesa_glsl_lex_init (yyscan_t* scanner); - -int _mesa_glsl_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int _mesa_glsl_lex_destroy (yyscan_t yyscanner ); - -int _mesa_glsl_get_debug (yyscan_t yyscanner ); - -void _mesa_glsl_set_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner ); - -void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *_mesa_glsl_get_in (yyscan_t yyscanner ); - -void _mesa_glsl_set_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *_mesa_glsl_get_out (yyscan_t yyscanner ); - -void _mesa_glsl_set_out (FILE * out_str ,yyscan_t yyscanner ); - -int _mesa_glsl_get_leng (yyscan_t yyscanner ); - -char *_mesa_glsl_get_text (yyscan_t yyscanner ); - -int _mesa_glsl_get_lineno (yyscan_t yyscanner ); - -void _mesa_glsl_set_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner ); - -void _mesa_glsl_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner ); - - void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int _mesa_glsl_wrap (yyscan_t yyscanner ); -#else -extern int _mesa_glsl_wrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - int n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int _mesa_glsl_lex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int _mesa_glsl_lex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 86 "glsl_lexer.lpp" - - -#line 1227 "glsl_lexer.cpp" - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - _mesa_glsl_ensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - _mesa_glsl__load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 708 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 707 ); - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 88 "glsl_lexer.lpp" -; - YY_BREAK -/* Preprocessor tokens. */ -case 2: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 91 "glsl_lexer.lpp" -; - YY_BREAK -case 3: -YY_RULE_SETUP -#line 92 "glsl_lexer.lpp" -{ BEGIN PP; return VERSION; } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 93 "glsl_lexer.lpp" -{ BEGIN PP; return EXTENSION; } - YY_BREAK -case 5: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 94 "glsl_lexer.lpp" -{ - /* 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); - } - YY_BREAK -case 6: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 109 "glsl_lexer.lpp" -{ - /* 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; - } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 123 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_DEBUG_ON; - } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 127 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_DEBUG_OFF; - } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 131 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_OPTIMIZE_ON; - } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 135 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_OPTIMIZE_OFF; - } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 139 "glsl_lexer.lpp" -{ BEGIN PRAGMA; } - YY_BREAK -case 12: -/* rule 12 can match eol */ -YY_RULE_SETUP -#line 141 "glsl_lexer.lpp" -{ BEGIN 0; yylineno++; yycolumn = 0; } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 142 "glsl_lexer.lpp" -{ } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 144 "glsl_lexer.lpp" -{ } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 145 "glsl_lexer.lpp" -{ } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 146 "glsl_lexer.lpp" -return COLON; - YY_BREAK -case 17: -YY_RULE_SETUP -#line 147 "glsl_lexer.lpp" -{ - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 151 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext, NULL, 10); - return INTCONSTANT; - } - YY_BREAK -case 19: -/* rule 19 can match eol */ -YY_RULE_SETUP -#line 155 "glsl_lexer.lpp" -{ BEGIN 0; yylineno++; yycolumn = 0; return EOL; } - YY_BREAK -case 20: -/* rule 20 can match eol */ -YY_RULE_SETUP -#line 157 "glsl_lexer.lpp" -{ yylineno++; yycolumn = 0; } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 159 "glsl_lexer.lpp" -return ATTRIBUTE; - YY_BREAK -case 22: -YY_RULE_SETUP -#line 160 "glsl_lexer.lpp" -return CONST_TOK; - YY_BREAK -case 23: -YY_RULE_SETUP -#line 161 "glsl_lexer.lpp" -return BOOL_TOK; - YY_BREAK -case 24: -YY_RULE_SETUP -#line 162 "glsl_lexer.lpp" -return FLOAT_TOK; - YY_BREAK -case 25: -YY_RULE_SETUP -#line 163 "glsl_lexer.lpp" -return INT_TOK; - YY_BREAK -case 26: -YY_RULE_SETUP -#line 165 "glsl_lexer.lpp" -return BREAK; - YY_BREAK -case 27: -YY_RULE_SETUP -#line 166 "glsl_lexer.lpp" -return CONTINUE; - YY_BREAK -case 28: -YY_RULE_SETUP -#line 167 "glsl_lexer.lpp" -return DO; - YY_BREAK -case 29: -YY_RULE_SETUP -#line 168 "glsl_lexer.lpp" -return WHILE; - YY_BREAK -case 30: -YY_RULE_SETUP -#line 169 "glsl_lexer.lpp" -return ELSE; - YY_BREAK -case 31: -YY_RULE_SETUP -#line 170 "glsl_lexer.lpp" -return FOR; - YY_BREAK -case 32: -YY_RULE_SETUP -#line 171 "glsl_lexer.lpp" -return IF; - YY_BREAK -case 33: -YY_RULE_SETUP -#line 172 "glsl_lexer.lpp" -return DISCARD; - YY_BREAK -case 34: -YY_RULE_SETUP -#line 173 "glsl_lexer.lpp" -return RETURN; - YY_BREAK -case 35: -YY_RULE_SETUP -#line 175 "glsl_lexer.lpp" -return BVEC2; - YY_BREAK -case 36: -YY_RULE_SETUP -#line 176 "glsl_lexer.lpp" -return BVEC3; - YY_BREAK -case 37: -YY_RULE_SETUP -#line 177 "glsl_lexer.lpp" -return BVEC4; - YY_BREAK -case 38: -YY_RULE_SETUP -#line 178 "glsl_lexer.lpp" -return IVEC2; - YY_BREAK -case 39: -YY_RULE_SETUP -#line 179 "glsl_lexer.lpp" -return IVEC3; - YY_BREAK -case 40: -YY_RULE_SETUP -#line 180 "glsl_lexer.lpp" -return IVEC4; - YY_BREAK -case 41: -YY_RULE_SETUP -#line 181 "glsl_lexer.lpp" -return VEC2; - YY_BREAK -case 42: -YY_RULE_SETUP -#line 182 "glsl_lexer.lpp" -return VEC3; - YY_BREAK -case 43: -YY_RULE_SETUP -#line 183 "glsl_lexer.lpp" -return VEC4; - YY_BREAK -case 44: -YY_RULE_SETUP -#line 184 "glsl_lexer.lpp" -return MAT2X2; - YY_BREAK -case 45: -YY_RULE_SETUP -#line 185 "glsl_lexer.lpp" -return MAT3X3; - YY_BREAK -case 46: -YY_RULE_SETUP -#line 186 "glsl_lexer.lpp" -return MAT4X4; - YY_BREAK -case 47: -YY_RULE_SETUP -#line 187 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT2X2); - YY_BREAK -case 48: -YY_RULE_SETUP -#line 188 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT2X3); - YY_BREAK -case 49: -YY_RULE_SETUP -#line 189 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT2X4); - YY_BREAK -case 50: -YY_RULE_SETUP -#line 190 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT3X2); - YY_BREAK -case 51: -YY_RULE_SETUP -#line 191 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT3X3); - YY_BREAK -case 52: -YY_RULE_SETUP -#line 192 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT3X4); - YY_BREAK -case 53: -YY_RULE_SETUP -#line 193 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT4X2); - YY_BREAK -case 54: -YY_RULE_SETUP -#line 194 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT4X3); - YY_BREAK -case 55: -YY_RULE_SETUP -#line 195 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, MAT4X4); - YY_BREAK -case 56: -YY_RULE_SETUP -#line 197 "glsl_lexer.lpp" -return IN_TOK; - YY_BREAK -case 57: -YY_RULE_SETUP -#line 198 "glsl_lexer.lpp" -return OUT_TOK; - YY_BREAK -case 58: -YY_RULE_SETUP -#line 199 "glsl_lexer.lpp" -return INOUT_TOK; - YY_BREAK -case 59: -YY_RULE_SETUP -#line 200 "glsl_lexer.lpp" -return UNIFORM; - YY_BREAK -case 60: -YY_RULE_SETUP -#line 201 "glsl_lexer.lpp" -return VARYING; - YY_BREAK -case 61: -YY_RULE_SETUP -#line 202 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(120, CENTROID); - YY_BREAK -case 62: -YY_RULE_SETUP -#line 203 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER_ES(120, INVARIANT); - YY_BREAK -case 63: -YY_RULE_SETUP -#line 205 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER_ES(130, FLAT); - YY_BREAK -case 64: -YY_RULE_SETUP -#line 206 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, SMOOTH); - YY_BREAK -case 65: -YY_RULE_SETUP -#line 207 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, NOPERSPECTIVE); - YY_BREAK -case 66: -YY_RULE_SETUP -#line 209 "glsl_lexer.lpp" -return SAMPLER1D; - YY_BREAK -case 67: -YY_RULE_SETUP -#line 210 "glsl_lexer.lpp" -return SAMPLER2D; - YY_BREAK -case 68: -YY_RULE_SETUP -#line 211 "glsl_lexer.lpp" -return SAMPLER3D; - YY_BREAK -case 69: -YY_RULE_SETUP -#line 212 "glsl_lexer.lpp" -return SAMPLERCUBE; - YY_BREAK -case 70: -YY_RULE_SETUP -#line 213 "glsl_lexer.lpp" -return SAMPLER1DSHADOW; - YY_BREAK -case 71: -YY_RULE_SETUP -#line 214 "glsl_lexer.lpp" -return SAMPLER2DSHADOW; - YY_BREAK -case 72: -YY_RULE_SETUP -#line 216 "glsl_lexer.lpp" -return STRUCT; - YY_BREAK -case 73: -YY_RULE_SETUP -#line 217 "glsl_lexer.lpp" -return VOID_TOK; - YY_BREAK -case 74: -YY_RULE_SETUP -#line 219 "glsl_lexer.lpp" -{ - if ((yyextra->language_version >= 140) - || (yyextra->ARB_fragment_coord_conventions_enable)){ - return LAYOUT_TOK; - } else { - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } - } - YY_BREAK -case 75: -YY_RULE_SETUP -#line 229 "glsl_lexer.lpp" -return INC_OP; - YY_BREAK -case 76: -YY_RULE_SETUP -#line 230 "glsl_lexer.lpp" -return DEC_OP; - YY_BREAK -case 77: -YY_RULE_SETUP -#line 231 "glsl_lexer.lpp" -return LE_OP; - YY_BREAK -case 78: -YY_RULE_SETUP -#line 232 "glsl_lexer.lpp" -return GE_OP; - YY_BREAK -case 79: -YY_RULE_SETUP -#line 233 "glsl_lexer.lpp" -return EQ_OP; - YY_BREAK -case 80: -YY_RULE_SETUP -#line 234 "glsl_lexer.lpp" -return NE_OP; - YY_BREAK -case 81: -YY_RULE_SETUP -#line 235 "glsl_lexer.lpp" -return AND_OP; - YY_BREAK -case 82: -YY_RULE_SETUP -#line 236 "glsl_lexer.lpp" -return OR_OP; - YY_BREAK -case 83: -YY_RULE_SETUP -#line 237 "glsl_lexer.lpp" -return XOR_OP; - YY_BREAK -case 84: -YY_RULE_SETUP -#line 239 "glsl_lexer.lpp" -return MUL_ASSIGN; - YY_BREAK -case 85: -YY_RULE_SETUP -#line 240 "glsl_lexer.lpp" -return DIV_ASSIGN; - YY_BREAK -case 86: -YY_RULE_SETUP -#line 241 "glsl_lexer.lpp" -return ADD_ASSIGN; - YY_BREAK -case 87: -YY_RULE_SETUP -#line 242 "glsl_lexer.lpp" -return MOD_ASSIGN; - YY_BREAK -case 88: -YY_RULE_SETUP -#line 243 "glsl_lexer.lpp" -return LEFT_ASSIGN; - YY_BREAK -case 89: -YY_RULE_SETUP -#line 244 "glsl_lexer.lpp" -return RIGHT_ASSIGN; - YY_BREAK -case 90: -YY_RULE_SETUP -#line 245 "glsl_lexer.lpp" -return AND_ASSIGN; - YY_BREAK -case 91: -YY_RULE_SETUP -#line 246 "glsl_lexer.lpp" -return XOR_ASSIGN; - YY_BREAK -case 92: -YY_RULE_SETUP -#line 247 "glsl_lexer.lpp" -return OR_ASSIGN; - YY_BREAK -case 93: -YY_RULE_SETUP -#line 248 "glsl_lexer.lpp" -return SUB_ASSIGN; - YY_BREAK -case 94: -YY_RULE_SETUP -#line 250 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext, NULL, 10); - return INTCONSTANT; - } - YY_BREAK -case 95: -YY_RULE_SETUP -#line 254 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext + 2, NULL, 16); - return INTCONSTANT; - } - YY_BREAK -case 96: -YY_RULE_SETUP -#line 258 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext, NULL, 8); - return INTCONSTANT; - } - YY_BREAK -case 97: -YY_RULE_SETUP -#line 263 "glsl_lexer.lpp" -{ - yylval->real = strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 98: -YY_RULE_SETUP -#line 267 "glsl_lexer.lpp" -{ - yylval->real = strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 99: -YY_RULE_SETUP -#line 271 "glsl_lexer.lpp" -{ - yylval->real = strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 100: -YY_RULE_SETUP -#line 275 "glsl_lexer.lpp" -{ - yylval->real = strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 101: -YY_RULE_SETUP -#line 279 "glsl_lexer.lpp" -{ - yylval->real = strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 102: -YY_RULE_SETUP -#line 284 "glsl_lexer.lpp" -{ - yylval->n = 1; - return BOOLCONSTANT; - } - YY_BREAK -case 103: -YY_RULE_SETUP -#line 288 "glsl_lexer.lpp" -{ - yylval->n = 0; - return BOOLCONSTANT; - } - YY_BREAK -/* Reserved words in GLSL 1.10. */ -case 104: -YY_RULE_SETUP -#line 295 "glsl_lexer.lpp" -RESERVED_WORD(999, ASM); - YY_BREAK -case 105: -YY_RULE_SETUP -#line 296 "glsl_lexer.lpp" -RESERVED_WORD(999, CLASS); - YY_BREAK -case 106: -YY_RULE_SETUP -#line 297 "glsl_lexer.lpp" -RESERVED_WORD(999, UNION); - YY_BREAK -case 107: -YY_RULE_SETUP -#line 298 "glsl_lexer.lpp" -RESERVED_WORD(999, ENUM); - YY_BREAK -case 108: -YY_RULE_SETUP -#line 299 "glsl_lexer.lpp" -RESERVED_WORD(999, TYPEDEF); - YY_BREAK -case 109: -YY_RULE_SETUP -#line 300 "glsl_lexer.lpp" -RESERVED_WORD(999, TEMPLATE); - YY_BREAK -case 110: -YY_RULE_SETUP -#line 301 "glsl_lexer.lpp" -RESERVED_WORD(999, THIS); - YY_BREAK -case 111: -YY_RULE_SETUP -#line 302 "glsl_lexer.lpp" -RESERVED_WORD(999, PACKED_TOK); - YY_BREAK -case 112: -YY_RULE_SETUP -#line 303 "glsl_lexer.lpp" -RESERVED_WORD(999, GOTO); - YY_BREAK -case 113: -YY_RULE_SETUP -#line 304 "glsl_lexer.lpp" -RESERVED_WORD(130, SWITCH); - YY_BREAK -case 114: -YY_RULE_SETUP -#line 305 "glsl_lexer.lpp" -RESERVED_WORD(130, DEFAULT); - YY_BREAK -case 115: -YY_RULE_SETUP -#line 306 "glsl_lexer.lpp" -RESERVED_WORD(999, INLINE_TOK); - YY_BREAK -case 116: -YY_RULE_SETUP -#line 307 "glsl_lexer.lpp" -RESERVED_WORD(999, NOINLINE); - YY_BREAK -case 117: -YY_RULE_SETUP -#line 308 "glsl_lexer.lpp" -RESERVED_WORD(999, VOLATILE); - YY_BREAK -case 118: -YY_RULE_SETUP -#line 309 "glsl_lexer.lpp" -RESERVED_WORD(999, PUBLIC_TOK); - YY_BREAK -case 119: -YY_RULE_SETUP -#line 310 "glsl_lexer.lpp" -RESERVED_WORD(999, STATIC); - YY_BREAK -case 120: -YY_RULE_SETUP -#line 311 "glsl_lexer.lpp" -RESERVED_WORD(999, EXTERN); - YY_BREAK -case 121: -YY_RULE_SETUP -#line 312 "glsl_lexer.lpp" -RESERVED_WORD(999, EXTERNAL); - YY_BREAK -case 122: -YY_RULE_SETUP -#line 313 "glsl_lexer.lpp" -RESERVED_WORD(999, INTERFACE); - YY_BREAK -case 123: -YY_RULE_SETUP -#line 314 "glsl_lexer.lpp" -RESERVED_WORD(999, LONG_TOK); - YY_BREAK -case 124: -YY_RULE_SETUP -#line 315 "glsl_lexer.lpp" -RESERVED_WORD(999, SHORT_TOK); - YY_BREAK -case 125: -YY_RULE_SETUP -#line 316 "glsl_lexer.lpp" -RESERVED_WORD(999, DOUBLE_TOK); - YY_BREAK -case 126: -YY_RULE_SETUP -#line 317 "glsl_lexer.lpp" -RESERVED_WORD(999, HALF); - YY_BREAK -case 127: -YY_RULE_SETUP -#line 318 "glsl_lexer.lpp" -RESERVED_WORD(999, FIXED_TOK); - YY_BREAK -case 128: -YY_RULE_SETUP -#line 319 "glsl_lexer.lpp" -RESERVED_WORD(999, UNSIGNED); - YY_BREAK -case 129: -YY_RULE_SETUP -#line 320 "glsl_lexer.lpp" -RESERVED_WORD(999, INPUT_TOK); - YY_BREAK -case 130: -YY_RULE_SETUP -#line 321 "glsl_lexer.lpp" -RESERVED_WORD(999, OUTPUT); - YY_BREAK -case 131: -YY_RULE_SETUP -#line 322 "glsl_lexer.lpp" -RESERVED_WORD(999, HVEC2); - YY_BREAK -case 132: -YY_RULE_SETUP -#line 323 "glsl_lexer.lpp" -RESERVED_WORD(999, HVEC3); - YY_BREAK -case 133: -YY_RULE_SETUP -#line 324 "glsl_lexer.lpp" -RESERVED_WORD(999, HVEC4); - YY_BREAK -case 134: -YY_RULE_SETUP -#line 325 "glsl_lexer.lpp" -RESERVED_WORD(999, DVEC2); - YY_BREAK -case 135: -YY_RULE_SETUP -#line 326 "glsl_lexer.lpp" -RESERVED_WORD(999, DVEC3); - YY_BREAK -case 136: -YY_RULE_SETUP -#line 327 "glsl_lexer.lpp" -RESERVED_WORD(999, DVEC4); - YY_BREAK -case 137: -YY_RULE_SETUP -#line 328 "glsl_lexer.lpp" -RESERVED_WORD(999, FVEC2); - YY_BREAK -case 138: -YY_RULE_SETUP -#line 329 "glsl_lexer.lpp" -RESERVED_WORD(999, FVEC3); - YY_BREAK -case 139: -YY_RULE_SETUP -#line 330 "glsl_lexer.lpp" -RESERVED_WORD(999, FVEC4); - YY_BREAK -case 140: -YY_RULE_SETUP -#line 331 "glsl_lexer.lpp" -return SAMPLER2DRECT; - YY_BREAK -case 141: -YY_RULE_SETUP -#line 332 "glsl_lexer.lpp" -RESERVED_WORD(999, SAMPLER3DRECT); - YY_BREAK -case 142: -YY_RULE_SETUP -#line 333 "glsl_lexer.lpp" -return SAMPLER2DRECTSHADOW; - YY_BREAK -case 143: -YY_RULE_SETUP -#line 334 "glsl_lexer.lpp" -RESERVED_WORD(999, SIZEOF); - YY_BREAK -case 144: -YY_RULE_SETUP -#line 335 "glsl_lexer.lpp" -RESERVED_WORD(999, CAST); - YY_BREAK -case 145: -YY_RULE_SETUP -#line 336 "glsl_lexer.lpp" -RESERVED_WORD(999, NAMESPACE); - YY_BREAK -case 146: -YY_RULE_SETUP -#line 337 "glsl_lexer.lpp" -RESERVED_WORD(999, USING); - YY_BREAK -/* Additional reserved words in GLSL 1.20. */ -case 147: -YY_RULE_SETUP -#line 340 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER_ES(120, LOWP); - YY_BREAK -case 148: -YY_RULE_SETUP -#line 341 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER_ES(120, MEDIUMP); - YY_BREAK -case 149: -YY_RULE_SETUP -#line 342 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER_ES(120, HIGHP); - YY_BREAK -case 150: -YY_RULE_SETUP -#line 343 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER_ES(120, PRECISION); - YY_BREAK -/* Additional reserved words in GLSL 1.30. */ -case 151: -YY_RULE_SETUP -#line 346 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, COMMON); - YY_BREAK -case 152: -YY_RULE_SETUP -#line 347 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, PARTITION); - YY_BREAK -case 153: -YY_RULE_SETUP -#line 348 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, ACTIVE); - YY_BREAK -case 154: -YY_RULE_SETUP -#line 349 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER_ES(130, SUPERP); - YY_BREAK -case 155: -YY_RULE_SETUP -#line 350 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, SAMPLERBUFFER); - YY_BREAK -case 156: -YY_RULE_SETUP -#line 351 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, FILTER); - YY_BREAK -case 157: -YY_RULE_SETUP -#line 352 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGE1D); - YY_BREAK -case 158: -YY_RULE_SETUP -#line 353 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGE2D); - YY_BREAK -case 159: -YY_RULE_SETUP -#line 354 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGE3D); - YY_BREAK -case 160: -YY_RULE_SETUP -#line 355 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGECUBE); - YY_BREAK -case 161: -YY_RULE_SETUP -#line 356 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IIMAGE1D); - YY_BREAK -case 162: -YY_RULE_SETUP -#line 357 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IIMAGE2D); - YY_BREAK -case 163: -YY_RULE_SETUP -#line 358 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IIMAGE3D); - YY_BREAK -case 164: -YY_RULE_SETUP -#line 359 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IIMAGECUBE); - YY_BREAK -case 165: -YY_RULE_SETUP -#line 360 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, UIMAGE1D); - YY_BREAK -case 166: -YY_RULE_SETUP -#line 361 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, UIMAGE2D); - YY_BREAK -case 167: -YY_RULE_SETUP -#line 362 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, UIMAGE3D); - YY_BREAK -case 168: -YY_RULE_SETUP -#line 363 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, UIMAGECUBE); - YY_BREAK -case 169: -YY_RULE_SETUP -#line 364 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGE1DARRAY); - YY_BREAK -case 170: -YY_RULE_SETUP -#line 365 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGE2DARRAY); - YY_BREAK -case 171: -YY_RULE_SETUP -#line 366 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IIMAGE1DARRAY); - YY_BREAK -case 172: -YY_RULE_SETUP -#line 367 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IIMAGE2DARRAY); - YY_BREAK -case 173: -YY_RULE_SETUP -#line 368 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, UIMAGE1DARRAY); - YY_BREAK -case 174: -YY_RULE_SETUP -#line 369 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, UIMAGE2DARRAY); - YY_BREAK -case 175: -YY_RULE_SETUP -#line 370 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGE1DSHADOW); - YY_BREAK -case 176: -YY_RULE_SETUP -#line 371 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGE2DSHADOW); - YY_BREAK -case 177: -YY_RULE_SETUP -#line 372 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IMAGEBUFFER); - YY_BREAK -case 178: -YY_RULE_SETUP -#line 373 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, IIMAGEBUFFER); - YY_BREAK -case 179: -YY_RULE_SETUP -#line 374 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, UIMAGEBUFFER); - YY_BREAK -case 180: -YY_RULE_SETUP -#line 375 "glsl_lexer.lpp" -TOKEN_OR_IDENTIFIER(130, ROW_MAJOR); - YY_BREAK -case 181: -YY_RULE_SETUP -#line 377 "glsl_lexer.lpp" -{ - struct _mesa_glsl_parse_state *state = yyextra; - void *ctx = state; - yylval->identifier = talloc_strdup(ctx, yytext); - return IDENTIFIER; - } - YY_BREAK -case 182: -YY_RULE_SETUP -#line 384 "glsl_lexer.lpp" -{ return yytext[0]; } - YY_BREAK -case 183: -YY_RULE_SETUP -#line 386 "glsl_lexer.lpp" -ECHO; - YY_BREAK -#line 2330 "glsl_lexer.cpp" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(PP): -case YY_STATE_EOF(PRAGMA): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * _mesa_glsl_lex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( _mesa_glsl_wrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of _mesa_glsl_lex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - _mesa_glsl_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - _mesa_glsl_restart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) _mesa_glsl_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 708 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 708 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 707); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - _mesa_glsl_restart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( _mesa_glsl_wrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void _mesa_glsl_restart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - _mesa_glsl_ensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - _mesa_glsl__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - _mesa_glsl__load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * _mesa_glsl_pop_buffer_state(); - * _mesa_glsl_push_buffer_state(new_buffer); - */ - _mesa_glsl_ensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - _mesa_glsl__load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (_mesa_glsl_wrap()) processing, but the only time this flag - * is looked at is after _mesa_glsl_wrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) _mesa_glsl_alloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" ); - - b->yy_is_our_buffer = 1; - - _mesa_glsl__init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with _mesa_glsl__create_buffer() - * @param yyscanner The scanner object. - */ - void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - _mesa_glsl_free((void *) b->yy_ch_buf ,yyscanner ); - - _mesa_glsl_free((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a _mesa_glsl_restart() or at EOF. - */ - static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - _mesa_glsl__flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then _mesa_glsl__init_buffer was _probably_ - * called from _mesa_glsl_restart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - _mesa_glsl__load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - _mesa_glsl_ensure_buffer_stack(yyscanner); - - /* This block is copied from _mesa_glsl__switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from _mesa_glsl__switch_to_buffer. */ - _mesa_glsl__load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - _mesa_glsl__load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_alloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_realloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE _mesa_glsl__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - _mesa_glsl__switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to _mesa_glsl_lex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * _mesa_glsl__scan_bytes() instead. - */ -YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return _mesa_glsl__scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to _mesa_glsl_lex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) _mesa_glsl_alloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = _mesa_glsl__scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in _mesa_glsl__scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int _mesa_glsl_get_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int _mesa_glsl_get_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *_mesa_glsl_get_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *_mesa_glsl_get_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int _mesa_glsl_get_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *_mesa_glsl_get_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void _mesa_glsl_set_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "_mesa_glsl_set_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void _mesa_glsl_set_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "_mesa_glsl_set_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see _mesa_glsl__switch_to_buffer - */ -void _mesa_glsl_set_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void _mesa_glsl_set_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int _mesa_glsl_get_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void _mesa_glsl_set_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void _mesa_glsl_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* _mesa_glsl_lex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int _mesa_glsl_lex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* _mesa_glsl_lex_init_extra has the same functionality as _mesa_glsl_lex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to _mesa_glsl_alloc in - * the yyextra field. - */ - -int _mesa_glsl_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - _mesa_glsl_set_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - _mesa_glsl_set_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from _mesa_glsl_lex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * _mesa_glsl_lex_init() - */ - return 0; -} - -/* _mesa_glsl_lex_destroy is for both reentrant and non-reentrant scanners. */ -int _mesa_glsl_lex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - _mesa_glsl_pop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - _mesa_glsl_free(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - _mesa_glsl_free(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * _mesa_glsl_lex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - _mesa_glsl_free ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *_mesa_glsl_alloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *_mesa_glsl_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void _mesa_glsl_free (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see _mesa_glsl_realloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 386 "glsl_lexer.lpp" - - - -void -_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string) -{ - _mesa_glsl_lex_init_extra(state,& state->scanner); - _mesa_glsl__scan_string(string,state->scanner); -} - -void -_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state) -{ - _mesa_glsl_lex_destroy(state->scanner); -} - +#line 2 "glsl_lexer.cpp"
+
+#line 4 "glsl_lexer.cpp"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE _mesa_glsl_restart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via _mesa_glsl_restart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void _mesa_glsl_restart (FILE *input_file ,yyscan_t yyscanner );
+void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner );
+
+static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner );
+static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner );
+static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER _mesa_glsl__flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE _mesa_glsl__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *_mesa_glsl_alloc (yy_size_t ,yyscan_t yyscanner );
+void *_mesa_glsl_realloc (void *,yy_size_t ,yyscan_t yyscanner );
+void _mesa_glsl_free (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer _mesa_glsl__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ _mesa_glsl_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ _mesa_glsl_ensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define _mesa_glsl_wrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 209
+#define YY_END_OF_BUFFER 210
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[813] =
+ { 0,
+ 0, 0, 15, 15, 0, 0, 210, 208, 1, 20,
+ 208, 208, 208, 208, 208, 208, 208, 208, 119, 117,
+ 208, 208, 208, 207, 208, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 208, 1, 208, 209, 15,
+ 19, 209, 18, 16, 17, 13, 12, 1, 101, 110,
+ 102, 113, 107, 96, 109, 97, 116, 121, 108, 122,
+ 119, 0, 0, 124, 119, 0, 117, 117, 105, 98,
+ 100, 99, 106, 207, 114, 104, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 29, 207,
+
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 33, 207, 207, 60, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 115,
+ 103, 1, 0, 0, 2, 0, 0, 0, 0, 15,
+ 14, 18, 17, 0, 121, 120, 0, 122, 0, 123,
+ 118, 111, 112, 207, 127, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 32, 207, 207, 207,
+
+ 207, 207, 207, 207, 207, 207, 207, 25, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 61,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 0, 0, 0, 0, 14, 0, 121, 0, 120, 0,
+ 122, 123, 118, 207, 207, 23, 207, 207, 174, 167,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 31,
+ 130, 207, 207, 207, 207, 67, 207, 207, 135, 149,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+
+ 207, 207, 146, 170, 48, 49, 50, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 133, 125, 207,
+ 207, 26, 207, 207, 207, 207, 207, 207, 207, 45,
+ 46, 47, 94, 207, 207, 0, 0, 0, 0, 0,
+ 120, 207, 207, 27, 36, 37, 38, 207, 128, 207,
+ 22, 207, 207, 207, 207, 157, 158, 159, 207, 126,
+ 207, 150, 24, 160, 161, 162, 172, 154, 155, 156,
+ 207, 207, 207, 62, 152, 207, 207, 207, 39, 40,
+ 41, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+
+ 207, 207, 207, 207, 207, 207, 207, 147, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 129, 207,
+ 207, 169, 42, 43, 44, 207, 207, 30, 0, 0,
+ 0, 0, 177, 207, 207, 175, 207, 207, 207, 148,
+ 143, 180, 207, 207, 207, 207, 207, 207, 138, 207,
+ 207, 207, 95, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 207, 207, 207, 207, 153, 134, 207, 207,
+ 141, 35, 207, 207, 166, 68, 142, 93, 178, 136,
+ 207, 207, 207, 207, 207, 207, 207, 207, 0, 0,
+ 0, 0, 207, 207, 207, 137, 34, 207, 207, 207,
+
+ 207, 207, 207, 181, 182, 183, 207, 207, 207, 207,
+ 207, 171, 207, 207, 207, 207, 207, 207, 207, 207,
+ 131, 207, 207, 207, 207, 207, 63, 207, 207, 64,
+ 207, 0, 0, 0, 0, 0, 207, 65, 28, 144,
+ 185, 186, 187, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 139, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 132, 189, 190, 191, 207,
+ 207, 151, 207, 140, 0, 0, 6, 0, 0, 0,
+ 11, 3, 21, 207, 207, 207, 207, 207, 207, 207,
+ 207, 207, 184, 145, 66, 207, 207, 207, 207, 168,
+
+ 207, 176, 173, 206, 70, 71, 72, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 0, 0, 0,
+ 0, 0, 0, 207, 207, 207, 188, 207, 207, 207,
+ 207, 207, 81, 82, 83, 207, 207, 207, 207, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 192, 87,
+ 88, 89, 207, 4, 0, 5, 0, 0, 0, 0,
+ 0, 207, 207, 207, 207, 207, 207, 207, 203, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 73, 207, 207, 207, 207, 207, 207, 0, 0, 0,
+ 207, 207, 204, 193, 207, 194, 207, 207, 207, 84,
+
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 207, 205, 207, 207, 90, 0, 0, 195, 196, 207,
+ 199, 207, 200, 207, 207, 69, 207, 207, 207, 163,
+ 207, 164, 179, 207, 197, 198, 207, 207, 0, 0,
+ 207, 207, 207, 207, 74, 207, 75, 207, 207, 207,
+ 207, 207, 0, 0, 0, 207, 207, 85, 86, 207,
+ 76, 207, 207, 77, 207, 91, 92, 0, 0, 0,
+ 207, 207, 207, 207, 207, 207, 0, 0, 0, 207,
+ 207, 207, 207, 207, 78, 0, 0, 7, 0, 0,
+ 201, 202, 207, 207, 207, 0, 8, 0, 0, 207,
+
+ 207, 165, 0, 0, 79, 80, 0, 0, 9, 0,
+ 10, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 1, 6, 1, 7, 8, 1, 9,
+ 10, 11, 12, 1, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 21, 21, 22, 22, 23, 1, 24,
+ 25, 26, 1, 1, 27, 28, 29, 30, 31, 32,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 34, 35, 33, 36, 33, 33, 37, 33, 33,
+ 1, 1, 1, 38, 39, 1, 40, 41, 42, 43,
+
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 33, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 1, 65, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[66] =
+ { 0,
+ 1, 2, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 4, 4, 4, 4, 4,
+ 4, 5, 1, 1, 1, 1, 6, 6, 6, 6,
+ 5, 5, 7, 7, 7, 7, 8, 1, 7, 6,
+ 6, 6, 6, 5, 5, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 8, 7, 7, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[824] =
+ { 0,
+ 0, 64, 70, 0, 1185, 1184, 1186, 1189, 65, 1189,
+ 1160, 1159, 128, 1158, 125, 126, 124, 1157, 140, 189,
+ 123, 1156, 138, 0, 127, 124, 113, 135, 144, 161,
+ 176, 1126, 130, 187, 140, 143, 161, 1120, 182, 174,
+ 202, 199, 211, 212, 1131, 130, 263, 255, 1189, 189,
+ 1189, 1162, 256, 1189, 0, 1189, 1189, 215, 1189, 1189,
+ 1189, 1189, 1189, 1189, 1189, 1189, 1189, 248, 1189, 250,
+ 112, 302, 319, 1189, 1189, 0, 0, 1189, 1151, 1189,
+ 1189, 1189, 1150, 0, 1189, 1189, 1116, 1121, 1114, 1117,
+ 1126, 1125, 1111, 1114, 1126, 144, 1120, 1107, 1104, 1118,
+
+ 1104, 1101, 1101, 1107, 175, 191, 1101, 1112, 1097, 1103,
+ 1107, 1108, 0, 1099, 1110, 247, 1109, 1104, 1084, 230,
+ 1088, 1102, 1092, 241, 1085, 228, 1098, 1100, 1082, 1078,
+ 1086, 1083, 1072, 1081, 173, 1079, 1085, 1080, 1083, 1071,
+ 1074, 233, 240, 260, 1084, 1071, 1084, 239, 1077, 1189,
+ 1189, 307, 301, 323, 1189, 1062, 1075, 1066, 1077, 249,
+ 0, 368, 0, 379, 1189, 298, 390, 1189, 397, 404,
+ 291, 1189, 1189, 1072, 0, 1063, 1067, 1077, 1074, 270,
+ 1057, 1057, 1061, 291, 1072, 1069, 1069, 1067, 1064, 1055,
+ 1062, 1048, 1046, 1059, 1044, 1061, 0, 1058, 1045, 1053,
+
+ 1050, 1054, 1055, 1048, 1045, 1033, 1032, 1046, 1049, 1036,
+ 1045, 1032, 1039, 1029, 335, 1035, 1038, 1028, 1036, 1024,
+ 1028, 1019, 1034, 1024, 1015, 1034, 1017, 1015, 1026, 1015,
+ 1010, 1008, 1022, 1007, 1009, 1006, 1018, 1017, 1020, 1001,
+ 306, 1010, 1005, 1003, 1013, 991, 339, 1010, 1012, 1000,
+ 992, 996, 1008, 991, 0, 411, 421, 438, 1189, 451,
+ 458, 1189, 1189, 986, 997, 0, 994, 344, 0, 0,
+ 987, 985, 987, 982, 991, 979, 997, 985, 350, 0,
+ 0, 979, 990, 989, 989, 0, 973, 353, 0, 0,
+ 975, 357, 983, 984, 974, 968, 967, 968, 967, 967,
+
+ 361, 962, 0, 0, 958, 957, 956, 958, 959, 964,
+ 958, 954, 968, 963, 962, 961, 952, 955, 955, 947,
+ 950, 945, 954, 959, 944, 957, 947, 0, 0, 954,
+ 950, 0, 941, 941, 947, 937, 945, 426, 942, 0,
+ 0, 0, 0, 931, 944, 943, 942, 939, 927, 465,
+ 475, 939, 941, 0, 0, 0, 0, 927, 0, 927,
+ 0, 926, 927, 921, 932, 0, 0, 0, 922, 0,
+ 918, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 929, 481, 928, 0, 0, 926, 922, 918, 0, 0,
+ 0, 910, 443, 486, 493, 915, 911, 917, 907, 905,
+
+ 919, 903, 903, 917, 905, 917, 912, 0, 910, 907,
+ 911, 894, 896, 903, 909, 904, 903, 890, 0, 892,
+ 893, 0, 0, 0, 0, 890, 894, 0, 888, 938,
+ 887, 890, 0, 878, 888, 0, 876, 876, 890, 0,
+ 892, 0, 497, 901, 900, 899, 869, 868, 0, 886,
+ 885, 880, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 868, 882, 868, 865, 0, 0, 871, 870,
+ 0, 0, 868, 860, 0, 0, 0, 0, 0, 0,
+ 857, 869, 500, 861, 868, 867, 864, 858, 851, 519,
+ 867, 852, 847, 861, 859, 0, 0, 851, 871, 870,
+
+ 869, 839, 838, 495, 496, 0, 851, 854, 852, 840,
+ 836, 0, 849, 846, 845, 834, 833, 832, 515, 841,
+ 0, 854, 853, 852, 822, 821, 0, 836, 822, 0,
+ 833, 828, 543, 545, 873, 821, 829, 0, 0, 0,
+ 845, 844, 0, 825, 828, 812, 820, 810, 818, 819,
+ 819, 818, 803, 539, 816, 0, 817, 805, 804, 800,
+ 825, 824, 823, 793, 792, 0, 823, 822, 0, 803,
+ 806, 0, 552, 0, 792, 557, 1189, 580, 0, 590,
+ 499, 1189, 0, 789, 788, 798, 798, 785, 800, 783,
+ 798, 793, 0, 0, 0, 806, 805, 804, 774, 0,
+
+ 774, 0, 0, 0, 559, 568, 797, 785, 788, 772,
+ 771, 781, 781, 794, 793, 792, 762, 767, 552, 613,
+ 363, 775, 763, 761, 760, 771, 0, 774, 770, 772,
+ 768, 754, 782, 781, 0, 766, 758, 749, 757, 747,
+ 758, 754, 756, 754, 754, 741, 740, 751, 0, 767,
+ 766, 0, 751, 1189, 391, 1189, 620, 0, 640, 750,
+ 732, 749, 748, 731, 723, 731, 721, 729, 0, 726,
+ 725, 736, 719, 722, 737, 720, 733, 734, 731, 728,
+ 736, 730, 729, 712, 711, 710, 721, 402, 705, 715,
+ 699, 698, 0, 725, 698, 723, 696, 700, 699, 0,
+
+ 710, 713, 709, 711, 688, 702, 686, 680, 688, 671,
+ 662, 0, 640, 639, 0, 648, 641, 0, 0, 645,
+ 0, 644, 0, 650, 649, 0, 625, 633, 623, 650,
+ 630, 0, 0, 643, 0, 0, 642, 641, 582, 632,
+ 639, 638, 614, 613, 635, 608, 633, 607, 590, 607,
+ 586, 585, 611, 380, 526, 545, 544, 0, 0, 538,
+ 0, 504, 510, 0, 495, 0, 0, 550, 572, 483,
+ 470, 454, 462, 449, 445, 404, 419, 616, 619, 391,
+ 387, 404, 392, 290, 0, 617, 642, 1189, 644, 570,
+ 0, 0, 263, 258, 139, 645, 1189, 643, 618, 107,
+
+ 77, 0, 23, 662, 0, 0, 663, 664, 1189, 665,
+ 1189, 1189, 697, 702, 707, 712, 714, 716, 722, 729,
+ 734, 739, 744
+ } ;
+
+static yyconst flex_int16_t yy_def[824] =
+ { 0,
+ 812, 1, 812, 3, 813, 813, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 814, 812, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 815, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 816, 812, 817,
+ 19, 812, 812, 812, 812, 818, 20, 812, 812, 812,
+ 812, 812, 812, 814, 812, 812, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 819, 812, 815, 812, 812, 817, 812, 812, 812, 812,
+ 818, 812, 812, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 812, 812, 812, 812, 819, 812, 812, 812, 812, 812,
+ 812, 812, 812, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 812, 812, 812, 812, 812,
+ 812, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 812, 812,
+ 812, 812, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 812, 812,
+ 812, 812, 814, 814, 814, 814, 814, 814, 814, 814,
+
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 812, 820, 812, 812, 812, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 812, 812, 812, 812, 821, 812,
+ 812, 812, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 812, 822, 812,
+ 821, 812, 812, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 812, 812, 812, 812, 823, 812, 812,
+ 812, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 823, 812, 812,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 812, 812, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 814, 812, 812,
+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814,
+ 814, 814, 812, 812, 812, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 814, 814, 812, 812, 812,
+ 814, 814, 814, 814, 814, 814, 812, 812, 812, 814,
+ 814, 814, 814, 814, 814, 812, 812, 812, 812, 812,
+ 814, 814, 814, 814, 814, 812, 812, 812, 812, 814,
+
+ 814, 814, 812, 812, 814, 814, 812, 812, 812, 812,
+ 812, 0, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812
+ } ;
+
+static yyconst flex_int16_t yy_nxt[1255] =
+ { 0,
+ 8, 9, 10, 9, 11, 8, 12, 13, 8, 8,
+ 14, 15, 16, 17, 18, 19, 20, 20, 20, 20,
+ 20, 20, 8, 21, 22, 23, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 25, 24, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 24, 24,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 24, 24, 24, 46, 47, 58, 807, 58, 48,
+ 49, 50, 51, 50, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 52, 49, 53, 53, 53, 53,
+ 53, 53, 54, 49, 49, 49, 55, 55, 55, 55,
+
+ 55, 55, 55, 55, 55, 55, 55, 49, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 49, 61, 64, 806, 66, 68,
+ 68, 68, 68, 68, 68, 68, 79, 80, 812, 65,
+ 67, 85, 62, 70, 150, 71, 71, 71, 71, 71,
+ 71, 72, 82, 83, 86, 87, 90, 805, 91, 110,
+ 73, 74, 92, 812, 93, 75, 76, 111, 94, 119,
+ 88, 89, 121, 73, 74, 95, 122, 97, 96, 112,
+ 160, 98, 160, 120, 151, 183, 184, 99, 75, 802,
+
+ 123, 76, 70, 100, 77, 77, 77, 77, 77, 77,
+ 77, 101, 231, 102, 124, 104, 58, 129, 58, 73,
+ 74, 126, 103, 105, 78, 193, 106, 130, 232, 107,
+ 195, 113, 73, 74, 114, 108, 194, 127, 115, 116,
+ 128, 131, 138, 117, 196, 139, 118, 78, 132, 133,
+ 160, 146, 160, 134, 140, 147, 154, 155, 142, 135,
+ 136, 141, 137, 143, 152, 148, 58, 144, 153, 221,
+ 145, 162, 162, 162, 162, 162, 162, 162, 164, 165,
+ 167, 168, 213, 222, 239, 240, 248, 241, 218, 249,
+ 214, 164, 165, 167, 168, 219, 242, 205, 156, 243,
+
+ 206, 207, 154, 155, 208, 157, 209, 244, 152, 158,
+ 58, 801, 153, 269, 159, 70, 800, 72, 72, 72,
+ 72, 72, 72, 72, 154, 155, 263, 270, 258, 259,
+ 169, 169, 73, 74, 170, 170, 170, 170, 170, 170,
+ 170, 258, 259, 795, 156, 73, 74, 274, 275, 263,
+ 333, 157, 305, 306, 307, 158, 340, 341, 342, 334,
+ 159, 355, 356, 357, 576, 577, 156, 366, 367, 368,
+ 374, 375, 376, 157, 378, 379, 380, 158, 389, 390,
+ 391, 768, 159, 162, 162, 162, 162, 162, 162, 162,
+ 256, 256, 655, 656, 257, 257, 257, 257, 257, 257,
+
+ 257, 260, 260, 655, 656, 261, 261, 261, 261, 261,
+ 261, 261, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 257, 257, 257, 257,
+ 257, 257, 257, 769, 794, 262, 257, 257, 257, 257,
+ 257, 257, 257, 423, 424, 425, 793, 792, 262, 350,
+ 350, 791, 165, 351, 351, 351, 351, 351, 351, 351,
+ 454, 455, 456, 786, 785, 165, 261, 261, 261, 261,
+ 261, 261, 261, 261, 261, 261, 261, 261, 261, 261,
+ 351, 351, 351, 351, 351, 351, 351, 784, 783, 168,
+ 351, 351, 351, 351, 351, 351, 351, 444, 445, 446,
+
+ 581, 782, 168, 457, 458, 459, 259, 781, 447, 448,
+ 460, 461, 462, 499, 500, 501, 522, 523, 524, 259,
+ 490, 546, 548, 780, 502, 503, 779, 525, 526, 547,
+ 549, 561, 562, 563, 533, 534, 534, 534, 534, 534,
+ 534, 622, 564, 565, 576, 577, 576, 577, 776, 775,
+ 774, 768, 623, 655, 656, 596, 597, 598, 576, 577,
+ 580, 580, 580, 580, 580, 580, 580, 599, 614, 615,
+ 616, 798, 619, 620, 620, 620, 620, 620, 620, 579,
+ 617, 576, 577, 753, 773, 638, 772, 771, 658, 770,
+ 754, 576, 577, 639, 640, 578, 578, 578, 578, 578,
+
+ 578, 641, 642, 769, 579, 580, 580, 580, 580, 580,
+ 580, 580, 753, 658, 655, 656, 777, 787, 796, 754,
+ 789, 655, 656, 799, 778, 788, 797, 790, 659, 659,
+ 659, 659, 659, 659, 659, 657, 657, 657, 657, 657,
+ 657, 655, 656, 787, 798, 789, 796, 767, 766, 765,
+ 764, 788, 790, 763, 797, 659, 659, 659, 659, 659,
+ 659, 659, 803, 808, 810, 808, 810, 762, 761, 760,
+ 804, 809, 811, 809, 811, 759, 758, 757, 756, 755,
+ 752, 751, 750, 749, 748, 747, 746, 745, 744, 743,
+ 742, 741, 740, 739, 738, 737, 799, 56, 56, 56,
+
+ 56, 56, 56, 56, 56, 84, 84, 84, 84, 84,
+ 163, 163, 163, 163, 163, 68, 68, 166, 166, 171,
+ 171, 171, 255, 255, 736, 255, 255, 255, 255, 255,
+ 578, 578, 578, 735, 734, 733, 578, 621, 621, 621,
+ 657, 657, 657, 732, 731, 730, 657, 688, 688, 688,
+ 729, 728, 727, 726, 725, 724, 723, 722, 721, 720,
+ 719, 718, 717, 716, 715, 714, 713, 712, 711, 710,
+ 709, 708, 707, 706, 705, 704, 703, 702, 701, 700,
+ 699, 698, 697, 696, 695, 694, 693, 692, 691, 690,
+ 689, 687, 686, 685, 684, 683, 682, 681, 680, 679,
+
+ 678, 677, 676, 675, 674, 673, 672, 671, 670, 669,
+ 668, 667, 666, 665, 664, 663, 662, 661, 660, 654,
+ 653, 652, 651, 650, 649, 648, 647, 646, 645, 644,
+ 643, 637, 636, 635, 634, 633, 632, 631, 630, 629,
+ 628, 627, 626, 625, 624, 618, 613, 612, 611, 610,
+ 609, 608, 607, 606, 605, 604, 603, 602, 601, 600,
+ 595, 594, 593, 592, 591, 590, 589, 588, 587, 586,
+ 585, 584, 583, 582, 581, 575, 574, 573, 572, 571,
+ 570, 569, 568, 567, 566, 560, 559, 558, 557, 556,
+ 555, 554, 553, 552, 551, 550, 545, 544, 543, 542,
+
+ 541, 540, 539, 538, 537, 536, 535, 532, 531, 530,
+ 529, 528, 527, 521, 520, 519, 518, 517, 516, 515,
+ 514, 513, 512, 511, 510, 509, 508, 507, 506, 505,
+ 504, 498, 497, 496, 495, 494, 493, 492, 491, 490,
+ 489, 488, 487, 486, 485, 484, 483, 482, 481, 480,
+ 479, 478, 477, 476, 475, 474, 473, 472, 471, 470,
+ 469, 468, 467, 466, 465, 464, 463, 453, 452, 451,
+ 450, 449, 443, 442, 441, 440, 439, 438, 437, 436,
+ 435, 434, 433, 432, 431, 430, 429, 428, 427, 426,
+ 422, 421, 420, 419, 418, 417, 416, 415, 414, 413,
+
+ 412, 411, 410, 409, 408, 407, 406, 405, 404, 403,
+ 402, 401, 400, 399, 398, 397, 396, 395, 394, 393,
+ 392, 388, 387, 386, 385, 384, 383, 382, 381, 377,
+ 373, 372, 371, 370, 369, 365, 364, 363, 362, 361,
+ 360, 359, 358, 354, 353, 352, 349, 348, 347, 346,
+ 345, 344, 343, 339, 338, 337, 336, 335, 332, 331,
+ 330, 329, 328, 327, 326, 325, 324, 323, 322, 321,
+ 320, 319, 318, 317, 316, 315, 314, 313, 312, 311,
+ 310, 309, 308, 304, 303, 302, 301, 300, 299, 298,
+ 297, 296, 295, 294, 293, 292, 291, 290, 289, 288,
+
+ 287, 286, 285, 284, 283, 282, 281, 280, 279, 278,
+ 277, 276, 273, 272, 271, 268, 267, 266, 265, 264,
+ 254, 253, 252, 251, 250, 247, 246, 245, 238, 237,
+ 236, 235, 234, 233, 230, 229, 228, 227, 226, 225,
+ 224, 223, 220, 217, 216, 215, 212, 211, 210, 204,
+ 203, 202, 201, 200, 199, 198, 197, 192, 191, 190,
+ 189, 188, 187, 186, 185, 182, 181, 180, 179, 178,
+ 177, 176, 175, 174, 173, 172, 161, 149, 125, 109,
+ 81, 69, 63, 60, 59, 812, 57, 57, 7, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812
+ } ;
+
+static yyconst flex_int16_t yy_chk[1255] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 2, 9, 803, 9, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 13, 15, 801, 16, 17,
+ 17, 17, 17, 17, 17, 17, 21, 21, 71, 15,
+ 16, 25, 13, 19, 46, 19, 19, 19, 19, 19,
+ 19, 19, 23, 23, 25, 26, 27, 800, 27, 33,
+ 19, 19, 27, 71, 28, 19, 19, 33, 28, 35,
+ 26, 26, 36, 19, 19, 28, 36, 29, 28, 33,
+ 50, 29, 50, 35, 46, 96, 96, 29, 19, 795,
+
+ 37, 19, 20, 29, 20, 20, 20, 20, 20, 20,
+ 20, 30, 135, 30, 37, 31, 58, 40, 58, 20,
+ 20, 39, 30, 31, 20, 105, 31, 40, 135, 31,
+ 106, 34, 20, 20, 34, 31, 105, 39, 34, 34,
+ 39, 41, 42, 34, 106, 42, 34, 20, 41, 41,
+ 160, 44, 160, 41, 42, 44, 48, 48, 43, 41,
+ 41, 42, 41, 43, 47, 44, 47, 43, 47, 126,
+ 43, 53, 53, 53, 53, 53, 53, 53, 68, 68,
+ 70, 70, 120, 126, 142, 142, 148, 143, 124, 148,
+ 120, 68, 68, 70, 70, 124, 143, 116, 48, 144,
+
+ 116, 116, 153, 153, 116, 48, 116, 144, 152, 48,
+ 152, 794, 152, 180, 48, 72, 793, 72, 72, 72,
+ 72, 72, 72, 72, 154, 154, 171, 180, 166, 166,
+ 73, 73, 72, 72, 73, 73, 73, 73, 73, 73,
+ 73, 166, 166, 784, 153, 72, 72, 184, 184, 171,
+ 241, 153, 215, 215, 215, 153, 247, 247, 247, 241,
+ 153, 268, 268, 268, 621, 621, 154, 279, 279, 279,
+ 288, 288, 288, 154, 292, 292, 292, 154, 301, 301,
+ 301, 754, 154, 162, 162, 162, 162, 162, 162, 162,
+ 164, 164, 655, 655, 164, 164, 164, 164, 164, 164,
+
+ 164, 167, 167, 688, 688, 167, 167, 167, 167, 167,
+ 167, 167, 169, 169, 169, 169, 169, 169, 169, 170,
+ 170, 170, 170, 170, 170, 170, 256, 256, 256, 256,
+ 256, 256, 256, 754, 783, 170, 257, 257, 257, 257,
+ 257, 257, 257, 338, 338, 338, 782, 781, 170, 258,
+ 258, 780, 257, 258, 258, 258, 258, 258, 258, 258,
+ 393, 393, 393, 777, 776, 257, 260, 260, 260, 260,
+ 260, 260, 260, 261, 261, 261, 261, 261, 261, 261,
+ 350, 350, 350, 350, 350, 350, 350, 775, 774, 261,
+ 351, 351, 351, 351, 351, 351, 351, 382, 382, 382,
+
+ 581, 773, 261, 394, 394, 394, 351, 772, 382, 382,
+ 395, 395, 395, 443, 443, 443, 483, 483, 483, 351,
+ 490, 504, 505, 771, 443, 443, 770, 483, 483, 504,
+ 505, 519, 519, 519, 490, 490, 490, 490, 490, 490,
+ 490, 581, 519, 519, 533, 533, 534, 534, 765, 763,
+ 762, 768, 581, 619, 619, 554, 554, 554, 576, 576,
+ 534, 534, 534, 534, 534, 534, 534, 554, 573, 573,
+ 573, 790, 576, 576, 576, 576, 576, 576, 576, 533,
+ 573, 578, 578, 739, 760, 605, 757, 756, 619, 755,
+ 739, 580, 580, 605, 606, 578, 578, 578, 578, 578,
+
+ 578, 606, 606, 768, 533, 580, 580, 580, 580, 580,
+ 580, 580, 753, 619, 620, 620, 769, 778, 786, 753,
+ 779, 657, 657, 790, 769, 778, 786, 779, 620, 620,
+ 620, 620, 620, 620, 620, 657, 657, 657, 657, 657,
+ 657, 659, 659, 787, 798, 789, 796, 752, 751, 750,
+ 749, 787, 789, 748, 796, 659, 659, 659, 659, 659,
+ 659, 659, 799, 804, 807, 808, 810, 747, 746, 745,
+ 799, 804, 807, 808, 810, 744, 743, 742, 741, 740,
+ 738, 737, 734, 731, 730, 729, 728, 727, 725, 724,
+ 722, 720, 717, 716, 714, 713, 798, 813, 813, 813,
+
+ 813, 813, 813, 813, 813, 814, 814, 814, 814, 814,
+ 815, 815, 815, 815, 815, 816, 816, 817, 817, 818,
+ 818, 818, 819, 819, 711, 819, 819, 819, 819, 819,
+ 820, 820, 820, 710, 709, 708, 820, 821, 821, 821,
+ 822, 822, 822, 707, 706, 705, 822, 823, 823, 823,
+ 704, 703, 702, 701, 699, 698, 697, 696, 695, 694,
+ 692, 691, 690, 689, 687, 686, 685, 684, 683, 682,
+ 681, 680, 679, 678, 677, 676, 675, 674, 673, 672,
+ 671, 670, 668, 667, 666, 665, 664, 663, 662, 661,
+ 660, 653, 651, 650, 648, 647, 646, 645, 644, 643,
+
+ 642, 641, 640, 639, 638, 637, 636, 634, 633, 632,
+ 631, 630, 629, 628, 626, 625, 624, 623, 622, 618,
+ 617, 616, 615, 614, 613, 612, 611, 610, 609, 608,
+ 607, 601, 599, 598, 597, 596, 592, 591, 590, 589,
+ 588, 587, 586, 585, 584, 575, 571, 570, 568, 567,
+ 565, 564, 563, 562, 561, 560, 559, 558, 557, 555,
+ 553, 552, 551, 550, 549, 548, 547, 546, 545, 544,
+ 542, 541, 537, 536, 535, 532, 531, 529, 528, 526,
+ 525, 524, 523, 522, 520, 518, 517, 516, 515, 514,
+ 513, 511, 510, 509, 508, 507, 503, 502, 501, 500,
+
+ 499, 498, 495, 494, 493, 492, 491, 489, 488, 487,
+ 486, 485, 484, 482, 481, 474, 473, 470, 469, 466,
+ 465, 464, 463, 452, 451, 450, 448, 447, 446, 445,
+ 444, 441, 439, 438, 437, 435, 434, 432, 431, 430,
+ 429, 427, 426, 421, 420, 418, 417, 416, 415, 414,
+ 413, 412, 411, 410, 409, 407, 406, 405, 404, 403,
+ 402, 401, 400, 399, 398, 397, 396, 392, 388, 387,
+ 386, 383, 381, 371, 369, 365, 364, 363, 362, 360,
+ 358, 353, 352, 349, 348, 347, 346, 345, 344, 339,
+ 337, 336, 335, 334, 333, 331, 330, 327, 326, 325,
+
+ 324, 323, 322, 321, 320, 319, 318, 317, 316, 315,
+ 314, 313, 312, 311, 310, 309, 308, 307, 306, 305,
+ 302, 300, 299, 298, 297, 296, 295, 294, 293, 291,
+ 287, 285, 284, 283, 282, 278, 277, 276, 275, 274,
+ 273, 272, 271, 267, 265, 264, 254, 253, 252, 251,
+ 250, 249, 248, 246, 245, 244, 243, 242, 240, 239,
+ 238, 237, 236, 235, 234, 233, 232, 231, 230, 229,
+ 228, 227, 226, 225, 224, 223, 222, 221, 220, 219,
+ 218, 217, 216, 214, 213, 212, 211, 210, 209, 208,
+ 207, 206, 205, 204, 203, 202, 201, 200, 199, 198,
+
+ 196, 195, 194, 193, 192, 191, 190, 189, 188, 187,
+ 186, 185, 183, 182, 181, 179, 178, 177, 176, 174,
+ 159, 158, 157, 156, 149, 147, 146, 145, 141, 140,
+ 139, 138, 137, 136, 134, 133, 132, 131, 130, 129,
+ 128, 127, 125, 123, 122, 121, 119, 118, 117, 115,
+ 114, 112, 111, 110, 109, 108, 107, 104, 103, 102,
+ 101, 100, 99, 98, 97, 95, 94, 93, 92, 91,
+ 90, 89, 88, 87, 83, 79, 52, 45, 38, 32,
+ 22, 18, 14, 12, 11, 7, 6, 5, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "glsl_lexer.lpp"
+#line 2 "glsl_lexer.lpp"
+/*
+ * 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 "strtod.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);
+
+#define YY_USER_INIT yylineno = 0; yycolumn = 0;
+
+#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U')
+
+/* A macro for handling reserved words and keywords across language versions.
+ *
+ * Certain words start out as identifiers, become reserved words in
+ * later language revisions, and finally become language keywords.
+ *
+ * For example, consider the following lexer rule:
+ * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER)
+ *
+ * This means that "samplerBuffer" will be treated as:
+ * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40
+ * - a reserved word - error ...in GLSL >= 1.30
+ * - an identifier ...in GLSL < 1.30
+ */
+#define KEYWORD(reserved_version, allowed_version, token) \
+ do { \
+ if (yyextra->language_version >= allowed_version) { \
+ return token; \
+ } else if (yyextra->language_version >= reserved_version) { \
+ _mesa_glsl_error(yylloc, yyextra, \
+ "Illegal use of reserved word `%s'", yytext); \
+ return ERROR_TOK; \
+ } else { \
+ yylval->identifier = strdup(yytext); \
+ return IDENTIFIER; \
+ } \
+ } while (0)
+
+/* The ES macro can be used in KEYWORD checks:
+ *
+ * word KEYWORD(110 || ES, 400, TOKEN)
+ * ...means the word is reserved in GLSL ES 1.00, while
+ *
+ * word KEYWORD(110, 130 || ES, TOKEN)
+ * ...means the word is a legal keyword in GLSL ES 1.00.
+ */
+#define ES yyextra->es_shader
+
+#line 1059 "glsl_lexer.cpp"
+
+#define INITIAL 0
+#define PP 1
+#define PRAGMA 2
+
+#define YY_EXTRA_TYPE struct _mesa_glsl_parse_state *
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ YYSTYPE * yylval_r;
+
+ YYLTYPE * yylloc_r;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+ /* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+ # define yylval yyg->yylval_r
+
+ # define yylloc yyg->yylloc_r
+
+int _mesa_glsl_lex_init (yyscan_t* scanner);
+
+int _mesa_glsl_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int _mesa_glsl_lex_destroy (yyscan_t yyscanner );
+
+int _mesa_glsl_get_debug (yyscan_t yyscanner );
+
+void _mesa_glsl_set_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner );
+
+void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *_mesa_glsl_get_in (yyscan_t yyscanner );
+
+void _mesa_glsl_set_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *_mesa_glsl_get_out (yyscan_t yyscanner );
+
+void _mesa_glsl_set_out (FILE * out_str ,yyscan_t yyscanner );
+
+int _mesa_glsl_get_leng (yyscan_t yyscanner );
+
+char *_mesa_glsl_get_text (yyscan_t yyscanner );
+
+int _mesa_glsl_get_lineno (yyscan_t yyscanner );
+
+void _mesa_glsl_set_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner );
+
+void _mesa_glsl_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+ YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner );
+
+ void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int _mesa_glsl_wrap (yyscan_t yyscanner );
+#else
+extern int _mesa_glsl_wrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ unsigned n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int _mesa_glsl_lex \
+ (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int _mesa_glsl_lex \
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 95 "glsl_lexer.lpp"
+
+
+#line 1296 "glsl_lexer.cpp"
+
+ yylval = yylval_param;
+
+ yylloc = yylloc_param;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ _mesa_glsl_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ _mesa_glsl__load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 813 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 812 );
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 97 "glsl_lexer.lpp"
+;
+ YY_BREAK
+/* Preprocessor tokens. */
+case 2:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 100 "glsl_lexer.lpp"
+;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 101 "glsl_lexer.lpp"
+{ BEGIN PP; return VERSION; }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 102 "glsl_lexer.lpp"
+{ BEGIN PP; return EXTENSION; }
+ YY_BREAK
+case 5:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 103 "glsl_lexer.lpp"
+{
+ /* 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);
+ }
+ YY_BREAK
+case 6:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 118 "glsl_lexer.lpp"
+{
+ /* 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;
+ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 132 "glsl_lexer.lpp"
+{
+ BEGIN PP;
+ return PRAGMA_DEBUG_ON;
+ }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 136 "glsl_lexer.lpp"
+{
+ BEGIN PP;
+ return PRAGMA_DEBUG_OFF;
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 140 "glsl_lexer.lpp"
+{
+ BEGIN PP;
+ return PRAGMA_OPTIMIZE_ON;
+ }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 144 "glsl_lexer.lpp"
+{
+ BEGIN PP;
+ return PRAGMA_OPTIMIZE_OFF;
+ }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 148 "glsl_lexer.lpp"
+{ BEGIN PRAGMA; }
+ YY_BREAK
+case 12:
+/* rule 12 can match eol */
+YY_RULE_SETUP
+#line 150 "glsl_lexer.lpp"
+{ BEGIN 0; yylineno++; yycolumn = 0; }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 151 "glsl_lexer.lpp"
+{ }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 153 "glsl_lexer.lpp"
+{ }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 154 "glsl_lexer.lpp"
+{ }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 155 "glsl_lexer.lpp"
+return COLON;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 156 "glsl_lexer.lpp"
+{
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 160 "glsl_lexer.lpp"
+{
+ yylval->n = strtol(yytext, NULL, 10);
+ return INTCONSTANT;
+ }
+ YY_BREAK
+case 19:
+/* rule 19 can match eol */
+YY_RULE_SETUP
+#line 164 "glsl_lexer.lpp"
+{ BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
+ YY_BREAK
+case 20:
+/* rule 20 can match eol */
+YY_RULE_SETUP
+#line 166 "glsl_lexer.lpp"
+{ yylineno++; yycolumn = 0; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 168 "glsl_lexer.lpp"
+return ATTRIBUTE;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 169 "glsl_lexer.lpp"
+return CONST_TOK;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 170 "glsl_lexer.lpp"
+return BOOL_TOK;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 171 "glsl_lexer.lpp"
+return FLOAT_TOK;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 172 "glsl_lexer.lpp"
+return INT_TOK;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 173 "glsl_lexer.lpp"
+KEYWORD(130, 130, UINT_TOK);
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 175 "glsl_lexer.lpp"
+return BREAK;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 176 "glsl_lexer.lpp"
+return CONTINUE;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 177 "glsl_lexer.lpp"
+return DO;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 178 "glsl_lexer.lpp"
+return WHILE;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 179 "glsl_lexer.lpp"
+return ELSE;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 180 "glsl_lexer.lpp"
+return FOR;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 181 "glsl_lexer.lpp"
+return IF;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 182 "glsl_lexer.lpp"
+return DISCARD;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 183 "glsl_lexer.lpp"
+return RETURN;
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 185 "glsl_lexer.lpp"
+return BVEC2;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 186 "glsl_lexer.lpp"
+return BVEC3;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 187 "glsl_lexer.lpp"
+return BVEC4;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 188 "glsl_lexer.lpp"
+return IVEC2;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 189 "glsl_lexer.lpp"
+return IVEC3;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 190 "glsl_lexer.lpp"
+return IVEC4;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 191 "glsl_lexer.lpp"
+KEYWORD(130, 130, UVEC2);
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 192 "glsl_lexer.lpp"
+KEYWORD(130, 130, UVEC3);
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 193 "glsl_lexer.lpp"
+KEYWORD(130, 130, UVEC4);
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 194 "glsl_lexer.lpp"
+return VEC2;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 195 "glsl_lexer.lpp"
+return VEC3;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 196 "glsl_lexer.lpp"
+return VEC4;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 197 "glsl_lexer.lpp"
+return MAT2X2;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 198 "glsl_lexer.lpp"
+return MAT3X3;
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 199 "glsl_lexer.lpp"
+return MAT4X4;
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 200 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT2X2);
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 201 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT2X3);
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 202 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT2X4);
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 203 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT3X2);
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 204 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT3X3);
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 205 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT3X4);
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 206 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT4X2);
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 207 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT4X3);
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 208 "glsl_lexer.lpp"
+KEYWORD(120, 120, MAT4X4);
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 210 "glsl_lexer.lpp"
+return IN_TOK;
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 211 "glsl_lexer.lpp"
+return OUT_TOK;
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 212 "glsl_lexer.lpp"
+return INOUT_TOK;
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 213 "glsl_lexer.lpp"
+return UNIFORM;
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 214 "glsl_lexer.lpp"
+return VARYING;
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 215 "glsl_lexer.lpp"
+KEYWORD(120, 120, CENTROID);
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 216 "glsl_lexer.lpp"
+KEYWORD(120 || ES, 120 || ES, INVARIANT);
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 217 "glsl_lexer.lpp"
+KEYWORD(130 || ES, 130, FLAT);
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 218 "glsl_lexer.lpp"
+KEYWORD(130, 130, SMOOTH);
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 219 "glsl_lexer.lpp"
+KEYWORD(130, 130, NOPERSPECTIVE);
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 221 "glsl_lexer.lpp"
+return SAMPLER1D;
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 222 "glsl_lexer.lpp"
+return SAMPLER2D;
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 223 "glsl_lexer.lpp"
+return SAMPLER3D;
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 224 "glsl_lexer.lpp"
+return SAMPLERCUBE;
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 225 "glsl_lexer.lpp"
+KEYWORD(130, 130, SAMPLER1DARRAY);
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 226 "glsl_lexer.lpp"
+KEYWORD(130, 130, SAMPLER2DARRAY);
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 227 "glsl_lexer.lpp"
+return SAMPLER1DSHADOW;
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 228 "glsl_lexer.lpp"
+return SAMPLER2DSHADOW;
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 229 "glsl_lexer.lpp"
+KEYWORD(130, 130, SAMPLERCUBESHADOW);
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 230 "glsl_lexer.lpp"
+KEYWORD(130, 130, SAMPLER1DARRAYSHADOW);
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 231 "glsl_lexer.lpp"
+KEYWORD(130, 130, SAMPLER2DARRAYSHADOW);
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 232 "glsl_lexer.lpp"
+KEYWORD(130, 130, ISAMPLER1D);
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 233 "glsl_lexer.lpp"
+KEYWORD(130, 130, ISAMPLER2D);
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 234 "glsl_lexer.lpp"
+KEYWORD(130, 130, ISAMPLER3D);
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 235 "glsl_lexer.lpp"
+KEYWORD(130, 130, ISAMPLERCUBE);
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 236 "glsl_lexer.lpp"
+KEYWORD(130, 130, ISAMPLER1DARRAY);
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 237 "glsl_lexer.lpp"
+KEYWORD(130, 130, ISAMPLER2DARRAY);
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 238 "glsl_lexer.lpp"
+KEYWORD(130, 130, USAMPLER1D);
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 239 "glsl_lexer.lpp"
+KEYWORD(130, 130, USAMPLER2D);
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 240 "glsl_lexer.lpp"
+KEYWORD(130, 130, USAMPLER3D);
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 241 "glsl_lexer.lpp"
+KEYWORD(130, 130, USAMPLERCUBE);
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 242 "glsl_lexer.lpp"
+KEYWORD(130, 130, USAMPLER1DARRAY);
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 243 "glsl_lexer.lpp"
+KEYWORD(130, 130, USAMPLER2DARRAY);
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 246 "glsl_lexer.lpp"
+return STRUCT;
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 247 "glsl_lexer.lpp"
+return VOID_TOK;
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 249 "glsl_lexer.lpp"
+{
+ if ((yyextra->language_version >= 140)
+ || yyextra->ARB_explicit_attrib_location_enable
+ || (yyextra->ARB_fragment_coord_conventions_enable)){
+ return LAYOUT_TOK;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 260 "glsl_lexer.lpp"
+return INC_OP;
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 261 "glsl_lexer.lpp"
+return DEC_OP;
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 262 "glsl_lexer.lpp"
+return LE_OP;
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 263 "glsl_lexer.lpp"
+return GE_OP;
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 264 "glsl_lexer.lpp"
+return EQ_OP;
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 265 "glsl_lexer.lpp"
+return NE_OP;
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 266 "glsl_lexer.lpp"
+return AND_OP;
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 267 "glsl_lexer.lpp"
+return OR_OP;
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 268 "glsl_lexer.lpp"
+return XOR_OP;
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 269 "glsl_lexer.lpp"
+return LEFT_OP;
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 270 "glsl_lexer.lpp"
+return RIGHT_OP;
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 272 "glsl_lexer.lpp"
+return MUL_ASSIGN;
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 273 "glsl_lexer.lpp"
+return DIV_ASSIGN;
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 274 "glsl_lexer.lpp"
+return ADD_ASSIGN;
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 275 "glsl_lexer.lpp"
+return MOD_ASSIGN;
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 276 "glsl_lexer.lpp"
+return LEFT_ASSIGN;
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 277 "glsl_lexer.lpp"
+return RIGHT_ASSIGN;
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 278 "glsl_lexer.lpp"
+return AND_ASSIGN;
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 279 "glsl_lexer.lpp"
+return XOR_ASSIGN;
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 280 "glsl_lexer.lpp"
+return OR_ASSIGN;
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 281 "glsl_lexer.lpp"
+return SUB_ASSIGN;
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 283 "glsl_lexer.lpp"
+{
+ yylval->n = strtol(yytext, NULL, 10);
+ return IS_UINT ? UINTCONSTANT : INTCONSTANT;
+ }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 287 "glsl_lexer.lpp"
+{
+ yylval->n = strtol(yytext + 2, NULL, 16);
+ return IS_UINT ? UINTCONSTANT : INTCONSTANT;
+ }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 291 "glsl_lexer.lpp"
+{
+ yylval->n = strtol(yytext, NULL, 8);
+ return IS_UINT ? UINTCONSTANT : INTCONSTANT;
+ }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 296 "glsl_lexer.lpp"
+{
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 300 "glsl_lexer.lpp"
+{
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 304 "glsl_lexer.lpp"
+{
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 308 "glsl_lexer.lpp"
+{
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 312 "glsl_lexer.lpp"
+{
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 317 "glsl_lexer.lpp"
+{
+ yylval->n = 1;
+ return BOOLCONSTANT;
+ }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 321 "glsl_lexer.lpp"
+{
+ yylval->n = 0;
+ return BOOLCONSTANT;
+ }
+ YY_BREAK
+/* Reserved words in GLSL 1.10. */
+case 127:
+YY_RULE_SETUP
+#line 328 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, ASM);
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 329 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, CLASS);
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 330 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, UNION);
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 331 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, ENUM);
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 332 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, TYPEDEF);
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 333 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, TEMPLATE);
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 334 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, THIS);
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 335 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, PACKED_TOK);
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 336 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, GOTO);
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 337 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 130, SWITCH);
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 338 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 130, DEFAULT);
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 339 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, INLINE_TOK);
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 340 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, NOINLINE);
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 341 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, VOLATILE);
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 342 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, PUBLIC_TOK);
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 343 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, STATIC);
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 344 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, EXTERN);
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 345 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, EXTERNAL);
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 346 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, INTERFACE);
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 347 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, LONG_TOK);
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 348 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, SHORT_TOK);
+ YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 349 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 400, DOUBLE_TOK);
+ YY_BREAK
+case 149:
+YY_RULE_SETUP
+#line 350 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, HALF);
+ YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 351 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, FIXED_TOK);
+ YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 352 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, UNSIGNED);
+ YY_BREAK
+case 152:
+YY_RULE_SETUP
+#line 353 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, INPUT_TOK);
+ YY_BREAK
+case 153:
+YY_RULE_SETUP
+#line 354 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, OUTPUT);
+ YY_BREAK
+case 154:
+YY_RULE_SETUP
+#line 355 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, HVEC2);
+ YY_BREAK
+case 155:
+YY_RULE_SETUP
+#line 356 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, HVEC3);
+ YY_BREAK
+case 156:
+YY_RULE_SETUP
+#line 357 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, HVEC4);
+ YY_BREAK
+case 157:
+YY_RULE_SETUP
+#line 358 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 400, DVEC2);
+ YY_BREAK
+case 158:
+YY_RULE_SETUP
+#line 359 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 400, DVEC3);
+ YY_BREAK
+case 159:
+YY_RULE_SETUP
+#line 360 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 400, DVEC4);
+ YY_BREAK
+case 160:
+YY_RULE_SETUP
+#line 361 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, FVEC2);
+ YY_BREAK
+case 161:
+YY_RULE_SETUP
+#line 362 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, FVEC3);
+ YY_BREAK
+case 162:
+YY_RULE_SETUP
+#line 363 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, FVEC4);
+ YY_BREAK
+case 163:
+YY_RULE_SETUP
+#line 364 "glsl_lexer.lpp"
+return SAMPLER2DRECT;
+ YY_BREAK
+case 164:
+YY_RULE_SETUP
+#line 365 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, SAMPLER3DRECT);
+ YY_BREAK
+case 165:
+YY_RULE_SETUP
+#line 366 "glsl_lexer.lpp"
+return SAMPLER2DRECTSHADOW;
+ YY_BREAK
+case 166:
+YY_RULE_SETUP
+#line 367 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, SIZEOF);
+ YY_BREAK
+case 167:
+YY_RULE_SETUP
+#line 368 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, CAST);
+ YY_BREAK
+case 168:
+YY_RULE_SETUP
+#line 369 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, NAMESPACE);
+ YY_BREAK
+case 169:
+YY_RULE_SETUP
+#line 370 "glsl_lexer.lpp"
+KEYWORD(110 || ES, 999, USING);
+ YY_BREAK
+/* Additional reserved words in GLSL 1.20. */
+case 170:
+YY_RULE_SETUP
+#line 373 "glsl_lexer.lpp"
+KEYWORD(120, 130 || ES, LOWP);
+ YY_BREAK
+case 171:
+YY_RULE_SETUP
+#line 374 "glsl_lexer.lpp"
+KEYWORD(120, 130 || ES, MEDIUMP);
+ YY_BREAK
+case 172:
+YY_RULE_SETUP
+#line 375 "glsl_lexer.lpp"
+KEYWORD(120, 130 || ES, HIGHP);
+ YY_BREAK
+case 173:
+YY_RULE_SETUP
+#line 376 "glsl_lexer.lpp"
+KEYWORD(120, 130 || ES, PRECISION);
+ YY_BREAK
+/* Additional reserved words in GLSL 1.30. */
+case 174:
+YY_RULE_SETUP
+#line 379 "glsl_lexer.lpp"
+KEYWORD(130, 130, CASE);
+ YY_BREAK
+case 175:
+YY_RULE_SETUP
+#line 380 "glsl_lexer.lpp"
+KEYWORD(130, 999, COMMON);
+ YY_BREAK
+case 176:
+YY_RULE_SETUP
+#line 381 "glsl_lexer.lpp"
+KEYWORD(130, 999, PARTITION);
+ YY_BREAK
+case 177:
+YY_RULE_SETUP
+#line 382 "glsl_lexer.lpp"
+KEYWORD(130, 999, ACTIVE);
+ YY_BREAK
+case 178:
+YY_RULE_SETUP
+#line 383 "glsl_lexer.lpp"
+KEYWORD(130 || ES, 999, SUPERP);
+ YY_BREAK
+case 179:
+YY_RULE_SETUP
+#line 384 "glsl_lexer.lpp"
+KEYWORD(130, 140, SAMPLERBUFFER);
+ YY_BREAK
+case 180:
+YY_RULE_SETUP
+#line 385 "glsl_lexer.lpp"
+KEYWORD(130, 999, FILTER);
+ YY_BREAK
+case 181:
+YY_RULE_SETUP
+#line 386 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE1D);
+ YY_BREAK
+case 182:
+YY_RULE_SETUP
+#line 387 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE2D);
+ YY_BREAK
+case 183:
+YY_RULE_SETUP
+#line 388 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE3D);
+ YY_BREAK
+case 184:
+YY_RULE_SETUP
+#line 389 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGECUBE);
+ YY_BREAK
+case 185:
+YY_RULE_SETUP
+#line 390 "glsl_lexer.lpp"
+KEYWORD(130, 999, IIMAGE1D);
+ YY_BREAK
+case 186:
+YY_RULE_SETUP
+#line 391 "glsl_lexer.lpp"
+KEYWORD(130, 999, IIMAGE2D);
+ YY_BREAK
+case 187:
+YY_RULE_SETUP
+#line 392 "glsl_lexer.lpp"
+KEYWORD(130, 999, IIMAGE3D);
+ YY_BREAK
+case 188:
+YY_RULE_SETUP
+#line 393 "glsl_lexer.lpp"
+KEYWORD(130, 999, IIMAGECUBE);
+ YY_BREAK
+case 189:
+YY_RULE_SETUP
+#line 394 "glsl_lexer.lpp"
+KEYWORD(130, 999, UIMAGE1D);
+ YY_BREAK
+case 190:
+YY_RULE_SETUP
+#line 395 "glsl_lexer.lpp"
+KEYWORD(130, 999, UIMAGE2D);
+ YY_BREAK
+case 191:
+YY_RULE_SETUP
+#line 396 "glsl_lexer.lpp"
+KEYWORD(130, 999, UIMAGE3D);
+ YY_BREAK
+case 192:
+YY_RULE_SETUP
+#line 397 "glsl_lexer.lpp"
+KEYWORD(130, 999, UIMAGECUBE);
+ YY_BREAK
+case 193:
+YY_RULE_SETUP
+#line 398 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE1DARRAY);
+ YY_BREAK
+case 194:
+YY_RULE_SETUP
+#line 399 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE2DARRAY);
+ YY_BREAK
+case 195:
+YY_RULE_SETUP
+#line 400 "glsl_lexer.lpp"
+KEYWORD(130, 999, IIMAGE1DARRAY);
+ YY_BREAK
+case 196:
+YY_RULE_SETUP
+#line 401 "glsl_lexer.lpp"
+KEYWORD(130, 999, IIMAGE2DARRAY);
+ YY_BREAK
+case 197:
+YY_RULE_SETUP
+#line 402 "glsl_lexer.lpp"
+KEYWORD(130, 999, UIMAGE1DARRAY);
+ YY_BREAK
+case 198:
+YY_RULE_SETUP
+#line 403 "glsl_lexer.lpp"
+KEYWORD(130, 999, UIMAGE2DARRAY);
+ YY_BREAK
+case 199:
+YY_RULE_SETUP
+#line 404 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE1DSHADOW);
+ YY_BREAK
+case 200:
+YY_RULE_SETUP
+#line 405 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE2DSHADOW);
+ YY_BREAK
+case 201:
+YY_RULE_SETUP
+#line 406 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE1DARRAYSHADOW);
+ YY_BREAK
+case 202:
+YY_RULE_SETUP
+#line 407 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGE2DARRAYSHADOW);
+ YY_BREAK
+case 203:
+YY_RULE_SETUP
+#line 408 "glsl_lexer.lpp"
+KEYWORD(130, 999, IMAGEBUFFER);
+ YY_BREAK
+case 204:
+YY_RULE_SETUP
+#line 409 "glsl_lexer.lpp"
+KEYWORD(130, 999, IIMAGEBUFFER);
+ YY_BREAK
+case 205:
+YY_RULE_SETUP
+#line 410 "glsl_lexer.lpp"
+KEYWORD(130, 999, UIMAGEBUFFER);
+ YY_BREAK
+case 206:
+YY_RULE_SETUP
+#line 411 "glsl_lexer.lpp"
+KEYWORD(130, 999, ROW_MAJOR);
+ YY_BREAK
+case 207:
+YY_RULE_SETUP
+#line 413 "glsl_lexer.lpp"
+{
+ struct _mesa_glsl_parse_state *state = yyextra;
+ void *ctx = state;
+ yylval->identifier = talloc_strdup(ctx, yytext);
+ return IDENTIFIER;
+ }
+ YY_BREAK
+case 208:
+YY_RULE_SETUP
+#line 420 "glsl_lexer.lpp"
+{ return yytext[0]; }
+ YY_BREAK
+case 209:
+YY_RULE_SETUP
+#line 422 "glsl_lexer.lpp"
+ECHO;
+ YY_BREAK
+#line 2530 "glsl_lexer.cpp"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(PP):
+case YY_STATE_EOF(PRAGMA):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * _mesa_glsl_lex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( _mesa_glsl_wrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of _mesa_glsl_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ _mesa_glsl_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ _mesa_glsl_restart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) _mesa_glsl_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 813 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 813 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 812);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ _mesa_glsl_restart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( _mesa_glsl_wrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void _mesa_glsl_restart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ _mesa_glsl_ensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ _mesa_glsl__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ _mesa_glsl__load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * _mesa_glsl_pop_buffer_state();
+ * _mesa_glsl_push_buffer_state(new_buffer);
+ */
+ _mesa_glsl_ensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ _mesa_glsl__load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (_mesa_glsl_wrap()) processing, but the only time this flag
+ * is looked at is after _mesa_glsl_wrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) _mesa_glsl_alloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ _mesa_glsl__init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with _mesa_glsl__create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ _mesa_glsl_free((void *) b->yy_ch_buf ,yyscanner );
+
+ _mesa_glsl_free((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a _mesa_glsl_restart() or at EOF.
+ */
+ static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ _mesa_glsl__flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then _mesa_glsl__init_buffer was _probably_
+ * called from _mesa_glsl_restart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ _mesa_glsl__load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ _mesa_glsl_ensure_buffer_stack(yyscanner);
+
+ /* This block is copied from _mesa_glsl__switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from _mesa_glsl__switch_to_buffer. */
+ _mesa_glsl__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ _mesa_glsl__load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner)
+{
+ int num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_alloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_realloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE _mesa_glsl__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ _mesa_glsl__switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to _mesa_glsl_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * _mesa_glsl__scan_bytes() instead.
+ */
+YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return _mesa_glsl__scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to _mesa_glsl_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) _mesa_glsl_alloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = _mesa_glsl__scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in _mesa_glsl__scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int _mesa_glsl_get_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int _mesa_glsl_get_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *_mesa_glsl_get_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *_mesa_glsl_get_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int _mesa_glsl_get_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *_mesa_glsl_get_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void _mesa_glsl_set_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "_mesa_glsl_set_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void _mesa_glsl_set_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "_mesa_glsl_set_column called with no buffer" , yyscanner);
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see _mesa_glsl__switch_to_buffer
+ */
+void _mesa_glsl_set_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void _mesa_glsl_set_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int _mesa_glsl_get_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void _mesa_glsl_set_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylval;
+}
+
+void _mesa_glsl_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylloc;
+}
+
+void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* _mesa_glsl_lex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int _mesa_glsl_lex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* _mesa_glsl_lex_init_extra has the same functionality as _mesa_glsl_lex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to _mesa_glsl_alloc in
+ * the yyextra field.
+ */
+
+int _mesa_glsl_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ _mesa_glsl_set_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ _mesa_glsl_set_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from _mesa_glsl_lex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * _mesa_glsl_lex_init()
+ */
+ return 0;
+}
+
+/* _mesa_glsl_lex_destroy is for both reentrant and non-reentrant scanners. */
+int _mesa_glsl_lex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ _mesa_glsl_pop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ _mesa_glsl_free(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ _mesa_glsl_free(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * _mesa_glsl_lex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ _mesa_glsl_free ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *_mesa_glsl_alloc (yy_size_t size , yyscan_t yyscanner)
+{
+ return (void *) malloc( size );
+}
+
+void *_mesa_glsl_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void _mesa_glsl_free (void * ptr , yyscan_t yyscanner)
+{
+ free( (char *) ptr ); /* see _mesa_glsl_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 422 "glsl_lexer.lpp"
+
+
+
+void
+_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
+{
+ _mesa_glsl_lex_init_extra(state,& state->scanner);
+ _mesa_glsl__scan_string(string,state->scanner);
+}
+
+void
+_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
+{
+ _mesa_glsl_lex_destroy(state->scanner);
+}
+
diff --git a/mesalib/src/glsl/glsl_lexer.lpp b/mesalib/src/glsl/glsl_lexer.lpp index ed3cb251a..1c6de692a 100644 --- a/mesalib/src/glsl/glsl_lexer.lpp +++ b/mesalib/src/glsl/glsl_lexer.lpp @@ -1,399 +1,435 @@ -%{ -/* - * 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); - -#define YY_USER_INIT yylineno = 0; yycolumn = 0; - -#define TOKEN_OR_IDENTIFIER(version, token) \ - do { \ - if (yyextra->language_version >= version) { \ - return token; \ - } else { \ - yylval->identifier = strdup(yytext); \ - return IDENTIFIER; \ - } \ - } while (0) - -/* Handle reserved words in GLSL ES (version 100) */ -#define TOKEN_OR_IDENTIFIER_ES(version, token) \ - do { \ - if (yyextra->es_shader) { \ - return token; \ - } else { \ - TOKEN_OR_IDENTIFIER(version, token); \ - } \ - } while (0) - -#define RESERVED_WORD(version, token) \ - do { \ - if (yyextra->language_version >= version) { \ - return token; \ - } else { \ - _mesa_glsl_error(yylloc, yyextra, \ - "Illegal use of reserved word `%s'", yytext); \ - return ERROR_TOK; \ - } \ - } 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 PRAGMA - -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; - } -^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) { - BEGIN PP; - return PRAGMA_DEBUG_ON; - } -^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) { - BEGIN PP; - return PRAGMA_DEBUG_OFF; - } -^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) { - BEGIN PP; - return PRAGMA_OPTIMIZE_ON; - } -^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) { - BEGIN PP; - return PRAGMA_OPTIMIZE_OFF; - } -^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; } - -<PRAGMA>\n { BEGIN 0; yylineno++; yycolumn = 0; } -<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_TOK; -bool return BOOL_TOK; -float return FLOAT_TOK; -int return INT_TOK; - -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 MAT2X2; -mat3 return MAT3X3; -mat4 return MAT4X4; -mat2x2 TOKEN_OR_IDENTIFIER(120, MAT2X2); -mat2x3 TOKEN_OR_IDENTIFIER(120, MAT2X3); -mat2x4 TOKEN_OR_IDENTIFIER(120, MAT2X4); -mat3x2 TOKEN_OR_IDENTIFIER(120, MAT3X2); -mat3x3 TOKEN_OR_IDENTIFIER(120, MAT3X3); -mat3x4 TOKEN_OR_IDENTIFIER(120, MAT3X4); -mat4x2 TOKEN_OR_IDENTIFIER(120, MAT4X2); -mat4x3 TOKEN_OR_IDENTIFIER(120, MAT4X3); -mat4x4 TOKEN_OR_IDENTIFIER(120, MAT4X4); - -in return IN_TOK; -out return OUT_TOK; -inout return INOUT_TOK; -uniform return UNIFORM; -varying return VARYING; -centroid TOKEN_OR_IDENTIFIER(120, CENTROID); -invariant TOKEN_OR_IDENTIFIER_ES(120, INVARIANT); - -flat TOKEN_OR_IDENTIFIER_ES(130, FLAT); -smooth TOKEN_OR_IDENTIFIER(130, SMOOTH); -noperspective TOKEN_OR_IDENTIFIER(130, NOPERSPECTIVE); - -sampler1D return SAMPLER1D; -sampler2D return SAMPLER2D; -sampler3D return SAMPLER3D; -samplerCube return SAMPLERCUBE; -sampler1DShadow return SAMPLER1DSHADOW; -sampler2DShadow return SAMPLER2DSHADOW; - -struct return STRUCT; -void return VOID_TOK; - -layout { - if ((yyextra->language_version >= 140) - || (yyextra->ARB_fragment_coord_conventions_enable)){ - return LAYOUT_TOK; - } else { - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } - } - -\+\+ 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, 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; - } -[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 RESERVED_WORD(999, ASM); -class RESERVED_WORD(999, CLASS); -union RESERVED_WORD(999, UNION); -enum RESERVED_WORD(999, ENUM); -typedef RESERVED_WORD(999, TYPEDEF); -template RESERVED_WORD(999, TEMPLATE); -this RESERVED_WORD(999, THIS); -packed RESERVED_WORD(999, PACKED_TOK); -goto RESERVED_WORD(999, GOTO); -switch RESERVED_WORD(130, SWITCH); -default RESERVED_WORD(130, DEFAULT); -inline RESERVED_WORD(999, INLINE_TOK); -noinline RESERVED_WORD(999, NOINLINE); -volatile RESERVED_WORD(999, VOLATILE); -public RESERVED_WORD(999, PUBLIC_TOK); -static RESERVED_WORD(999, STATIC); -extern RESERVED_WORD(999, EXTERN); -external RESERVED_WORD(999, EXTERNAL); -interface RESERVED_WORD(999, INTERFACE); -long RESERVED_WORD(999, LONG_TOK); -short RESERVED_WORD(999, SHORT_TOK); -double RESERVED_WORD(999, DOUBLE_TOK); -half RESERVED_WORD(999, HALF); -fixed RESERVED_WORD(999, FIXED_TOK); -unsigned RESERVED_WORD(999, UNSIGNED); -input RESERVED_WORD(999, INPUT_TOK); -output RESERVED_WORD(999, OUTPUT); -hvec2 RESERVED_WORD(999, HVEC2); -hvec3 RESERVED_WORD(999, HVEC3); -hvec4 RESERVED_WORD(999, HVEC4); -dvec2 RESERVED_WORD(999, DVEC2); -dvec3 RESERVED_WORD(999, DVEC3); -dvec4 RESERVED_WORD(999, DVEC4); -fvec2 RESERVED_WORD(999, FVEC2); -fvec3 RESERVED_WORD(999, FVEC3); -fvec4 RESERVED_WORD(999, FVEC4); -sampler2DRect return SAMPLER2DRECT; -sampler3DRect RESERVED_WORD(999, SAMPLER3DRECT); -sampler2DRectShadow return SAMPLER2DRECTSHADOW; -sizeof RESERVED_WORD(999, SIZEOF); -cast RESERVED_WORD(999, CAST); -namespace RESERVED_WORD(999, NAMESPACE); -using RESERVED_WORD(999, USING); - - /* Additional reserved words in GLSL 1.20. */ -lowp TOKEN_OR_IDENTIFIER_ES(120, LOWP); -mediump TOKEN_OR_IDENTIFIER_ES(120, MEDIUMP); -highp TOKEN_OR_IDENTIFIER_ES(120, HIGHP); -precision TOKEN_OR_IDENTIFIER_ES(120, PRECISION); - - /* Additional reserved words in GLSL 1.30. */ -common TOKEN_OR_IDENTIFIER(130, COMMON); -partition TOKEN_OR_IDENTIFIER(130, PARTITION); -active TOKEN_OR_IDENTIFIER(130, ACTIVE); -superp TOKEN_OR_IDENTIFIER_ES(130, SUPERP); -samplerBuffer TOKEN_OR_IDENTIFIER(130, SAMPLERBUFFER); -filter TOKEN_OR_IDENTIFIER(130, FILTER); -image1D TOKEN_OR_IDENTIFIER(130, IMAGE1D); -image2D TOKEN_OR_IDENTIFIER(130, IMAGE2D); -image3D TOKEN_OR_IDENTIFIER(130, IMAGE3D); -imageCube TOKEN_OR_IDENTIFIER(130, IMAGECUBE); -iimage1D TOKEN_OR_IDENTIFIER(130, IIMAGE1D); -iimage2D TOKEN_OR_IDENTIFIER(130, IIMAGE2D); -iimage3D TOKEN_OR_IDENTIFIER(130, IIMAGE3D); -iimageCube TOKEN_OR_IDENTIFIER(130, IIMAGECUBE); -uimage1D TOKEN_OR_IDENTIFIER(130, UIMAGE1D); -uimage2D TOKEN_OR_IDENTIFIER(130, UIMAGE2D); -uimage3D TOKEN_OR_IDENTIFIER(130, UIMAGE3D); -uimageCube TOKEN_OR_IDENTIFIER(130, UIMAGECUBE); -image1DArray TOKEN_OR_IDENTIFIER(130, IMAGE1DARRAY); -image2DArray TOKEN_OR_IDENTIFIER(130, IMAGE2DARRAY); -iimage1DArray TOKEN_OR_IDENTIFIER(130, IIMAGE1DARRAY); -iimage2DArray TOKEN_OR_IDENTIFIER(130, IIMAGE2DARRAY); -uimage1DArray TOKEN_OR_IDENTIFIER(130, UIMAGE1DARRAY); -uimage2DArray TOKEN_OR_IDENTIFIER(130, UIMAGE2DARRAY); -image1DShadow TOKEN_OR_IDENTIFIER(130, IMAGE1DSHADOW); -image2DShadow TOKEN_OR_IDENTIFIER(130, IMAGE2DSHADOW); -imageBuffer TOKEN_OR_IDENTIFIER(130, IMAGEBUFFER); -iimageBuffer TOKEN_OR_IDENTIFIER(130, IIMAGEBUFFER); -uimageBuffer TOKEN_OR_IDENTIFIER(130, UIMAGEBUFFER); -row_major TOKEN_OR_IDENTIFIER(130, ROW_MAJOR); - -[_a-zA-Z][_a-zA-Z0-9]* { - struct _mesa_glsl_parse_state *state = yyextra; - void *ctx = 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); -} +%{
+/*
+ * 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 "strtod.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);
+
+#define YY_USER_INIT yylineno = 0; yycolumn = 0;
+
+#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U')
+
+/* A macro for handling reserved words and keywords across language versions.
+ *
+ * Certain words start out as identifiers, become reserved words in
+ * later language revisions, and finally become language keywords.
+ *
+ * For example, consider the following lexer rule:
+ * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER)
+ *
+ * This means that "samplerBuffer" will be treated as:
+ * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40
+ * - a reserved word - error ...in GLSL >= 1.30
+ * - an identifier ...in GLSL < 1.30
+ */
+#define KEYWORD(reserved_version, allowed_version, token) \
+ do { \
+ if (yyextra->language_version >= allowed_version) { \
+ return token; \
+ } else if (yyextra->language_version >= reserved_version) { \
+ _mesa_glsl_error(yylloc, yyextra, \
+ "Illegal use of reserved word `%s'", yytext); \
+ return ERROR_TOK; \
+ } else { \
+ yylval->identifier = strdup(yytext); \
+ return IDENTIFIER; \
+ } \
+ } while (0)
+
+/* The ES macro can be used in KEYWORD checks:
+ *
+ * word KEYWORD(110 || ES, 400, TOKEN)
+ * ...means the word is reserved in GLSL ES 1.00, while
+ *
+ * word KEYWORD(110, 130 || ES, TOKEN)
+ * ...means the word is a legal keyword in GLSL ES 1.00.
+ */
+#define ES yyextra->es_shader
+%}
+
+%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 PRAGMA
+
+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;
+ }
+^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_DEBUG_ON;
+ }
+^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_DEBUG_OFF;
+ }
+^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_OPTIMIZE_ON;
+ }
+^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_OPTIMIZE_OFF;
+ }
+^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; }
+
+<PRAGMA>\n { BEGIN 0; yylineno++; yycolumn = 0; }
+<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_TOK;
+bool return BOOL_TOK;
+float return FLOAT_TOK;
+int return INT_TOK;
+uint KEYWORD(130, 130, UINT_TOK);
+
+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;
+uvec2 KEYWORD(130, 130, UVEC2);
+uvec3 KEYWORD(130, 130, UVEC3);
+uvec4 KEYWORD(130, 130, UVEC4);
+vec2 return VEC2;
+vec3 return VEC3;
+vec4 return VEC4;
+mat2 return MAT2X2;
+mat3 return MAT3X3;
+mat4 return MAT4X4;
+mat2x2 KEYWORD(120, 120, MAT2X2);
+mat2x3 KEYWORD(120, 120, MAT2X3);
+mat2x4 KEYWORD(120, 120, MAT2X4);
+mat3x2 KEYWORD(120, 120, MAT3X2);
+mat3x3 KEYWORD(120, 120, MAT3X3);
+mat3x4 KEYWORD(120, 120, MAT3X4);
+mat4x2 KEYWORD(120, 120, MAT4X2);
+mat4x3 KEYWORD(120, 120, MAT4X3);
+mat4x4 KEYWORD(120, 120, MAT4X4);
+
+in return IN_TOK;
+out return OUT_TOK;
+inout return INOUT_TOK;
+uniform return UNIFORM;
+varying return VARYING;
+centroid KEYWORD(120, 120, CENTROID);
+invariant KEYWORD(120 || ES, 120 || ES, INVARIANT);
+flat KEYWORD(130 || ES, 130, FLAT);
+smooth KEYWORD(130, 130, SMOOTH);
+noperspective KEYWORD(130, 130, NOPERSPECTIVE);
+
+sampler1D return SAMPLER1D;
+sampler2D return SAMPLER2D;
+sampler3D return SAMPLER3D;
+samplerCube return SAMPLERCUBE;
+sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY);
+sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY);
+sampler1DShadow return SAMPLER1DSHADOW;
+sampler2DShadow return SAMPLER2DSHADOW;
+samplerCubeShadow KEYWORD(130, 130, SAMPLERCUBESHADOW);
+sampler1DArrayShadow KEYWORD(130, 130, SAMPLER1DARRAYSHADOW);
+sampler2DArrayShadow KEYWORD(130, 130, SAMPLER2DARRAYSHADOW);
+isampler1D KEYWORD(130, 130, ISAMPLER1D);
+isampler2D KEYWORD(130, 130, ISAMPLER2D);
+isampler3D KEYWORD(130, 130, ISAMPLER3D);
+isamplerCube KEYWORD(130, 130, ISAMPLERCUBE);
+isampler1DArray KEYWORD(130, 130, ISAMPLER1DARRAY);
+isampler2DArray KEYWORD(130, 130, ISAMPLER2DARRAY);
+usampler1D KEYWORD(130, 130, USAMPLER1D);
+usampler2D KEYWORD(130, 130, USAMPLER2D);
+usampler3D KEYWORD(130, 130, USAMPLER3D);
+usamplerCube KEYWORD(130, 130, USAMPLERCUBE);
+usampler1DArray KEYWORD(130, 130, USAMPLER1DARRAY);
+usampler2DArray KEYWORD(130, 130, USAMPLER2DARRAY);
+
+
+struct return STRUCT;
+void return VOID_TOK;
+
+layout {
+ if ((yyextra->language_version >= 140)
+ || yyextra->ARB_explicit_attrib_location_enable
+ || (yyextra->ARB_fragment_coord_conventions_enable)){
+ return LAYOUT_TOK;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+
+\+\+ 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 LEFT_OP;
+">>" return RIGHT_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]*[uU]? {
+ yylval->n = strtol(yytext, NULL, 10);
+ return IS_UINT ? UINTCONSTANT : INTCONSTANT;
+ }
+0[xX][0-9a-fA-F]+[uU]? {
+ yylval->n = strtol(yytext + 2, NULL, 16);
+ return IS_UINT ? UINTCONSTANT : INTCONSTANT;
+ }
+0[0-7]*[uU]? {
+ yylval->n = strtol(yytext, NULL, 8);
+ return IS_UINT ? UINTCONSTANT : INTCONSTANT;
+ }
+
+[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+[eE][+-]?[0-9]+[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+[fF] {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+
+true {
+ yylval->n = 1;
+ return BOOLCONSTANT;
+ }
+false {
+ yylval->n = 0;
+ return BOOLCONSTANT;
+ }
+
+
+ /* Reserved words in GLSL 1.10. */
+asm KEYWORD(110 || ES, 999, ASM);
+class KEYWORD(110 || ES, 999, CLASS);
+union KEYWORD(110 || ES, 999, UNION);
+enum KEYWORD(110 || ES, 999, ENUM);
+typedef KEYWORD(110 || ES, 999, TYPEDEF);
+template KEYWORD(110 || ES, 999, TEMPLATE);
+this KEYWORD(110 || ES, 999, THIS);
+packed KEYWORD(110 || ES, 999, PACKED_TOK);
+goto KEYWORD(110 || ES, 999, GOTO);
+switch KEYWORD(110 || ES, 130, SWITCH);
+default KEYWORD(110 || ES, 130, DEFAULT);
+inline KEYWORD(110 || ES, 999, INLINE_TOK);
+noinline KEYWORD(110 || ES, 999, NOINLINE);
+volatile KEYWORD(110 || ES, 999, VOLATILE);
+public KEYWORD(110 || ES, 999, PUBLIC_TOK);
+static KEYWORD(110 || ES, 999, STATIC);
+extern KEYWORD(110 || ES, 999, EXTERN);
+external KEYWORD(110 || ES, 999, EXTERNAL);
+interface KEYWORD(110 || ES, 999, INTERFACE);
+long KEYWORD(110 || ES, 999, LONG_TOK);
+short KEYWORD(110 || ES, 999, SHORT_TOK);
+double KEYWORD(110 || ES, 400, DOUBLE_TOK);
+half KEYWORD(110 || ES, 999, HALF);
+fixed KEYWORD(110 || ES, 999, FIXED_TOK);
+unsigned KEYWORD(110 || ES, 999, UNSIGNED);
+input KEYWORD(110 || ES, 999, INPUT_TOK);
+output KEYWORD(110 || ES, 999, OUTPUT);
+hvec2 KEYWORD(110 || ES, 999, HVEC2);
+hvec3 KEYWORD(110 || ES, 999, HVEC3);
+hvec4 KEYWORD(110 || ES, 999, HVEC4);
+dvec2 KEYWORD(110 || ES, 400, DVEC2);
+dvec3 KEYWORD(110 || ES, 400, DVEC3);
+dvec4 KEYWORD(110 || ES, 400, DVEC4);
+fvec2 KEYWORD(110 || ES, 999, FVEC2);
+fvec3 KEYWORD(110 || ES, 999, FVEC3);
+fvec4 KEYWORD(110 || ES, 999, FVEC4);
+sampler2DRect return SAMPLER2DRECT;
+sampler3DRect KEYWORD(110 || ES, 999, SAMPLER3DRECT);
+sampler2DRectShadow return SAMPLER2DRECTSHADOW;
+sizeof KEYWORD(110 || ES, 999, SIZEOF);
+cast KEYWORD(110 || ES, 999, CAST);
+namespace KEYWORD(110 || ES, 999, NAMESPACE);
+using KEYWORD(110 || ES, 999, USING);
+
+ /* Additional reserved words in GLSL 1.20. */
+lowp KEYWORD(120, 130 || ES, LOWP);
+mediump KEYWORD(120, 130 || ES, MEDIUMP);
+highp KEYWORD(120, 130 || ES, HIGHP);
+precision KEYWORD(120, 130 || ES, PRECISION);
+
+ /* Additional reserved words in GLSL 1.30. */
+case KEYWORD(130, 130, CASE);
+common KEYWORD(130, 999, COMMON);
+partition KEYWORD(130, 999, PARTITION);
+active KEYWORD(130, 999, ACTIVE);
+superp KEYWORD(130 || ES, 999, SUPERP);
+samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER);
+filter KEYWORD(130, 999, FILTER);
+image1D KEYWORD(130, 999, IMAGE1D);
+image2D KEYWORD(130, 999, IMAGE2D);
+image3D KEYWORD(130, 999, IMAGE3D);
+imageCube KEYWORD(130, 999, IMAGECUBE);
+iimage1D KEYWORD(130, 999, IIMAGE1D);
+iimage2D KEYWORD(130, 999, IIMAGE2D);
+iimage3D KEYWORD(130, 999, IIMAGE3D);
+iimageCube KEYWORD(130, 999, IIMAGECUBE);
+uimage1D KEYWORD(130, 999, UIMAGE1D);
+uimage2D KEYWORD(130, 999, UIMAGE2D);
+uimage3D KEYWORD(130, 999, UIMAGE3D);
+uimageCube KEYWORD(130, 999, UIMAGECUBE);
+image1DArray KEYWORD(130, 999, IMAGE1DARRAY);
+image2DArray KEYWORD(130, 999, IMAGE2DARRAY);
+iimage1DArray KEYWORD(130, 999, IIMAGE1DARRAY);
+iimage2DArray KEYWORD(130, 999, IIMAGE2DARRAY);
+uimage1DArray KEYWORD(130, 999, UIMAGE1DARRAY);
+uimage2DArray KEYWORD(130, 999, UIMAGE2DARRAY);
+image1DShadow KEYWORD(130, 999, IMAGE1DSHADOW);
+image2DShadow KEYWORD(130, 999, IMAGE2DSHADOW);
+image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW);
+image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW);
+imageBuffer KEYWORD(130, 999, IMAGEBUFFER);
+iimageBuffer KEYWORD(130, 999, IIMAGEBUFFER);
+uimageBuffer KEYWORD(130, 999, UIMAGEBUFFER);
+row_major KEYWORD(130, 999, ROW_MAJOR);
+
+[_a-zA-Z][_a-zA-Z0-9]* {
+ struct _mesa_glsl_parse_state *state = yyextra;
+ void *ctx = 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);
+}
diff --git a/mesalib/src/glsl/glsl_parser.cpp b/mesalib/src/glsl/glsl_parser.cpp index 301c22189..df858db2b 100644 --- a/mesalib/src/glsl/glsl_parser.cpp +++ b/mesalib/src/glsl/glsl_parser.cpp @@ -1,5232 +1,5306 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2009, 2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 1 - -/* Substitute the variable and function names. */ -#define yyparse _mesa_glsl_parse -#define yylex _mesa_glsl_lex -#define yyerror _mesa_glsl_error -#define yylval _mesa_glsl_lval -#define yychar _mesa_glsl_char -#define yydebug _mesa_glsl_debug -#define yynerrs _mesa_glsl_nerrs -#define yylloc _mesa_glsl_lloc - -/* Copy the first part of user declarations. */ - -/* Line 189 of yacc.c */ -#line 1 "glsl_parser.ypp" - -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_types.h" - -#define YYLEX_PARAM state->scanner - - - -/* Line 189 of yacc.c */ -#line 117 "glsl_parser.cpp" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ATTRIBUTE = 258, - CONST_TOK = 259, - BOOL_TOK = 260, - FLOAT_TOK = 261, - INT_TOK = 262, - UINT_TOK = 263, - BREAK = 264, - CONTINUE = 265, - DO = 266, - ELSE = 267, - FOR = 268, - IF = 269, - DISCARD = 270, - RETURN = 271, - SWITCH = 272, - CASE = 273, - DEFAULT = 274, - BVEC2 = 275, - BVEC3 = 276, - BVEC4 = 277, - IVEC2 = 278, - IVEC3 = 279, - IVEC4 = 280, - UVEC2 = 281, - UVEC3 = 282, - UVEC4 = 283, - VEC2 = 284, - VEC3 = 285, - VEC4 = 286, - CENTROID = 287, - IN_TOK = 288, - OUT_TOK = 289, - INOUT_TOK = 290, - UNIFORM = 291, - VARYING = 292, - NOPERSPECTIVE = 293, - FLAT = 294, - SMOOTH = 295, - MAT2X2 = 296, - MAT2X3 = 297, - MAT2X4 = 298, - MAT3X2 = 299, - MAT3X3 = 300, - MAT3X4 = 301, - MAT4X2 = 302, - MAT4X3 = 303, - MAT4X4 = 304, - SAMPLER1D = 305, - SAMPLER2D = 306, - SAMPLER3D = 307, - SAMPLERCUBE = 308, - SAMPLER1DSHADOW = 309, - SAMPLER2DSHADOW = 310, - SAMPLERCUBESHADOW = 311, - SAMPLER1DARRAY = 312, - SAMPLER2DARRAY = 313, - SAMPLER1DARRAYSHADOW = 314, - SAMPLER2DARRAYSHADOW = 315, - ISAMPLER1D = 316, - ISAMPLER2D = 317, - ISAMPLER3D = 318, - ISAMPLERCUBE = 319, - ISAMPLER1DARRAY = 320, - ISAMPLER2DARRAY = 321, - USAMPLER1D = 322, - USAMPLER2D = 323, - USAMPLER3D = 324, - USAMPLERCUBE = 325, - USAMPLER1DARRAY = 326, - USAMPLER2DARRAY = 327, - STRUCT = 328, - VOID_TOK = 329, - WHILE = 330, - IDENTIFIER = 331, - FLOATCONSTANT = 332, - INTCONSTANT = 333, - UINTCONSTANT = 334, - BOOLCONSTANT = 335, - FIELD_SELECTION = 336, - LEFT_OP = 337, - RIGHT_OP = 338, - INC_OP = 339, - DEC_OP = 340, - LE_OP = 341, - GE_OP = 342, - EQ_OP = 343, - NE_OP = 344, - AND_OP = 345, - OR_OP = 346, - XOR_OP = 347, - MUL_ASSIGN = 348, - DIV_ASSIGN = 349, - ADD_ASSIGN = 350, - MOD_ASSIGN = 351, - LEFT_ASSIGN = 352, - RIGHT_ASSIGN = 353, - AND_ASSIGN = 354, - XOR_ASSIGN = 355, - OR_ASSIGN = 356, - SUB_ASSIGN = 357, - INVARIANT = 358, - LOWP = 359, - MEDIUMP = 360, - HIGHP = 361, - SUPERP = 362, - PRECISION = 363, - VERSION = 364, - EXTENSION = 365, - LINE = 366, - COLON = 367, - EOL = 368, - INTERFACE = 369, - OUTPUT = 370, - PRAGMA_DEBUG_ON = 371, - PRAGMA_DEBUG_OFF = 372, - PRAGMA_OPTIMIZE_ON = 373, - PRAGMA_OPTIMIZE_OFF = 374, - LAYOUT_TOK = 375, - ASM = 376, - CLASS = 377, - UNION = 378, - ENUM = 379, - TYPEDEF = 380, - TEMPLATE = 381, - THIS = 382, - PACKED_TOK = 383, - GOTO = 384, - INLINE_TOK = 385, - NOINLINE = 386, - VOLATILE = 387, - PUBLIC_TOK = 388, - STATIC = 389, - EXTERN = 390, - EXTERNAL = 391, - LONG_TOK = 392, - SHORT_TOK = 393, - DOUBLE_TOK = 394, - HALF = 395, - FIXED_TOK = 396, - UNSIGNED = 397, - INPUT_TOK = 398, - OUPTUT = 399, - HVEC2 = 400, - HVEC3 = 401, - HVEC4 = 402, - DVEC2 = 403, - DVEC3 = 404, - DVEC4 = 405, - FVEC2 = 406, - FVEC3 = 407, - FVEC4 = 408, - SAMPLER2DRECT = 409, - SAMPLER3DRECT = 410, - SAMPLER2DRECTSHADOW = 411, - SIZEOF = 412, - CAST = 413, - NAMESPACE = 414, - USING = 415, - ERROR_TOK = 416, - COMMON = 417, - PARTITION = 418, - ACTIVE = 419, - SAMPLERBUFFER = 420, - FILTER = 421, - IMAGE1D = 422, - IMAGE2D = 423, - IMAGE3D = 424, - IMAGECUBE = 425, - IMAGE1DARRAY = 426, - IMAGE2DARRAY = 427, - IIMAGE1D = 428, - IIMAGE2D = 429, - IIMAGE3D = 430, - IIMAGECUBE = 431, - IIMAGE1DARRAY = 432, - IIMAGE2DARRAY = 433, - UIMAGE1D = 434, - UIMAGE2D = 435, - UIMAGE3D = 436, - UIMAGECUBE = 437, - UIMAGE1DARRAY = 438, - UIMAGE2DARRAY = 439, - IMAGE1DSHADOW = 440, - IMAGE2DSHADOW = 441, - IMAGEBUFFER = 442, - IIMAGEBUFFER = 443, - UIMAGEBUFFER = 444, - ROW_MAJOR = 445 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 214 of yacc.c */ -#line 52 "glsl_parser.ypp" - - int n; - float real; - char *identifier; - - union { - struct ast_type_qualifier q; - unsigned i; - } type_qualifier; - - ast_node *node; - ast_type_specifier *type_specifier; - ast_fully_specified_type *fully_specified_type; - ast_function *function; - ast_parameter_declarator *parameter_declarator; - ast_function_definition *function_definition; - ast_compound_statement *compound_statement; - ast_expression *expression; - ast_declarator_list *declarator_list; - ast_struct_specifier *struct_specifier; - ast_declaration *declaration; - - struct { - ast_node *cond; - ast_expression *rest; - } for_rest_statement; - - struct { - ast_node *then_statement; - ast_node *else_statement; - } selection_rest_statement; - - - -/* Line 214 of yacc.c */ -#line 378 "glsl_parser.cpp" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -/* Copy the second part of user declarations. */ - - -/* Line 264 of yacc.c */ -#line 403 "glsl_parser.cpp" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 5 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 4005 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 215 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 88 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 274 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 409 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 445 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 199, 2, 2, 2, 203, 206, 2, - 191, 192, 201, 197, 196, 198, 195, 202, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 210, 212, - 204, 211, 205, 209, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 193, 2, 194, 207, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 213, 208, 214, 200, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 4, 9, 10, 14, 17, 20, 23, - 26, 27, 30, 36, 38, 41, 43, 45, 47, 49, - 51, 53, 57, 59, 64, 66, 70, 73, 76, 78, - 80, 82, 86, 89, 92, 95, 97, 100, 104, 107, - 109, 111, 113, 115, 118, 121, 124, 126, 128, 130, - 132, 134, 138, 142, 146, 148, 152, 156, 158, 162, - 166, 168, 172, 176, 180, 184, 186, 190, 194, 196, - 200, 202, 206, 208, 212, 214, 218, 220, 224, 226, - 230, 232, 238, 240, 244, 246, 248, 250, 252, 254, - 256, 258, 260, 262, 264, 266, 268, 272, 274, 277, - 280, 285, 288, 290, 292, 295, 299, 303, 306, 312, - 316, 319, 323, 326, 327, 329, 331, 333, 335, 337, - 341, 347, 354, 362, 371, 377, 379, 382, 387, 393, - 400, 408, 413, 416, 418, 421, 422, 424, 429, 431, - 435, 437, 439, 441, 443, 445, 447, 450, 453, 455, - 457, 460, 463, 466, 468, 471, 474, 476, 478, 481, - 483, 487, 492, 494, 496, 498, 500, 502, 504, 506, - 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, - 528, 530, 532, 534, 536, 538, 540, 542, 544, 546, - 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, - 568, 570, 572, 574, 576, 578, 580, 582, 584, 586, - 588, 590, 592, 594, 596, 598, 600, 602, 604, 606, - 612, 617, 619, 622, 626, 628, 632, 634, 639, 641, - 643, 645, 647, 649, 651, 653, 655, 657, 659, 661, - 664, 668, 670, 672, 675, 679, 681, 684, 686, 689, - 695, 699, 701, 703, 708, 714, 718, 721, 727, 735, - 742, 744, 746, 748, 749, 752, 756, 759, 762, 765, - 769, 772, 774, 776, 778 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int16 yyrhs[] = -{ - 216, 0, -1, -1, 218, 220, 217, 222, -1, -1, - 109, 78, 113, -1, 116, 113, -1, 117, 113, -1, - 118, 113, -1, 119, 113, -1, -1, 220, 221, -1, - 110, 76, 112, 76, 113, -1, 301, -1, 222, 301, - -1, 76, -1, 223, -1, 78, -1, 79, -1, 77, - -1, 80, -1, 191, 250, 192, -1, 224, -1, 225, - 193, 226, 194, -1, 227, -1, 225, 195, 76, -1, - 225, 84, -1, 225, 85, -1, 250, -1, 228, -1, - 229, -1, 225, 195, 229, -1, 231, 192, -1, 230, - 192, -1, 232, 74, -1, 232, -1, 232, 248, -1, - 231, 196, 248, -1, 233, 191, -1, 272, -1, 76, - -1, 81, -1, 225, -1, 84, 234, -1, 85, 234, - -1, 235, 234, -1, 197, -1, 198, -1, 199, -1, - 200, -1, 234, -1, 236, 201, 234, -1, 236, 202, - 234, -1, 236, 203, 234, -1, 236, -1, 237, 197, - 236, -1, 237, 198, 236, -1, 237, -1, 238, 82, - 237, -1, 238, 83, 237, -1, 238, -1, 239, 204, - 238, -1, 239, 205, 238, -1, 239, 86, 238, -1, - 239, 87, 238, -1, 239, -1, 240, 88, 239, -1, - 240, 89, 239, -1, 240, -1, 241, 206, 240, -1, - 241, -1, 242, 207, 241, -1, 242, -1, 243, 208, - 242, -1, 243, -1, 244, 90, 243, -1, 244, -1, - 245, 92, 244, -1, 245, -1, 246, 91, 245, -1, - 246, -1, 246, 209, 250, 210, 248, -1, 247, -1, - 234, 249, 248, -1, 211, -1, 93, -1, 94, -1, - 96, -1, 95, -1, 102, -1, 97, -1, 98, -1, - 99, -1, 100, -1, 101, -1, 248, -1, 250, 196, - 248, -1, 247, -1, 253, 212, -1, 261, 212, -1, - 108, 276, 273, 212, -1, 254, 192, -1, 256, -1, - 255, -1, 256, 258, -1, 255, 196, 258, -1, 263, - 76, 191, -1, 272, 76, -1, 272, 76, 193, 251, - 194, -1, 269, 259, 257, -1, 259, 257, -1, 269, - 259, 260, -1, 259, 260, -1, -1, 33, -1, 34, - -1, 35, -1, 272, -1, 262, -1, 261, 196, 76, - -1, 261, 196, 76, 193, 194, -1, 261, 196, 76, - 193, 251, 194, -1, 261, 196, 76, 193, 194, 211, - 282, -1, 261, 196, 76, 193, 251, 194, 211, 282, - -1, 261, 196, 76, 211, 282, -1, 263, -1, 263, - 76, -1, 263, 76, 193, 194, -1, 263, 76, 193, - 251, 194, -1, 263, 76, 193, 194, 211, 282, -1, - 263, 76, 193, 251, 194, 211, 282, -1, 263, 76, - 211, 282, -1, 103, 76, -1, 272, -1, 270, 272, - -1, -1, 265, -1, 120, 191, 266, 192, -1, 267, - -1, 266, 196, 267, -1, 76, -1, 40, -1, 39, - -1, 38, -1, 4, -1, 271, -1, 268, 270, -1, - 103, 270, -1, 4, -1, 3, -1, 264, 37, -1, - 32, 37, -1, 264, 33, -1, 34, -1, 32, 33, - -1, 32, 34, -1, 36, -1, 273, -1, 276, 273, - -1, 274, -1, 274, 193, 194, -1, 274, 193, 251, - 194, -1, 275, -1, 277, -1, 76, -1, 74, -1, - 6, -1, 7, -1, 8, -1, 5, -1, 29, -1, - 30, -1, 31, -1, 20, -1, 21, -1, 22, -1, - 23, -1, 24, -1, 25, -1, 26, -1, 27, -1, - 28, -1, 41, -1, 42, -1, 43, -1, 44, -1, - 45, -1, 46, -1, 47, -1, 48, -1, 49, -1, - 50, -1, 51, -1, 154, -1, 52, -1, 53, -1, - 54, -1, 55, -1, 156, -1, 56, -1, 57, -1, - 58, -1, 59, -1, 60, -1, 61, -1, 62, -1, - 63, -1, 64, -1, 65, -1, 66, -1, 67, -1, - 68, -1, 69, -1, 70, -1, 71, -1, 72, -1, - 106, -1, 105, -1, 104, -1, 73, 76, 213, 278, - 214, -1, 73, 213, 278, 214, -1, 279, -1, 278, - 279, -1, 272, 280, 212, -1, 281, -1, 280, 196, - 281, -1, 76, -1, 76, 193, 251, 194, -1, 248, - -1, 252, -1, 286, -1, 285, -1, 283, -1, 290, - -1, 291, -1, 294, -1, 295, -1, 296, -1, 300, - -1, 213, 214, -1, 213, 289, 214, -1, 288, -1, - 285, -1, 213, 214, -1, 213, 289, 214, -1, 284, - -1, 289, 284, -1, 212, -1, 250, 212, -1, 14, - 191, 250, 192, 292, -1, 284, 12, 284, -1, 284, - -1, 250, -1, 263, 76, 211, 282, -1, 17, 191, - 250, 192, 286, -1, 18, 250, 210, -1, 19, 210, - -1, 75, 191, 293, 192, 287, -1, 11, 284, 75, - 191, 250, 192, 212, -1, 13, 191, 297, 299, 192, - 287, -1, 290, -1, 283, -1, 293, -1, -1, 298, - 212, -1, 298, 212, 250, -1, 10, 212, -1, 9, - 212, -1, 16, 212, -1, 16, 250, 212, -1, 15, - 212, -1, 302, -1, 252, -1, 219, -1, 253, 288, - -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 214, 214, 213, 220, 222, 242, 243, 244, 245, - 248, 250, 254, 263, 271, 282, 286, 293, 300, 307, - 314, 321, 328, 329, 335, 339, 346, 352, 361, 365, - 369, 370, 379, 380, 384, 385, 389, 395, 407, 411, - 417, 424, 435, 436, 442, 448, 458, 459, 460, 461, - 465, 466, 472, 478, 487, 488, 494, 503, 504, 510, - 519, 520, 526, 532, 538, 547, 548, 554, 563, 564, - 573, 574, 583, 584, 593, 594, 603, 604, 613, 614, - 623, 624, 633, 634, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 657, 661, 677, 681, 685, - 689, 703, 707, 708, 712, 717, 725, 736, 746, 761, - 768, 773, 784, 796, 797, 798, 799, 803, 807, 808, - 817, 826, 835, 844, 853, 866, 877, 886, 895, 904, - 913, 922, 931, 945, 952, 963, 964, 968, 975, 976, - 983, 1017, 1018, 1019, 1023, 1027, 1028, 1032, 1040, 1041, - 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1052, 1053, 1061, - 1062, 1068, 1077, 1083, 1089, 1098, 1099, 1100, 1101, 1102, - 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, - 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, - 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, - 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, - 1143, 1144, 1145, 1146, 1147, 1148, 1152, 1163, 1174, 1188, - 1194, 1203, 1208, 1216, 1231, 1236, 1244, 1250, 1259, 1263, - 1269, 1270, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1284, - 1290, 1299, 1300, 1304, 1310, 1319, 1329, 1341, 1347, 1356, - 1365, 1370, 1378, 1382, 1396, 1400, 1401, 1405, 1412, 1419, - 1429, 1430, 1434, 1436, 1442, 1447, 1456, 1462, 1468, 1474, - 1480, 1489, 1490, 1491, 1495 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "ATTRIBUTE", "CONST_TOK", "BOOL_TOK", - "FLOAT_TOK", "INT_TOK", "UINT_TOK", "BREAK", "CONTINUE", "DO", "ELSE", - "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "BVEC2", - "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "UVEC2", "UVEC3", "UVEC4", - "VEC2", "VEC3", "VEC4", "CENTROID", "IN_TOK", "OUT_TOK", "INOUT_TOK", - "UNIFORM", "VARYING", "NOPERSPECTIVE", "FLAT", "SMOOTH", "MAT2X2", - "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", - "MAT4X4", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", - "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", - "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", - "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", - "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D", - "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY", - "USAMPLER2DARRAY", "STRUCT", "VOID_TOK", "WHILE", "IDENTIFIER", - "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", - "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", - "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", - "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", - "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "INVARIANT", - "LOWP", "MEDIUMP", "HIGHP", "SUPERP", "PRECISION", "VERSION", - "EXTENSION", "LINE", "COLON", "EOL", "INTERFACE", "OUTPUT", - "PRAGMA_DEBUG_ON", "PRAGMA_DEBUG_OFF", "PRAGMA_OPTIMIZE_ON", - "PRAGMA_OPTIMIZE_OFF", "LAYOUT_TOK", "ASM", "CLASS", "UNION", "ENUM", - "TYPEDEF", "TEMPLATE", "THIS", "PACKED_TOK", "GOTO", "INLINE_TOK", - "NOINLINE", "VOLATILE", "PUBLIC_TOK", "STATIC", "EXTERN", "EXTERNAL", - "LONG_TOK", "SHORT_TOK", "DOUBLE_TOK", "HALF", "FIXED_TOK", "UNSIGNED", - "INPUT_TOK", "OUPTUT", "HVEC2", "HVEC3", "HVEC4", "DVEC2", "DVEC3", - "DVEC4", "FVEC2", "FVEC3", "FVEC4", "SAMPLER2DRECT", "SAMPLER3DRECT", - "SAMPLER2DRECTSHADOW", "SIZEOF", "CAST", "NAMESPACE", "USING", - "ERROR_TOK", "COMMON", "PARTITION", "ACTIVE", "SAMPLERBUFFER", "FILTER", - "IMAGE1D", "IMAGE2D", "IMAGE3D", "IMAGECUBE", "IMAGE1DARRAY", - "IMAGE2DARRAY", "IIMAGE1D", "IIMAGE2D", "IIMAGE3D", "IIMAGECUBE", - "IIMAGE1DARRAY", "IIMAGE2DARRAY", "UIMAGE1D", "UIMAGE2D", "UIMAGE3D", - "UIMAGECUBE", "UIMAGE1DARRAY", "UIMAGE2DARRAY", "IMAGE1DSHADOW", - "IMAGE2DSHADOW", "IMAGEBUFFER", "IIMAGEBUFFER", "UIMAGEBUFFER", - "ROW_MAJOR", "'('", "')'", "'['", "']'", "'.'", "','", "'+'", "'-'", - "'!'", "'~'", "'*'", "'/'", "'%'", "'<'", "'>'", "'&'", "'^'", "'|'", - "'?'", "':'", "'='", "';'", "'{'", "'}'", "$accept", "translation_unit", - "$@1", "version_statement", "pragma_statement", - "extension_statement_list", "extension_statement", - "external_declaration_list", "variable_identifier", "primary_expression", - "postfix_expression", "integer_expression", "function_call", - "function_call_or_method", "function_call_generic", - "function_call_header_no_parameters", - "function_call_header_with_parameters", "function_call_header", - "function_identifier", "unary_expression", "unary_operator", - "multiplicative_expression", "additive_expression", "shift_expression", - "relational_expression", "equality_expression", "and_expression", - "exclusive_or_expression", "inclusive_or_expression", - "logical_and_expression", "logical_xor_expression", - "logical_or_expression", "conditional_expression", - "assignment_expression", "assignment_operator", "expression", - "constant_expression", "declaration", "function_prototype", - "function_declarator", "function_header_with_parameters", - "function_header", "parameter_declarator", "parameter_declaration", - "parameter_qualifier", "parameter_type_specifier", - "init_declarator_list", "single_declaration", "fully_specified_type", - "opt_layout_qualifier", "layout_qualifier", "layout_qualifier_id_list", - "layout_qualifier_id", "interpolation_qualifier", - "parameter_type_qualifier", "type_qualifier", "storage_qualifier", - "type_specifier", "type_specifier_no_prec", "type_specifier_nonarray", - "basic_type_specifier_nonarray", "precision_qualifier", - "struct_specifier", "struct_declaration_list", "struct_declaration", - "struct_declarator_list", "struct_declarator", "initializer", - "declaration_statement", "statement", "simple_statement", - "compound_statement", "statement_no_new_scope", - "compound_statement_no_new_scope", "statement_list", - "expression_statement", "selection_statement", - "selection_rest_statement", "condition", "switch_statement", - "case_label", "iteration_statement", "for_init_statement", - "conditionopt", "for_rest_statement", "jump_statement", - "external_declaration", "function_definition", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 40, 41, 91, 93, 46, 44, 43, 45, 33, - 126, 42, 47, 37, 60, 62, 38, 94, 124, 63, - 58, 61, 59, 123, 125 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 215, 217, 216, 218, 218, 219, 219, 219, 219, - 220, 220, 221, 222, 222, 223, 224, 224, 224, 224, - 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, - 228, 228, 229, 229, 230, 230, 231, 231, 232, 233, - 233, 233, 234, 234, 234, 234, 235, 235, 235, 235, - 236, 236, 236, 236, 237, 237, 237, 238, 238, 238, - 239, 239, 239, 239, 239, 240, 240, 240, 241, 241, - 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, - 247, 247, 248, 248, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 250, 250, 251, 252, 252, - 252, 253, 254, 254, 255, 255, 256, 257, 257, 258, - 258, 258, 258, 259, 259, 259, 259, 260, 261, 261, - 261, 261, 261, 261, 261, 262, 262, 262, 262, 262, - 262, 262, 262, 263, 263, 264, 264, 265, 266, 266, - 267, 268, 268, 268, 269, 270, 270, 270, 271, 271, - 271, 271, 271, 271, 271, 271, 271, 272, 272, 273, - 273, 273, 274, 274, 274, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 276, 276, 276, 277, - 277, 278, 278, 279, 280, 280, 281, 281, 282, 283, - 284, 284, 285, 285, 285, 285, 285, 285, 285, 286, - 286, 287, 287, 288, 288, 289, 289, 290, 290, 291, - 292, 292, 293, 293, 294, 295, 295, 296, 296, 296, - 297, 297, 298, 298, 299, 299, 300, 300, 300, 300, - 300, 301, 301, 301, 302 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 0, 4, 0, 3, 2, 2, 2, 2, - 0, 2, 5, 1, 2, 1, 1, 1, 1, 1, - 1, 3, 1, 4, 1, 3, 2, 2, 1, 1, - 1, 3, 2, 2, 2, 1, 2, 3, 2, 1, - 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, - 1, 3, 3, 3, 1, 3, 3, 1, 3, 3, - 1, 3, 3, 3, 3, 1, 3, 3, 1, 3, - 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, - 1, 5, 1, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, 2, 2, - 4, 2, 1, 1, 2, 3, 3, 2, 5, 3, - 2, 3, 2, 0, 1, 1, 1, 1, 1, 3, - 5, 6, 7, 8, 5, 1, 2, 4, 5, 6, - 7, 4, 2, 1, 2, 0, 1, 4, 1, 3, - 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, - 2, 2, 2, 1, 2, 2, 1, 1, 2, 1, - 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, - 4, 1, 2, 3, 1, 3, 1, 4, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 3, 1, 1, 2, 3, 1, 2, 1, 2, 5, - 3, 1, 1, 4, 5, 3, 2, 5, 7, 6, - 1, 1, 1, 0, 2, 3, 2, 2, 2, 3, - 2, 1, 1, 1, 2 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint16 yydefact[] = -{ - 4, 0, 0, 10, 0, 1, 2, 5, 0, 135, - 11, 0, 149, 148, 169, 166, 167, 168, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 170, 171, 172, - 0, 153, 156, 143, 142, 141, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 194, 195, 196, - 197, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 0, 165, - 164, 135, 218, 217, 216, 0, 0, 0, 0, 0, - 0, 193, 198, 273, 135, 272, 0, 0, 103, 113, - 0, 118, 125, 0, 136, 135, 0, 145, 133, 157, - 159, 162, 0, 163, 13, 271, 0, 154, 155, 151, - 0, 0, 132, 135, 147, 0, 6, 7, 8, 9, - 0, 14, 98, 135, 274, 101, 113, 144, 114, 115, - 116, 104, 0, 113, 0, 99, 126, 152, 150, 146, - 134, 0, 158, 0, 0, 0, 0, 221, 0, 140, - 0, 138, 0, 0, 135, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 19, 17, 18, 20, 41, 0, - 0, 0, 46, 47, 48, 49, 247, 135, 243, 16, - 22, 42, 24, 29, 30, 0, 0, 35, 0, 50, - 0, 54, 57, 60, 65, 68, 70, 72, 74, 76, - 78, 80, 82, 95, 0, 229, 0, 133, 232, 245, - 231, 230, 135, 233, 234, 235, 236, 237, 238, 105, - 110, 112, 117, 0, 119, 106, 0, 0, 160, 50, - 97, 0, 39, 12, 0, 226, 0, 224, 220, 222, - 100, 137, 0, 267, 266, 0, 135, 0, 270, 268, - 0, 0, 0, 256, 135, 43, 44, 0, 239, 135, - 26, 27, 0, 0, 33, 32, 0, 165, 36, 38, - 85, 86, 88, 87, 90, 91, 92, 93, 94, 89, - 84, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 248, 244, 246, 107, 109, 111, - 0, 0, 127, 0, 228, 131, 161, 219, 0, 0, - 223, 139, 0, 261, 260, 135, 0, 269, 0, 255, - 252, 0, 0, 21, 240, 0, 28, 25, 31, 37, - 83, 51, 52, 53, 55, 56, 58, 59, 63, 64, - 61, 62, 66, 67, 69, 71, 73, 75, 77, 79, - 0, 96, 0, 120, 0, 124, 0, 128, 0, 225, - 0, 262, 0, 0, 135, 0, 0, 135, 23, 0, - 0, 0, 121, 129, 0, 227, 0, 264, 135, 251, - 249, 254, 0, 242, 257, 241, 81, 108, 122, 0, - 130, 0, 265, 259, 135, 253, 123, 258, 250 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 2, 9, 3, 83, 6, 10, 84, 179, 180, - 181, 335, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 281, 204, 231, 205, 206, 87, - 88, 89, 220, 131, 132, 221, 90, 91, 92, 93, - 94, 150, 151, 95, 133, 96, 97, 232, 99, 100, - 101, 102, 103, 146, 147, 236, 237, 315, 208, 209, - 210, 211, 394, 395, 212, 213, 214, 390, 332, 215, - 216, 217, 325, 372, 373, 218, 104, 105 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -329 -static const yytype_int16 yypact[] = -{ - -58, -22, 72, -329, -28, -329, -15, -329, 22, 3589, - -329, -4, -329, -329, -329, -329, -329, -329, -329, -329, - -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, - 44, -329, -329, -329, -329, -329, -329, -329, -329, -329, - -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, - -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, - -329, -329, -329, -329, -329, -329, -329, -329, -72, -329, - -329, 6, -329, -329, -329, 14, -8, 9, 11, 26, - -64, -329, -329, -329, 3470, -329, -159, -23, -12, -2, - -149, -329, 105, 57, -329, 140, 3777, -329, -329, -329, - 15, -329, 3849, -329, -329, -329, 131, -329, -329, -329, - -3, 3777, -329, 140, -329, 3849, -329, -329, -329, -329, - 133, -329, -329, 383, -329, -329, 32, -329, -329, -329, - -329, -329, 3777, 158, 135, -329, -150, -329, -329, -329, - -329, 2565, -329, 100, 3777, 141, 1954, -329, 4, -329, - -95, -329, 7, 8, 1231, 27, 31, 12, 2186, 37, - 3108, 13, 39, -59, -329, -329, -329, -329, -329, 3108, - 3108, 3108, -329, -329, -329, -329, -329, 595, -329, -329, - -329, -55, -329, -329, -329, 41, -92, 3289, 40, -75, - 3108, -7, -118, 51, -74, 109, 28, 29, 30, 145, - 147, -84, -329, -329, -148, -329, 34, 49, -329, -329, - -329, -329, 807, -329, -329, -329, -329, -329, -329, -329, - -329, -329, 166, 3777, -143, -329, 2746, 3108, -329, -329, - -329, 53, -329, -329, 2070, 55, -139, -329, -329, -329, - -329, -329, 133, -329, -329, 174, 1640, 3108, -329, -329, - -138, 3108, -134, -329, 2384, -329, -329, -81, -329, 1019, - -329, -329, 3108, 3705, -329, -329, 3108, 61, -329, -329, - -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, - -329, 3108, -329, 3108, 3108, 3108, 3108, 3108, 3108, 3108, - 3108, 3108, 3108, 3108, 3108, 3108, 3108, 3108, 3108, 3108, - 3108, 3108, 3108, 3108, -329, -329, -329, 62, -329, -329, - 2927, 3108, 43, 63, -329, -329, -329, -329, 3108, 141, - -329, -329, 65, -329, -329, 1838, -80, -329, -79, -329, - 66, 182, 69, -329, -329, 70, 66, 74, -329, -329, - -329, -329, -329, -329, -7, -7, -118, -118, 51, 51, - 51, 51, -74, -74, 109, 28, 29, 30, 145, 147, - -127, -329, 3108, 52, 75, -329, 3108, 59, 77, -329, - 3108, -329, 54, 76, 1231, 60, 64, 1442, -329, 3108, - 78, 3108, 67, -329, 3108, -329, -50, 3108, 1442, 262, - -329, -329, 3108, -329, -329, -329, -329, -329, -329, 3108, - -329, 71, 66, -329, 1231, -329, -329, -329, -329 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -329, -329, -329, -329, -329, -329, -329, -329, -329, -329, - -329, -329, -329, -329, 16, -329, -329, -329, -329, -135, - -329, -87, -83, -104, -93, -20, -16, -21, -13, -11, - -17, -329, -133, -99, -329, -155, -189, 2, 5, -329, - -329, -329, 68, 161, 155, 73, -329, -329, -215, -329, - -329, -329, 48, -329, -329, -43, -329, -9, -31, -329, - -329, 217, -329, 150, -131, -329, -24, -140, 56, -153, - -328, -78, -90, 213, 124, 58, -329, -329, -19, -329, - -329, -329, -329, -329, -329, -329, 219, -329 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -264 -static const yytype_int16 yytable[] = -{ - 98, 245, 127, 250, 110, 252, 229, 301, 230, 12, - 13, 85, 290, 291, 86, 239, 257, -164, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 114, 260, - 261, 128, 129, 130, 255, 256, 127, 313, 30, 331, - 31, 225, 32, 226, 33, 34, 35, 134, 303, 393, - 310, 1, 139, 122, 123, 282, 4, 319, 303, 306, - 393, 227, 303, 135, 304, 128, 129, 130, 311, 303, - 114, 142, 5, 320, 327, 98, 329, 107, 108, 286, - 287, 109, 112, 379, 148, 7, 85, 140, 268, 86, - 137, 229, 326, 230, 138, 8, 328, 241, 11, 330, - 265, 242, 145, 239, 266, 116, 306, 336, 106, 113, - 331, 333, 374, 375, 207, 303, 303, 303, 72, 73, - 74, 364, 117, 222, 118, 302, 80, 120, 314, 368, - 292, 293, -40, 288, 289, 145, 280, 145, 262, 119, - 263, 111, 401, 12, 13, 207, 303, 360, 341, 342, - 343, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 339, 207, 125, - 330, 365, 30, 380, 31, 229, 32, 230, 33, 34, - 35, 136, 340, 229, 126, 230, 348, 349, 350, 351, - -102, 128, 129, 130, 283, 284, 285, 294, 295, 344, - 345, 352, 353, 207, 361, 346, 347, 143, 141, 149, - 144, 224, 314, 233, 222, 386, 240, 235, 246, 243, - 244, 389, 247, 253, 248, 145, 383, 229, 251, 230, - 254, 269, 402, 264, 296, 299, 297, 207, 298, 300, - -39, 398, 307, 113, 400, 207, 122, 316, 318, 322, - 207, 408, 405, -34, 366, 362, 370, 367, 376, 406, - 80, 377, 303, 381, 378, -40, 387, 314, 388, 382, - 384, 385, 397, 177, 404, 392, 354, 356, 399, 338, - 396, 355, 314, 407, 359, 314, 357, 219, 223, 358, - 321, 308, 115, 314, 234, 369, 309, 391, 403, 124, - 314, 259, 323, 121, 324, 0, 371, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 207, 0, 0, 207, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, - 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, - 16, 17, 152, 153, 154, 207, 155, 156, 157, 158, - 159, 160, 161, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 0, 31, 0, 32, - 0, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 162, 163, - 164, 165, 166, 167, 168, 0, 0, 169, 170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, - 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 81, 0, 82, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, - 172, 173, 174, 175, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 176, 177, 178, 12, 13, - 14, 15, 16, 17, 152, 153, 154, 0, 155, 156, - 157, 158, 159, 160, 161, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 0, 31, - 0, 32, 0, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 162, 163, 164, 165, 166, 167, 168, 0, 0, 169, - 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, - 73, 74, 0, 75, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, - 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, - 0, 0, 172, 173, 174, 175, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 176, 177, 258, - 12, 13, 14, 15, 16, 17, 152, 153, 154, 0, - 155, 156, 157, 158, 159, 160, 161, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 0, 31, 0, 32, 0, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 162, 163, 164, 165, 166, 167, 168, 0, - 0, 169, 170, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 71, 72, 73, 74, 0, 75, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 81, 0, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 171, 0, - 0, 0, 0, 0, 172, 173, 174, 175, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, - 177, 305, 12, 13, 14, 15, 16, 17, 152, 153, - 154, 0, 155, 156, 157, 158, 159, 160, 161, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 0, 31, 0, 32, 0, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 162, 163, 164, 165, 166, 167, - 168, 0, 0, 169, 170, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 71, 72, 73, 74, 0, 75, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 81, 0, 82, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 171, 0, 0, 0, 0, 0, 172, 173, 174, 175, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 176, 177, 334, 12, 13, 14, 15, 16, 17, - 152, 153, 154, 0, 155, 156, 157, 158, 159, 160, - 161, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 0, 31, 0, 32, 0, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 162, 163, 164, 165, - 166, 167, 168, 0, 0, 169, 170, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 71, 72, 73, 74, 0, 75, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 81, 0, 82, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 171, 0, 0, 0, 0, 0, 172, 173, - 174, 175, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 176, 177, 12, 13, 14, 15, 16, - 17, 152, 153, 154, 0, 155, 156, 157, 158, 159, - 160, 161, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 0, 31, 0, 32, 0, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 162, 163, 164, - 165, 166, 167, 168, 0, 0, 169, 170, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 71, 72, 73, 74, 0, - 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 81, 0, 82, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 171, 0, 0, 0, 0, 0, 172, - 173, 174, 175, 12, 13, 14, 15, 16, 17, 0, - 0, 0, 0, 0, 176, 123, 0, 0, 0, 0, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 0, 31, 0, 32, 0, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 0, 163, 164, 165, 166, - 167, 168, 0, 0, 169, 170, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 71, 72, 73, 74, 0, 75, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 81, 0, 82, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 171, 0, 0, 0, 0, 0, 172, 173, 174, - 175, 12, 13, 14, 15, 16, 17, 0, 0, 0, - 0, 0, 176, 0, 0, 0, 0, 0, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 0, 31, 0, 32, 0, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 0, 163, 164, 165, 166, 167, 168, - 0, 0, 169, 170, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 113, 72, 73, 74, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 80, 14, - 15, 16, 17, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, - 0, 0, 81, 0, 82, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 171, - 70, 0, 0, 0, 0, 172, 173, 174, 175, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -263, 0, 0, 0, 0, 0, 0, 0, 72, 73, - 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 14, 15, 16, 17, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 0, 0, 0, 0, 0, 0, 81, 0, - 82, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 0, 70, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, - 0, 0, 0, 0, 72, 73, 74, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 14, 15, 16, 17, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, - 0, 0, 0, 0, 81, 0, 82, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 0, 163, 164, 165, 166, 167, 168, 0, 0, - 169, 170, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 317, 0, 0, 0, 0, 0, - 72, 73, 74, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 81, 0, 82, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 171, 0, 0, - 0, 0, 0, 172, 173, 174, 175, 12, 13, 14, - 15, 16, 17, 0, 0, 0, 0, 0, 249, 0, - 0, 0, 0, 0, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 0, 31, 0, - 32, 0, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, - 163, 164, 165, 166, 167, 168, 0, 0, 169, 170, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 113, 72, 73, - 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, - 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 14, 15, 16, 17, 0, 171, 0, 0, 0, 0, - 0, 172, 173, 174, 175, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 0, 163, 164, 165, 166, 167, 168, 0, 0, 169, - 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, - 73, 74, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, - 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 14, 15, 16, 17, 0, 171, 0, 0, 228, - 0, 0, 172, 173, 174, 175, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 0, 163, 164, 165, 166, 167, 168, 0, 0, - 169, 170, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 73, 74, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 81, 0, 82, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 14, 15, 16, 17, 0, 171, 0, 0, - 312, 0, 0, 172, 173, 174, 175, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 0, 163, 164, 165, 166, 167, 168, 0, - 0, 169, 170, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 72, 73, 74, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 81, 0, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 14, 15, 16, 17, 0, 171, 0, - 0, 363, 0, 0, 172, 173, 174, 175, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 0, 163, 164, 165, 166, 167, 168, - 0, 0, 169, 170, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 72, 73, 74, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 81, 0, 82, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 14, 15, 16, 17, 0, 171, - 0, 0, 0, 0, 0, 172, 173, 174, 175, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 267, 0, 163, 164, 165, 166, 167, - 168, 0, 0, 169, 170, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 72, 73, 74, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 81, 0, 82, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -3, 0, 0, 12, 13, 14, 15, 16, 17, 0, - 171, 0, 0, 0, 0, 0, 172, 173, 174, 175, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 0, 31, 0, 32, 0, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 0, 70, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 71, 72, 73, 74, 0, 75, 0, - 0, 0, 0, 0, 0, 0, 76, 77, 78, 79, - 80, 0, 12, 13, 14, 15, 16, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 0, 31, 81, 32, 82, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 0, 70, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 71, 72, 73, 74, 0, 75, 0, 0, - 0, 0, 0, 0, 0, 76, 77, 78, 79, 80, - 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, - 0, 0, 0, 81, 0, 82, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 0, 337, 14, 15, 16, 17, 168, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 72, - 73, 74, 0, 0, 0, 0, 0, 0, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 0, 70, 14, 15, 16, 17, 0, 81, - 0, 82, 0, 0, 0, 0, 0, 0, 0, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 72, 73, 74, 0, 0, 0, 0, 0, 0, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 0, 70, 0, 0, 0, 0, - 0, 81, 0, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 81, 0, 82 -}; - -static const yytype_int16 yycheck[] = -{ - 9, 154, 4, 158, 76, 160, 141, 91, 141, 3, - 4, 9, 86, 87, 9, 146, 171, 76, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 71, 84, - 85, 33, 34, 35, 169, 170, 4, 226, 32, 254, - 34, 191, 36, 193, 38, 39, 40, 196, 196, 377, - 193, 109, 95, 212, 213, 190, 78, 196, 196, 212, - 388, 211, 196, 212, 212, 33, 34, 35, 211, 196, - 113, 102, 0, 212, 212, 84, 210, 33, 34, 197, - 198, 37, 76, 210, 115, 113, 84, 96, 187, 84, - 33, 226, 247, 226, 37, 110, 251, 192, 76, 254, - 192, 196, 111, 234, 196, 113, 259, 262, 112, 103, - 325, 192, 192, 192, 123, 196, 196, 196, 104, 105, - 106, 310, 113, 132, 113, 209, 120, 191, 227, 318, - 204, 205, 191, 82, 83, 144, 211, 146, 193, 113, - 195, 213, 192, 3, 4, 154, 196, 302, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 266, 177, 192, - 325, 311, 32, 362, 34, 310, 36, 310, 38, 39, - 40, 76, 281, 318, 196, 318, 290, 291, 292, 293, - 192, 33, 34, 35, 201, 202, 203, 88, 89, 286, - 287, 294, 295, 212, 303, 288, 289, 76, 193, 76, - 213, 76, 311, 113, 223, 370, 212, 76, 191, 212, - 212, 374, 191, 210, 212, 234, 366, 362, 191, 362, - 191, 191, 387, 192, 206, 90, 207, 246, 208, 92, - 191, 381, 76, 103, 384, 254, 212, 194, 193, 75, - 259, 404, 392, 192, 211, 193, 191, 194, 76, 399, - 120, 192, 196, 211, 194, 191, 212, 366, 192, 194, - 211, 194, 194, 213, 12, 211, 296, 298, 211, 263, - 379, 297, 381, 212, 301, 384, 299, 126, 133, 300, - 242, 223, 75, 392, 144, 319, 223, 375, 388, 86, - 399, 177, 246, 84, 246, -1, 325, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 325, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 374, -1, -1, 377, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 388, - -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 404, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, -1, 34, -1, 36, - -1, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, -1, -1, 84, 85, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - -1, 108, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 120, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 154, -1, 156, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 191, -1, -1, -1, -1, -1, - 197, 198, 199, 200, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 212, 213, 214, 3, 4, - 5, 6, 7, 8, 9, 10, 11, -1, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, -1, 34, - -1, 36, -1, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, -1, -1, 84, - 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, -1, 108, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 154, - -1, 156, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 191, -1, -1, -1, - -1, -1, 197, 198, 199, 200, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 212, 213, 214, - 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - -1, 34, -1, 36, -1, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, -1, - -1, 84, 85, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, -1, 108, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 154, -1, 156, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 191, -1, - -1, -1, -1, -1, 197, 198, 199, 200, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 212, - 213, 214, 3, 4, 5, 6, 7, 8, 9, 10, - 11, -1, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, -1, 34, -1, 36, -1, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 154, -1, 156, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 191, -1, -1, -1, -1, -1, 197, 198, 199, 200, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 212, 213, 214, 3, 4, 5, 6, 7, 8, - 9, 10, 11, -1, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, -1, 34, -1, 36, -1, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, -1, -1, 84, 85, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, -1, 108, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 120, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 154, -1, 156, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 191, -1, -1, -1, -1, -1, 197, 198, - 199, 200, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 212, 213, 3, 4, 5, 6, 7, - 8, 9, 10, 11, -1, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, -1, 34, -1, 36, -1, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, -1, -1, 84, 85, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 103, 104, 105, 106, -1, - 108, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 120, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 154, -1, 156, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 191, -1, -1, -1, -1, -1, 197, - 198, 199, 200, 3, 4, 5, 6, 7, 8, -1, - -1, -1, -1, -1, 212, 213, -1, -1, -1, -1, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, -1, 34, -1, 36, -1, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, -1, 76, 77, 78, 79, - 80, 81, -1, -1, 84, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 103, 104, 105, 106, -1, 108, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 120, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 154, -1, 156, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 191, -1, -1, -1, -1, -1, 197, 198, 199, - 200, 3, 4, 5, 6, 7, 8, -1, -1, -1, - -1, -1, 212, -1, -1, -1, -1, -1, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, -1, 34, -1, 36, -1, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, - -1, -1, 84, 85, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 103, 104, 105, 106, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 120, 5, - 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, - -1, -1, 154, -1, 156, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 191, - 76, -1, -1, -1, -1, 197, 198, 199, 200, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 212, -1, -1, -1, -1, -1, -1, -1, 104, 105, - 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 5, 6, 7, 8, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, -1, -1, -1, -1, -1, -1, 154, -1, - 156, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, -1, 76, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 214, -1, - -1, -1, -1, -1, 104, 105, 106, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 5, 6, 7, 8, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, - -1, -1, -1, -1, 154, -1, 156, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, -1, 76, 77, 78, 79, 80, 81, -1, -1, - 84, 85, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 214, -1, -1, -1, -1, -1, - 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 154, -1, 156, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 191, -1, -1, - -1, -1, -1, 197, 198, 199, 200, 3, 4, 5, - 6, 7, 8, -1, -1, -1, -1, -1, 212, -1, - -1, -1, -1, -1, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, -1, 34, -1, - 36, -1, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, -1, - 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, - 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 120, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 154, -1, - 156, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 5, 6, 7, 8, -1, 191, -1, -1, -1, -1, - -1, 197, 198, 199, 200, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - -1, 76, 77, 78, 79, 80, 81, -1, -1, 84, - 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, - 105, 106, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 154, - -1, 156, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 5, 6, 7, 8, -1, 191, -1, -1, 194, - -1, -1, 197, 198, 199, 200, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, -1, 76, 77, 78, 79, 80, 81, -1, -1, - 84, 85, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 154, -1, 156, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 5, 6, 7, 8, -1, 191, -1, -1, - 194, -1, -1, 197, 198, 199, 200, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, -1, 76, 77, 78, 79, 80, 81, -1, - -1, 84, 85, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 104, 105, 106, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 154, -1, 156, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 5, 6, 7, 8, -1, 191, -1, - -1, 194, -1, -1, 197, 198, 199, 200, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, - -1, -1, 84, 85, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 104, 105, 106, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 154, -1, 156, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 5, 6, 7, 8, -1, 191, - -1, -1, -1, -1, -1, 197, 198, 199, 200, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, -1, 76, 77, 78, 79, 80, - 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 104, 105, 106, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 154, -1, 156, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 0, -1, -1, 3, 4, 5, 6, 7, 8, -1, - 191, -1, -1, -1, -1, -1, 197, 198, 199, 200, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, -1, 34, -1, 36, -1, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, -1, 76, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 103, 104, 105, 106, -1, 108, -1, - -1, -1, -1, -1, -1, -1, 116, 117, 118, 119, - 120, -1, 3, 4, 5, 6, 7, 8, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, -1, 34, 154, 36, 156, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, -1, 76, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, - -1, -1, -1, -1, -1, 116, 117, 118, 119, 120, - 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, - -1, -1, -1, 154, -1, 156, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - -1, 76, 5, 6, 7, 8, 81, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 104, - 105, 106, -1, -1, -1, -1, -1, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, -1, 76, 5, 6, 7, 8, -1, 154, - -1, 156, -1, -1, -1, -1, -1, -1, -1, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 104, 105, 106, -1, -1, -1, -1, -1, -1, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, -1, 76, -1, -1, -1, -1, - -1, 154, -1, 156, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 154, -1, 156 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 109, 216, 218, 78, 0, 220, 113, 110, 217, - 221, 76, 3, 4, 5, 6, 7, 8, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 34, 36, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 76, 103, 104, 105, 106, 108, 116, 117, 118, 119, - 120, 154, 156, 219, 222, 252, 253, 254, 255, 256, - 261, 262, 263, 264, 265, 268, 270, 271, 272, 273, - 274, 275, 276, 277, 301, 302, 112, 33, 34, 37, - 76, 213, 76, 103, 270, 276, 113, 113, 113, 113, - 191, 301, 212, 213, 288, 192, 196, 4, 33, 34, - 35, 258, 259, 269, 196, 212, 76, 33, 37, 270, - 272, 193, 273, 76, 213, 272, 278, 279, 273, 76, - 266, 267, 9, 10, 11, 13, 14, 15, 16, 17, - 18, 19, 75, 76, 77, 78, 79, 80, 81, 84, - 85, 191, 197, 198, 199, 200, 212, 213, 214, 223, - 224, 225, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 250, 252, 253, 272, 283, 284, - 285, 286, 289, 290, 291, 294, 295, 296, 300, 258, - 257, 260, 272, 259, 76, 191, 193, 211, 194, 234, - 247, 251, 272, 113, 278, 76, 280, 281, 214, 279, - 212, 192, 196, 212, 212, 284, 191, 191, 212, 212, - 250, 191, 250, 210, 191, 234, 234, 250, 214, 289, - 84, 85, 193, 195, 192, 192, 196, 74, 248, 191, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 211, 249, 234, 201, 202, 203, 197, 198, 82, 83, - 86, 87, 204, 205, 88, 89, 206, 207, 208, 90, - 92, 91, 209, 196, 212, 214, 284, 76, 257, 260, - 193, 211, 194, 251, 248, 282, 194, 214, 193, 196, - 212, 267, 75, 283, 290, 297, 250, 212, 250, 210, - 250, 263, 293, 192, 214, 226, 250, 76, 229, 248, - 248, 234, 234, 234, 236, 236, 237, 237, 238, 238, - 238, 238, 239, 239, 240, 241, 242, 243, 244, 245, - 250, 248, 193, 194, 251, 282, 211, 194, 251, 281, - 191, 293, 298, 299, 192, 192, 76, 192, 194, 210, - 251, 211, 194, 282, 211, 194, 250, 212, 192, 284, - 292, 286, 211, 285, 287, 288, 248, 194, 282, 211, - 282, 192, 250, 287, 12, 282, 282, 212, 284 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, scanner) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, state); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - struct _mesa_glsl_parse_state *state; -#endif -{ - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (state); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - struct _mesa_glsl_parse_state *state; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct _mesa_glsl_parse_state *state) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, state) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - struct _mesa_glsl_parse_state *state; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , state); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, state); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct _mesa_glsl_parse_state *state) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, state) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - struct _mesa_glsl_parse_state *state; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (state); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (struct _mesa_glsl_parse_state *state); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (struct _mesa_glsl_parse_state *state) -#else -int -yyparse (state) - struct _mesa_glsl_parse_state *state; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - yylsp = yyls; - -#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 1; -#endif - -/* User initialization code. */ - -/* Line 1251 of yacc.c */ -#line 41 "glsl_parser.ypp" -{ - yylloc.first_line = 1; - yylloc.first_column = 1; - yylloc.last_line = 1; - yylloc.last_column = 1; - yylloc.source = 0; -} - -/* Line 1251 of yacc.c */ -#line 2691 "glsl_parser.cpp" - yylsp[0] = yylloc; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: - -/* Line 1464 of yacc.c */ -#line 214 "glsl_parser.ypp" - { - _mesa_glsl_initialize_types(state); - ;} - break; - - case 5: - -/* Line 1464 of yacc.c */ -#line 223 "glsl_parser.ypp" - { - switch ((yyvsp[(2) - (3)].n)) { - case 100: - state->es_shader = true; - case 110: - case 120: - case 130: - /* FINISHME: Check against implementation support versions. */ - state->language_version = (yyvsp[(2) - (3)].n); - break; - default: - _mesa_glsl_error(& (yylsp[(2) - (3)]), state, "Shading language version" - "%u is not supported\n", (yyvsp[(2) - (3)].n)); - break; - } - ;} - break; - - case 12: - -/* Line 1464 of yacc.c */ -#line 255 "glsl_parser.ypp" - { - if (!_mesa_glsl_process_extension((yyvsp[(2) - (5)].identifier), & (yylsp[(2) - (5)]), (yyvsp[(4) - (5)].identifier), & (yylsp[(4) - (5)]), state)) { - YYERROR; - } - ;} - break; - - case 13: - -/* Line 1464 of yacc.c */ -#line 264 "glsl_parser.ypp" - { - /* FINISHME: The NULL test is only required because 'precision' - * FINISHME: statements are not yet supported. - */ - if ((yyvsp[(1) - (1)].node) != NULL) - state->translation_unit.push_tail(& (yyvsp[(1) - (1)].node)->link); - ;} - break; - - case 14: - -/* Line 1464 of yacc.c */ -#line 272 "glsl_parser.ypp" - { - /* FINISHME: The NULL test is only required because 'precision' - * FINISHME: statements are not yet supported. - */ - if ((yyvsp[(2) - (2)].node) != NULL) - state->translation_unit.push_tail(& (yyvsp[(2) - (2)].node)->link); - ;} - break; - - case 16: - -/* Line 1464 of yacc.c */ -#line 287 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.identifier = (yyvsp[(1) - (1)].identifier); - ;} - break; - - case 17: - -/* Line 1464 of yacc.c */ -#line 294 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.int_constant = (yyvsp[(1) - (1)].n); - ;} - break; - - case 18: - -/* Line 1464 of yacc.c */ -#line 301 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.uint_constant = (yyvsp[(1) - (1)].n); - ;} - break; - - case 19: - -/* Line 1464 of yacc.c */ -#line 308 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.float_constant = (yyvsp[(1) - (1)].real); - ;} - break; - - case 20: - -/* Line 1464 of yacc.c */ -#line 315 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.bool_constant = (yyvsp[(1) - (1)].n); - ;} - break; - - case 21: - -/* Line 1464 of yacc.c */ -#line 322 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(2) - (3)].expression); - ;} - break; - - case 23: - -/* Line 1464 of yacc.c */ -#line 330 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_array_index, (yyvsp[(1) - (4)].expression), (yyvsp[(3) - (4)].expression), NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 24: - -/* Line 1464 of yacc.c */ -#line 336 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (1)].expression); - ;} - break; - - case 25: - -/* Line 1464 of yacc.c */ -#line 340 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.identifier = (yyvsp[(3) - (3)].identifier); - ;} - break; - - case 26: - -/* Line 1464 of yacc.c */ -#line 347 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_post_inc, (yyvsp[(1) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 27: - -/* Line 1464 of yacc.c */ -#line 353 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_post_dec, (yyvsp[(1) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 31: - -/* Line 1464 of yacc.c */ -#line 371 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 36: - -/* Line 1464 of yacc.c */ -#line 390 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (2)].expression); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->expressions.push_tail(& (yyvsp[(2) - (2)].expression)->link); - ;} - break; - - case 37: - -/* Line 1464 of yacc.c */ -#line 396 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (3)].expression); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); - ;} - break; - - case 39: - -/* Line 1464 of yacc.c */ -#line 412 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_function_expression((yyvsp[(1) - (1)].type_specifier)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 40: - -/* Line 1464 of yacc.c */ -#line 418 "glsl_parser.ypp" - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); - (yyval.expression) = new(ctx) ast_function_expression(callee); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 41: - -/* Line 1464 of yacc.c */ -#line 425 "glsl_parser.ypp" - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); - (yyval.expression) = new(ctx) ast_function_expression(callee); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 43: - -/* Line 1464 of yacc.c */ -#line 437 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_pre_inc, (yyvsp[(2) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 44: - -/* Line 1464 of yacc.c */ -#line 443 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_pre_dec, (yyvsp[(2) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 45: - -/* Line 1464 of yacc.c */ -#line 449 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 46: - -/* Line 1464 of yacc.c */ -#line 458 "glsl_parser.ypp" - { (yyval.n) = ast_plus; ;} - break; - - case 47: - -/* Line 1464 of yacc.c */ -#line 459 "glsl_parser.ypp" - { (yyval.n) = ast_neg; ;} - break; - - case 48: - -/* Line 1464 of yacc.c */ -#line 460 "glsl_parser.ypp" - { (yyval.n) = ast_logic_not; ;} - break; - - case 49: - -/* Line 1464 of yacc.c */ -#line 461 "glsl_parser.ypp" - { (yyval.n) = ast_bit_not; ;} - break; - - case 51: - -/* Line 1464 of yacc.c */ -#line 467 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_mul, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 52: - -/* Line 1464 of yacc.c */ -#line 473 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_div, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 53: - -/* Line 1464 of yacc.c */ -#line 479 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_mod, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 55: - -/* Line 1464 of yacc.c */ -#line 489 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_add, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 56: - -/* Line 1464 of yacc.c */ -#line 495 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_sub, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 58: - -/* Line 1464 of yacc.c */ -#line 505 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_lshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 59: - -/* Line 1464 of yacc.c */ -#line 511 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_rshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 61: - -/* Line 1464 of yacc.c */ -#line 521 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_less, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 62: - -/* Line 1464 of yacc.c */ -#line 527 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_greater, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 63: - -/* Line 1464 of yacc.c */ -#line 533 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_lequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 64: - -/* Line 1464 of yacc.c */ -#line 539 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_gequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 66: - -/* Line 1464 of yacc.c */ -#line 549 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_equal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 67: - -/* Line 1464 of yacc.c */ -#line 555 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_nequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 69: - -/* Line 1464 of yacc.c */ -#line 565 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 71: - -/* Line 1464 of yacc.c */ -#line 575 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 73: - -/* Line 1464 of yacc.c */ -#line 585 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 75: - -/* Line 1464 of yacc.c */ -#line 595 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 77: - -/* Line 1464 of yacc.c */ -#line 605 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 79: - -/* Line 1464 of yacc.c */ -#line 615 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 81: - -/* Line 1464 of yacc.c */ -#line 625 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_conditional, (yyvsp[(1) - (5)].expression), (yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 83: - -/* Line 1464 of yacc.c */ -#line 635 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression((yyvsp[(2) - (3)].n), (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 84: - -/* Line 1464 of yacc.c */ -#line 643 "glsl_parser.ypp" - { (yyval.n) = ast_assign; ;} - break; - - case 85: - -/* Line 1464 of yacc.c */ -#line 644 "glsl_parser.ypp" - { (yyval.n) = ast_mul_assign; ;} - break; - - case 86: - -/* Line 1464 of yacc.c */ -#line 645 "glsl_parser.ypp" - { (yyval.n) = ast_div_assign; ;} - break; - - case 87: - -/* Line 1464 of yacc.c */ -#line 646 "glsl_parser.ypp" - { (yyval.n) = ast_mod_assign; ;} - break; - - case 88: - -/* Line 1464 of yacc.c */ -#line 647 "glsl_parser.ypp" - { (yyval.n) = ast_add_assign; ;} - break; - - case 89: - -/* Line 1464 of yacc.c */ -#line 648 "glsl_parser.ypp" - { (yyval.n) = ast_sub_assign; ;} - break; - - case 90: - -/* Line 1464 of yacc.c */ -#line 649 "glsl_parser.ypp" - { (yyval.n) = ast_ls_assign; ;} - break; - - case 91: - -/* Line 1464 of yacc.c */ -#line 650 "glsl_parser.ypp" - { (yyval.n) = ast_rs_assign; ;} - break; - - case 92: - -/* Line 1464 of yacc.c */ -#line 651 "glsl_parser.ypp" - { (yyval.n) = ast_and_assign; ;} - break; - - case 93: - -/* Line 1464 of yacc.c */ -#line 652 "glsl_parser.ypp" - { (yyval.n) = ast_xor_assign; ;} - break; - - case 94: - -/* Line 1464 of yacc.c */ -#line 653 "glsl_parser.ypp" - { (yyval.n) = ast_or_assign; ;} - break; - - case 95: - -/* Line 1464 of yacc.c */ -#line 658 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (1)].expression); - ;} - break; - - case 96: - -/* Line 1464 of yacc.c */ -#line 662 "glsl_parser.ypp" - { - void *ctx = state; - if ((yyvsp[(1) - (3)].expression)->oper != ast_sequence) { - (yyval.expression) = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->expressions.push_tail(& (yyvsp[(1) - (3)].expression)->link); - } else { - (yyval.expression) = (yyvsp[(1) - (3)].expression); - } - - (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); - ;} - break; - - case 98: - -/* Line 1464 of yacc.c */ -#line 682 "glsl_parser.ypp" - { - (yyval.node) = (yyvsp[(1) - (2)].function); - ;} - break; - - case 99: - -/* Line 1464 of yacc.c */ -#line 686 "glsl_parser.ypp" - { - (yyval.node) = (yyvsp[(1) - (2)].declarator_list); - ;} - break; - - case 100: - -/* Line 1464 of yacc.c */ -#line 690 "glsl_parser.ypp" - { - if (((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_float) - && ((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_int)) { - _mesa_glsl_error(& (yylsp[(3) - (4)]), state, "global precision qualifier can " - "only be applied to `int' or `float'\n"); - YYERROR; - } - - (yyval.node) = NULL; /* FINISHME */ - ;} - break; - - case 104: - -/* Line 1464 of yacc.c */ -#line 713 "glsl_parser.ypp" - { - (yyval.function) = (yyvsp[(1) - (2)].function); - (yyval.function)->parameters.push_tail(& (yyvsp[(2) - (2)].parameter_declarator)->link); - ;} - break; - - case 105: - -/* Line 1464 of yacc.c */ -#line 718 "glsl_parser.ypp" - { - (yyval.function) = (yyvsp[(1) - (3)].function); - (yyval.function)->parameters.push_tail(& (yyvsp[(3) - (3)].parameter_declarator)->link); - ;} - break; - - case 106: - -/* Line 1464 of yacc.c */ -#line 726 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.function) = new(ctx) ast_function(); - (yyval.function)->set_location(yylloc); - (yyval.function)->return_type = (yyvsp[(1) - (3)].fully_specified_type); - (yyval.function)->identifier = (yyvsp[(2) - (3)].identifier); - ;} - break; - - case 107: - -/* Line 1464 of yacc.c */ -#line 737 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->set_location(yylloc); - (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (2)].type_specifier); - (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (2)].identifier); - ;} - break; - - case 108: - -/* Line 1464 of yacc.c */ -#line 747 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->set_location(yylloc); - (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (5)].type_specifier); - (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (5)].identifier); - (yyval.parameter_declarator)->is_array = true; - (yyval.parameter_declarator)->array_size = (yyvsp[(4) - (5)].expression); - ;} - break; - - case 109: - -/* Line 1464 of yacc.c */ -#line 762 "glsl_parser.ypp" - { - (yyvsp[(1) - (3)].type_qualifier).i |= (yyvsp[(2) - (3)].type_qualifier).i; - - (yyval.parameter_declarator) = (yyvsp[(3) - (3)].parameter_declarator); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier).q; - ;} - break; - - case 110: - -/* Line 1464 of yacc.c */ -#line 769 "glsl_parser.ypp" - { - (yyval.parameter_declarator) = (yyvsp[(2) - (2)].parameter_declarator); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier).q; - ;} - break; - - case 111: - -/* Line 1464 of yacc.c */ -#line 774 "glsl_parser.ypp" - { - void *ctx = state; - (yyvsp[(1) - (3)].type_qualifier).i |= (yyvsp[(2) - (3)].type_qualifier).i; - - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier).q; - (yyval.parameter_declarator)->type->specifier = (yyvsp[(3) - (3)].type_specifier); - ;} - break; - - case 112: - -/* Line 1464 of yacc.c */ -#line 785 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier).q; - (yyval.parameter_declarator)->type->specifier = (yyvsp[(2) - (2)].type_specifier); - ;} - break; - - case 113: - -/* Line 1464 of yacc.c */ -#line 796 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; ;} - break; - - case 114: - -/* Line 1464 of yacc.c */ -#line 797 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.in = 1; ;} - break; - - case 115: - -/* Line 1464 of yacc.c */ -#line 798 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.out = 1; ;} - break; - - case 116: - -/* Line 1464 of yacc.c */ -#line 799 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.in = 1; (yyval.type_qualifier).q.out = 1; ;} - break; - - case 119: - -/* Line 1464 of yacc.c */ -#line 809 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (3)].identifier), false, NULL, NULL); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (3)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 120: - -/* Line 1464 of yacc.c */ -#line 818 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), true, NULL, NULL); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 121: - -/* Line 1464 of yacc.c */ -#line 827 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (6)].identifier), true, (yyvsp[(5) - (6)].expression), NULL); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (6)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 122: - -/* Line 1464 of yacc.c */ -#line 836 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (7)].identifier), true, NULL, (yyvsp[(7) - (7)].expression)); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (7)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 123: - -/* Line 1464 of yacc.c */ -#line 845 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (8)].identifier), true, (yyvsp[(5) - (8)].expression), (yyvsp[(8) - (8)].expression)); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (8)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 124: - -/* Line 1464 of yacc.c */ -#line 854 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), false, NULL, (yyvsp[(5) - (5)].expression)); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 125: - -/* Line 1464 of yacc.c */ -#line 867 "glsl_parser.ypp" - { - void *ctx = state; - if ((yyvsp[(1) - (1)].fully_specified_type)->specifier->type_specifier != ast_struct) { - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "empty declaration list\n"); - YYERROR; - } else { - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (1)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - } - ;} - break; - - case 126: - -/* Line 1464 of yacc.c */ -#line 878 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (2)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 127: - -/* Line 1464 of yacc.c */ -#line 887 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), true, NULL, NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 128: - -/* Line 1464 of yacc.c */ -#line 896 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (5)].identifier), true, (yyvsp[(4) - (5)].expression), NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (5)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 129: - -/* Line 1464 of yacc.c */ -#line 905 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (6)].identifier), true, NULL, (yyvsp[(6) - (6)].expression)); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (6)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 130: - -/* Line 1464 of yacc.c */ -#line 914 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (7)].identifier), true, (yyvsp[(4) - (7)].expression), (yyvsp[(7) - (7)].expression)); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (7)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 131: - -/* Line 1464 of yacc.c */ -#line 923 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 132: - -/* Line 1464 of yacc.c */ -#line 932 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list(NULL); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->invariant = true; - - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 133: - -/* Line 1464 of yacc.c */ -#line 946 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); - (yyval.fully_specified_type)->set_location(yylloc); - (yyval.fully_specified_type)->specifier = (yyvsp[(1) - (1)].type_specifier); - ;} - break; - - case 134: - -/* Line 1464 of yacc.c */ -#line 953 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); - (yyval.fully_specified_type)->set_location(yylloc); - (yyval.fully_specified_type)->qualifier = (yyvsp[(1) - (2)].type_qualifier).q; - (yyval.fully_specified_type)->specifier = (yyvsp[(2) - (2)].type_specifier); - ;} - break; - - case 135: - -/* Line 1464 of yacc.c */ -#line 963 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; ;} - break; - - case 137: - -/* Line 1464 of yacc.c */ -#line 969 "glsl_parser.ypp" - { - (yyval.type_qualifier) = (yyvsp[(3) - (4)].type_qualifier); - ;} - break; - - case 139: - -/* Line 1464 of yacc.c */ -#line 977 "glsl_parser.ypp" - { - (yyval.type_qualifier).i = (yyvsp[(1) - (3)].type_qualifier).i | (yyvsp[(3) - (3)].type_qualifier).i; - ;} - break; - - case 140: - -/* Line 1464 of yacc.c */ -#line 984 "glsl_parser.ypp" - { - (yyval.type_qualifier).i = 0; - - if (state->ARB_fragment_coord_conventions_enable) { - bool got_one = false; - - if (strcmp((yyvsp[(1) - (1)].identifier), "origin_upper_left") == 0) { - got_one = true; - (yyval.type_qualifier).q.origin_upper_left = 1; - } else if (strcmp((yyvsp[(1) - (1)].identifier), "pixel_center_integer") == 0) { - got_one = true; - (yyval.type_qualifier).q.pixel_center_integer = 1; - } - - if (state->ARB_fragment_coord_conventions_warn && got_one) { - _mesa_glsl_warning(& (yylsp[(1) - (1)]), state, - "GL_ARB_fragment_coord_conventions layout " - "identifier `%s' used\n", (yyvsp[(1) - (1)].identifier)); - } - } - - /* If the identifier didn't match any known layout identifiers, - * emit an error. - */ - if ((yyval.type_qualifier).i == 0) { - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "unrecognized layout identifier " - "`%s'\n", (yyvsp[(1) - (1)].identifier)); - YYERROR; - } - ;} - break; - - case 141: - -/* Line 1464 of yacc.c */ -#line 1017 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.smooth = 1; ;} - break; - - case 142: - -/* Line 1464 of yacc.c */ -#line 1018 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.flat = 1; ;} - break; - - case 143: - -/* Line 1464 of yacc.c */ -#line 1019 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.noperspective = 1; ;} - break; - - case 144: - -/* Line 1464 of yacc.c */ -#line 1023 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.constant = 1; ;} - break; - - case 146: - -/* Line 1464 of yacc.c */ -#line 1029 "glsl_parser.ypp" - { - (yyval.type_qualifier).i = (yyvsp[(1) - (2)].type_qualifier).i | (yyvsp[(2) - (2)].type_qualifier).i; - ;} - break; - - case 147: - -/* Line 1464 of yacc.c */ -#line 1033 "glsl_parser.ypp" - { - (yyval.type_qualifier) = (yyvsp[(2) - (2)].type_qualifier); - (yyval.type_qualifier).q.invariant = 1; - ;} - break; - - case 148: - -/* Line 1464 of yacc.c */ -#line 1040 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.constant = 1; ;} - break; - - case 149: - -/* Line 1464 of yacc.c */ -#line 1041 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.attribute = 1; ;} - break; - - case 150: - -/* Line 1464 of yacc.c */ -#line 1042 "glsl_parser.ypp" - { (yyval.type_qualifier).i = (yyvsp[(1) - (2)].type_qualifier).i; (yyval.type_qualifier).q.varying = 1; ;} - break; - - case 151: - -/* Line 1464 of yacc.c */ -#line 1043 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.centroid = 1; (yyval.type_qualifier).q.varying = 1; ;} - break; - - case 152: - -/* Line 1464 of yacc.c */ -#line 1044 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.in = 1; ;} - break; - - case 153: - -/* Line 1464 of yacc.c */ -#line 1045 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.out = 1; ;} - break; - - case 154: - -/* Line 1464 of yacc.c */ -#line 1046 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.centroid = 1; (yyval.type_qualifier).q.in = 1; ;} - break; - - case 155: - -/* Line 1464 of yacc.c */ -#line 1047 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.centroid = 1; (yyval.type_qualifier).q.out = 1; ;} - break; - - case 156: - -/* Line 1464 of yacc.c */ -#line 1048 "glsl_parser.ypp" - { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.uniform = 1; ;} - break; - - case 158: - -/* Line 1464 of yacc.c */ -#line 1054 "glsl_parser.ypp" - { - (yyval.type_specifier) = (yyvsp[(2) - (2)].type_specifier); - (yyval.type_specifier)->precision = (yyvsp[(1) - (2)].n); - ;} - break; - - case 160: - -/* Line 1464 of yacc.c */ -#line 1063 "glsl_parser.ypp" - { - (yyval.type_specifier) = (yyvsp[(1) - (3)].type_specifier); - (yyval.type_specifier)->is_array = true; - (yyval.type_specifier)->array_size = NULL; - ;} - break; - - case 161: - -/* Line 1464 of yacc.c */ -#line 1069 "glsl_parser.ypp" - { - (yyval.type_specifier) = (yyvsp[(1) - (4)].type_specifier); - (yyval.type_specifier)->is_array = true; - (yyval.type_specifier)->array_size = (yyvsp[(3) - (4)].expression); - ;} - break; - - case 162: - -/* Line 1464 of yacc.c */ -#line 1078 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].n)); - (yyval.type_specifier)->set_location(yylloc); - ;} - break; - - case 163: - -/* Line 1464 of yacc.c */ -#line 1084 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].struct_specifier)); - (yyval.type_specifier)->set_location(yylloc); - ;} - break; - - case 164: - -/* Line 1464 of yacc.c */ -#line 1090 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].identifier)); - (yyval.type_specifier)->set_location(yylloc); - ;} - break; - - case 165: - -/* Line 1464 of yacc.c */ -#line 1098 "glsl_parser.ypp" - { (yyval.n) = ast_void; ;} - break; - - case 166: - -/* Line 1464 of yacc.c */ -#line 1099 "glsl_parser.ypp" - { (yyval.n) = ast_float; ;} - break; - - case 167: - -/* Line 1464 of yacc.c */ -#line 1100 "glsl_parser.ypp" - { (yyval.n) = ast_int; ;} - break; - - case 168: - -/* Line 1464 of yacc.c */ -#line 1101 "glsl_parser.ypp" - { (yyval.n) = ast_uint; ;} - break; - - case 169: - -/* Line 1464 of yacc.c */ -#line 1102 "glsl_parser.ypp" - { (yyval.n) = ast_bool; ;} - break; - - case 170: - -/* Line 1464 of yacc.c */ -#line 1103 "glsl_parser.ypp" - { (yyval.n) = ast_vec2; ;} - break; - - case 171: - -/* Line 1464 of yacc.c */ -#line 1104 "glsl_parser.ypp" - { (yyval.n) = ast_vec3; ;} - break; - - case 172: - -/* Line 1464 of yacc.c */ -#line 1105 "glsl_parser.ypp" - { (yyval.n) = ast_vec4; ;} - break; - - case 173: - -/* Line 1464 of yacc.c */ -#line 1106 "glsl_parser.ypp" - { (yyval.n) = ast_bvec2; ;} - break; - - case 174: - -/* Line 1464 of yacc.c */ -#line 1107 "glsl_parser.ypp" - { (yyval.n) = ast_bvec3; ;} - break; - - case 175: - -/* Line 1464 of yacc.c */ -#line 1108 "glsl_parser.ypp" - { (yyval.n) = ast_bvec4; ;} - break; - - case 176: - -/* Line 1464 of yacc.c */ -#line 1109 "glsl_parser.ypp" - { (yyval.n) = ast_ivec2; ;} - break; - - case 177: - -/* Line 1464 of yacc.c */ -#line 1110 "glsl_parser.ypp" - { (yyval.n) = ast_ivec3; ;} - break; - - case 178: - -/* Line 1464 of yacc.c */ -#line 1111 "glsl_parser.ypp" - { (yyval.n) = ast_ivec4; ;} - break; - - case 179: - -/* Line 1464 of yacc.c */ -#line 1112 "glsl_parser.ypp" - { (yyval.n) = ast_uvec2; ;} - break; - - case 180: - -/* Line 1464 of yacc.c */ -#line 1113 "glsl_parser.ypp" - { (yyval.n) = ast_uvec3; ;} - break; - - case 181: - -/* Line 1464 of yacc.c */ -#line 1114 "glsl_parser.ypp" - { (yyval.n) = ast_uvec4; ;} - break; - - case 182: - -/* Line 1464 of yacc.c */ -#line 1115 "glsl_parser.ypp" - { (yyval.n) = ast_mat2; ;} - break; - - case 183: - -/* Line 1464 of yacc.c */ -#line 1116 "glsl_parser.ypp" - { (yyval.n) = ast_mat2x3; ;} - break; - - case 184: - -/* Line 1464 of yacc.c */ -#line 1117 "glsl_parser.ypp" - { (yyval.n) = ast_mat2x4; ;} - break; - - case 185: - -/* Line 1464 of yacc.c */ -#line 1118 "glsl_parser.ypp" - { (yyval.n) = ast_mat3x2; ;} - break; - - case 186: - -/* Line 1464 of yacc.c */ -#line 1119 "glsl_parser.ypp" - { (yyval.n) = ast_mat3; ;} - break; - - case 187: - -/* Line 1464 of yacc.c */ -#line 1120 "glsl_parser.ypp" - { (yyval.n) = ast_mat3x4; ;} - break; - - case 188: - -/* Line 1464 of yacc.c */ -#line 1121 "glsl_parser.ypp" - { (yyval.n) = ast_mat4x2; ;} - break; - - case 189: - -/* Line 1464 of yacc.c */ -#line 1122 "glsl_parser.ypp" - { (yyval.n) = ast_mat4x3; ;} - break; - - case 190: - -/* Line 1464 of yacc.c */ -#line 1123 "glsl_parser.ypp" - { (yyval.n) = ast_mat4; ;} - break; - - case 191: - -/* Line 1464 of yacc.c */ -#line 1124 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1d; ;} - break; - - case 192: - -/* Line 1464 of yacc.c */ -#line 1125 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2d; ;} - break; - - case 193: - -/* Line 1464 of yacc.c */ -#line 1126 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2drect; ;} - break; - - case 194: - -/* Line 1464 of yacc.c */ -#line 1127 "glsl_parser.ypp" - { (yyval.n) = ast_sampler3d; ;} - break; - - case 195: - -/* Line 1464 of yacc.c */ -#line 1128 "glsl_parser.ypp" - { (yyval.n) = ast_samplercube; ;} - break; - - case 196: - -/* Line 1464 of yacc.c */ -#line 1129 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1dshadow; ;} - break; - - case 197: - -/* Line 1464 of yacc.c */ -#line 1130 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2dshadow; ;} - break; - - case 198: - -/* Line 1464 of yacc.c */ -#line 1131 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2drectshadow; ;} - break; - - case 199: - -/* Line 1464 of yacc.c */ -#line 1132 "glsl_parser.ypp" - { (yyval.n) = ast_samplercubeshadow; ;} - break; - - case 200: - -/* Line 1464 of yacc.c */ -#line 1133 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1darray; ;} - break; - - case 201: - -/* Line 1464 of yacc.c */ -#line 1134 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2darray; ;} - break; - - case 202: - -/* Line 1464 of yacc.c */ -#line 1135 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1darrayshadow; ;} - break; - - case 203: - -/* Line 1464 of yacc.c */ -#line 1136 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2darrayshadow; ;} - break; - - case 204: - -/* Line 1464 of yacc.c */ -#line 1137 "glsl_parser.ypp" - { (yyval.n) = ast_isampler1d; ;} - break; - - case 205: - -/* Line 1464 of yacc.c */ -#line 1138 "glsl_parser.ypp" - { (yyval.n) = ast_isampler2d; ;} - break; - - case 206: - -/* Line 1464 of yacc.c */ -#line 1139 "glsl_parser.ypp" - { (yyval.n) = ast_isampler3d; ;} - break; - - case 207: - -/* Line 1464 of yacc.c */ -#line 1140 "glsl_parser.ypp" - { (yyval.n) = ast_isamplercube; ;} - break; - - case 208: - -/* Line 1464 of yacc.c */ -#line 1141 "glsl_parser.ypp" - { (yyval.n) = ast_isampler1darray; ;} - break; - - case 209: - -/* Line 1464 of yacc.c */ -#line 1142 "glsl_parser.ypp" - { (yyval.n) = ast_isampler2darray; ;} - break; - - case 210: - -/* Line 1464 of yacc.c */ -#line 1143 "glsl_parser.ypp" - { (yyval.n) = ast_usampler1d; ;} - break; - - case 211: - -/* Line 1464 of yacc.c */ -#line 1144 "glsl_parser.ypp" - { (yyval.n) = ast_usampler2d; ;} - break; - - case 212: - -/* Line 1464 of yacc.c */ -#line 1145 "glsl_parser.ypp" - { (yyval.n) = ast_usampler3d; ;} - break; - - case 213: - -/* Line 1464 of yacc.c */ -#line 1146 "glsl_parser.ypp" - { (yyval.n) = ast_usamplercube; ;} - break; - - case 214: - -/* Line 1464 of yacc.c */ -#line 1147 "glsl_parser.ypp" - { (yyval.n) = ast_usampler1darray; ;} - break; - - case 215: - -/* Line 1464 of yacc.c */ -#line 1148 "glsl_parser.ypp" - { (yyval.n) = ast_usampler2darray; ;} - break; - - case 216: - -/* Line 1464 of yacc.c */ -#line 1152 "glsl_parser.ypp" - { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, - "precision qualifier forbidden " - "in GLSL %d.%d (1.30 or later " - "required)\n", - state->language_version / 100, - state->language_version % 100); - - (yyval.n) = ast_precision_high; - ;} - break; - - case 217: - -/* Line 1464 of yacc.c */ -#line 1163 "glsl_parser.ypp" - { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, - "precision qualifier forbidden " - "in GLSL %d.%d (1.30 or later " - "required)\n", - state->language_version / 100, - state->language_version % 100); - - (yyval.n) = ast_precision_medium; - ;} - break; - - case 218: - -/* Line 1464 of yacc.c */ -#line 1174 "glsl_parser.ypp" - { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, - "precision qualifier forbidden " - "in GLSL %d.%d (1.30 or later " - "required)\n", - state->language_version / 100, - state->language_version % 100); - - (yyval.n) = ast_precision_low; - ;} - break; - - case 219: - -/* Line 1464 of yacc.c */ -#line 1189 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.struct_specifier) = new(ctx) ast_struct_specifier((yyvsp[(2) - (5)].identifier), (yyvsp[(4) - (5)].node)); - (yyval.struct_specifier)->set_location(yylloc); - ;} - break; - - case 220: - -/* Line 1464 of yacc.c */ -#line 1195 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.struct_specifier) = new(ctx) ast_struct_specifier(NULL, (yyvsp[(3) - (4)].node)); - (yyval.struct_specifier)->set_location(yylloc); - ;} - break; - - case 221: - -/* Line 1464 of yacc.c */ -#line 1204 "glsl_parser.ypp" - { - (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list); - (yyvsp[(1) - (1)].declarator_list)->link.self_link(); - ;} - break; - - case 222: - -/* Line 1464 of yacc.c */ -#line 1209 "glsl_parser.ypp" - { - (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node); - (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link); - ;} - break; - - case 223: - -/* Line 1464 of yacc.c */ -#line 1217 "glsl_parser.ypp" - { - void *ctx = state; - ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); - type->set_location(yylloc); - - type->specifier = (yyvsp[(1) - (3)].type_specifier); - (yyval.declarator_list) = new(ctx) ast_declarator_list(type); - (yyval.declarator_list)->set_location(yylloc); - - (yyval.declarator_list)->declarations.push_degenerate_list_at_head(& (yyvsp[(2) - (3)].declaration)->link); - ;} - break; - - case 224: - -/* Line 1464 of yacc.c */ -#line 1232 "glsl_parser.ypp" - { - (yyval.declaration) = (yyvsp[(1) - (1)].declaration); - (yyvsp[(1) - (1)].declaration)->link.self_link(); - ;} - break; - - case 225: - -/* Line 1464 of yacc.c */ -#line 1237 "glsl_parser.ypp" - { - (yyval.declaration) = (yyvsp[(1) - (3)].declaration); - (yyval.declaration)->link.insert_before(& (yyvsp[(3) - (3)].declaration)->link); - ;} - break; - - case 226: - -/* Line 1464 of yacc.c */ -#line 1245 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (1)].identifier), false, NULL, NULL); - (yyval.declaration)->set_location(yylloc); - ;} - break; - - case 227: - -/* Line 1464 of yacc.c */ -#line 1251 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (4)].identifier), true, (yyvsp[(3) - (4)].expression), NULL); - (yyval.declaration)->set_location(yylloc); - ;} - break; - - case 230: - -/* Line 1464 of yacc.c */ -#line 1269 "glsl_parser.ypp" - { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} - break; - - case 235: - -/* Line 1464 of yacc.c */ -#line 1277 "glsl_parser.ypp" - { (yyval.node) = NULL; ;} - break; - - case 236: - -/* Line 1464 of yacc.c */ -#line 1278 "glsl_parser.ypp" - { (yyval.node) = NULL; ;} - break; - - case 239: - -/* Line 1464 of yacc.c */ -#line 1285 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(true, NULL); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 240: - -/* Line 1464 of yacc.c */ -#line 1291 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(true, (yyvsp[(2) - (3)].node)); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 241: - -/* Line 1464 of yacc.c */ -#line 1299 "glsl_parser.ypp" - { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} - break; - - case 243: - -/* Line 1464 of yacc.c */ -#line 1305 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(false, NULL); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 244: - -/* Line 1464 of yacc.c */ -#line 1311 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(false, (yyvsp[(2) - (3)].node)); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 245: - -/* Line 1464 of yacc.c */ -#line 1320 "glsl_parser.ypp" - { - if ((yyvsp[(1) - (1)].node) == NULL) { - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "<nil> statement\n"); - assert((yyvsp[(1) - (1)].node) != NULL); - } - - (yyval.node) = (yyvsp[(1) - (1)].node); - (yyval.node)->link.self_link(); - ;} - break; - - case 246: - -/* Line 1464 of yacc.c */ -#line 1330 "glsl_parser.ypp" - { - if ((yyvsp[(2) - (2)].node) == NULL) { - _mesa_glsl_error(& (yylsp[(2) - (2)]), state, "<nil> statement\n"); - assert((yyvsp[(2) - (2)].node) != NULL); - } - (yyval.node) = (yyvsp[(1) - (2)].node); - (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].node)->link); - ;} - break; - - case 247: - -/* Line 1464 of yacc.c */ -#line 1342 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_expression_statement(NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 248: - -/* Line 1464 of yacc.c */ -#line 1348 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_expression_statement((yyvsp[(1) - (2)].expression)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 249: - -/* Line 1464 of yacc.c */ -#line 1357 "glsl_parser.ypp" - { - (yyval.node) = new(state) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].selection_rest_statement).then_statement, - (yyvsp[(5) - (5)].selection_rest_statement).else_statement); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 250: - -/* Line 1464 of yacc.c */ -#line 1366 "glsl_parser.ypp" - { - (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (3)].node); - (yyval.selection_rest_statement).else_statement = (yyvsp[(3) - (3)].node); - ;} - break; - - case 251: - -/* Line 1464 of yacc.c */ -#line 1371 "glsl_parser.ypp" - { - (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (1)].node); - (yyval.selection_rest_statement).else_statement = NULL; - ;} - break; - - case 252: - -/* Line 1464 of yacc.c */ -#line 1379 "glsl_parser.ypp" - { - (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression); - ;} - break; - - case 253: - -/* Line 1464 of yacc.c */ -#line 1383 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); - ast_declarator_list *declarator = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); - decl->set_location(yylloc); - declarator->set_location(yylloc); - - declarator->declarations.push_tail(&decl->link); - (yyval.node) = declarator; - ;} - break; - - case 257: - -/* Line 1464 of yacc.c */ -#line 1406 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, - NULL, (yyvsp[(3) - (5)].node), NULL, (yyvsp[(5) - (5)].node)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 258: - -/* Line 1464 of yacc.c */ -#line 1413 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, - NULL, (yyvsp[(5) - (7)].expression), NULL, (yyvsp[(2) - (7)].node)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 259: - -/* Line 1464 of yacc.c */ -#line 1420 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, - (yyvsp[(3) - (6)].node), (yyvsp[(4) - (6)].for_rest_statement).cond, (yyvsp[(4) - (6)].for_rest_statement).rest, (yyvsp[(6) - (6)].node)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 263: - -/* Line 1464 of yacc.c */ -#line 1436 "glsl_parser.ypp" - { - (yyval.node) = NULL; - ;} - break; - - case 264: - -/* Line 1464 of yacc.c */ -#line 1443 "glsl_parser.ypp" - { - (yyval.for_rest_statement).cond = (yyvsp[(1) - (2)].node); - (yyval.for_rest_statement).rest = NULL; - ;} - break; - - case 265: - -/* Line 1464 of yacc.c */ -#line 1448 "glsl_parser.ypp" - { - (yyval.for_rest_statement).cond = (yyvsp[(1) - (3)].node); - (yyval.for_rest_statement).rest = (yyvsp[(3) - (3)].expression); - ;} - break; - - case 266: - -/* Line 1464 of yacc.c */ -#line 1457 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 267: - -/* Line 1464 of yacc.c */ -#line 1463 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 268: - -/* Line 1464 of yacc.c */ -#line 1469 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 269: - -/* Line 1464 of yacc.c */ -#line 1475 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, (yyvsp[(2) - (3)].expression)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 270: - -/* Line 1464 of yacc.c */ -#line 1481 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 271: - -/* Line 1464 of yacc.c */ -#line 1489 "glsl_parser.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].function_definition); ;} - break; - - case 272: - -/* Line 1464 of yacc.c */ -#line 1490 "glsl_parser.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); ;} - break; - - case 273: - -/* Line 1464 of yacc.c */ -#line 1491 "glsl_parser.ypp" - { (yyval.node) = NULL; ;} - break; - - case 274: - -/* Line 1464 of yacc.c */ -#line 1496 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.function_definition) = new(ctx) ast_function_definition(); - (yyval.function_definition)->set_location(yylloc); - (yyval.function_definition)->prototype = (yyvsp[(1) - (2)].function); - (yyval.function_definition)->body = (yyvsp[(2) - (2)].compound_statement); - ;} - break; - - - -/* Line 1464 of yacc.c */ -#line 5016 "glsl_parser.cpp" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, state, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, state, yymsg); - } - else - { - yyerror (&yylloc, state, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, state); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, state); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, state, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, state); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, state); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - +/* A Bison parser, made by GNU Bison 2.4.3. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.4.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+/* Substitute the variable and function names. */
+#define yyparse _mesa_glsl_parse
+#define yylex _mesa_glsl_lex
+#define yyerror _mesa_glsl_error
+#define yylval _mesa_glsl_lval
+#define yychar _mesa_glsl_char
+#define yydebug _mesa_glsl_debug
+#define yynerrs _mesa_glsl_nerrs
+#define yylloc _mesa_glsl_lloc
+
+/* Copy the first part of user declarations. */
+
+/* Line 189 of yacc.c */
+#line 1 "glsl_parser.ypp"
+
+/*
+ * Copyright © 2008, 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "ast.h"
+#include "glsl_parser_extras.h"
+#include "glsl_types.h"
+
+#define YYLEX_PARAM state->scanner
+
+
+
+/* Line 189 of yacc.c */
+#line 117 "glsl_parser.cpp"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ATTRIBUTE = 258,
+ CONST_TOK = 259,
+ BOOL_TOK = 260,
+ FLOAT_TOK = 261,
+ INT_TOK = 262,
+ UINT_TOK = 263,
+ BREAK = 264,
+ CONTINUE = 265,
+ DO = 266,
+ ELSE = 267,
+ FOR = 268,
+ IF = 269,
+ DISCARD = 270,
+ RETURN = 271,
+ SWITCH = 272,
+ CASE = 273,
+ DEFAULT = 274,
+ BVEC2 = 275,
+ BVEC3 = 276,
+ BVEC4 = 277,
+ IVEC2 = 278,
+ IVEC3 = 279,
+ IVEC4 = 280,
+ UVEC2 = 281,
+ UVEC3 = 282,
+ UVEC4 = 283,
+ VEC2 = 284,
+ VEC3 = 285,
+ VEC4 = 286,
+ CENTROID = 287,
+ IN_TOK = 288,
+ OUT_TOK = 289,
+ INOUT_TOK = 290,
+ UNIFORM = 291,
+ VARYING = 292,
+ NOPERSPECTIVE = 293,
+ FLAT = 294,
+ SMOOTH = 295,
+ MAT2X2 = 296,
+ MAT2X3 = 297,
+ MAT2X4 = 298,
+ MAT3X2 = 299,
+ MAT3X3 = 300,
+ MAT3X4 = 301,
+ MAT4X2 = 302,
+ MAT4X3 = 303,
+ MAT4X4 = 304,
+ SAMPLER1D = 305,
+ SAMPLER2D = 306,
+ SAMPLER3D = 307,
+ SAMPLERCUBE = 308,
+ SAMPLER1DSHADOW = 309,
+ SAMPLER2DSHADOW = 310,
+ SAMPLERCUBESHADOW = 311,
+ SAMPLER1DARRAY = 312,
+ SAMPLER2DARRAY = 313,
+ SAMPLER1DARRAYSHADOW = 314,
+ SAMPLER2DARRAYSHADOW = 315,
+ ISAMPLER1D = 316,
+ ISAMPLER2D = 317,
+ ISAMPLER3D = 318,
+ ISAMPLERCUBE = 319,
+ ISAMPLER1DARRAY = 320,
+ ISAMPLER2DARRAY = 321,
+ USAMPLER1D = 322,
+ USAMPLER2D = 323,
+ USAMPLER3D = 324,
+ USAMPLERCUBE = 325,
+ USAMPLER1DARRAY = 326,
+ USAMPLER2DARRAY = 327,
+ STRUCT = 328,
+ VOID_TOK = 329,
+ WHILE = 330,
+ IDENTIFIER = 331,
+ FLOATCONSTANT = 332,
+ INTCONSTANT = 333,
+ UINTCONSTANT = 334,
+ BOOLCONSTANT = 335,
+ FIELD_SELECTION = 336,
+ LEFT_OP = 337,
+ RIGHT_OP = 338,
+ INC_OP = 339,
+ DEC_OP = 340,
+ LE_OP = 341,
+ GE_OP = 342,
+ EQ_OP = 343,
+ NE_OP = 344,
+ AND_OP = 345,
+ OR_OP = 346,
+ XOR_OP = 347,
+ MUL_ASSIGN = 348,
+ DIV_ASSIGN = 349,
+ ADD_ASSIGN = 350,
+ MOD_ASSIGN = 351,
+ LEFT_ASSIGN = 352,
+ RIGHT_ASSIGN = 353,
+ AND_ASSIGN = 354,
+ XOR_ASSIGN = 355,
+ OR_ASSIGN = 356,
+ SUB_ASSIGN = 357,
+ INVARIANT = 358,
+ LOWP = 359,
+ MEDIUMP = 360,
+ HIGHP = 361,
+ SUPERP = 362,
+ PRECISION = 363,
+ VERSION = 364,
+ EXTENSION = 365,
+ LINE = 366,
+ COLON = 367,
+ EOL = 368,
+ INTERFACE = 369,
+ OUTPUT = 370,
+ PRAGMA_DEBUG_ON = 371,
+ PRAGMA_DEBUG_OFF = 372,
+ PRAGMA_OPTIMIZE_ON = 373,
+ PRAGMA_OPTIMIZE_OFF = 374,
+ LAYOUT_TOK = 375,
+ ASM = 376,
+ CLASS = 377,
+ UNION = 378,
+ ENUM = 379,
+ TYPEDEF = 380,
+ TEMPLATE = 381,
+ THIS = 382,
+ PACKED_TOK = 383,
+ GOTO = 384,
+ INLINE_TOK = 385,
+ NOINLINE = 386,
+ VOLATILE = 387,
+ PUBLIC_TOK = 388,
+ STATIC = 389,
+ EXTERN = 390,
+ EXTERNAL = 391,
+ LONG_TOK = 392,
+ SHORT_TOK = 393,
+ DOUBLE_TOK = 394,
+ HALF = 395,
+ FIXED_TOK = 396,
+ UNSIGNED = 397,
+ INPUT_TOK = 398,
+ OUPTUT = 399,
+ HVEC2 = 400,
+ HVEC3 = 401,
+ HVEC4 = 402,
+ DVEC2 = 403,
+ DVEC3 = 404,
+ DVEC4 = 405,
+ FVEC2 = 406,
+ FVEC3 = 407,
+ FVEC4 = 408,
+ SAMPLER2DRECT = 409,
+ SAMPLER3DRECT = 410,
+ SAMPLER2DRECTSHADOW = 411,
+ SIZEOF = 412,
+ CAST = 413,
+ NAMESPACE = 414,
+ USING = 415,
+ ERROR_TOK = 416,
+ COMMON = 417,
+ PARTITION = 418,
+ ACTIVE = 419,
+ SAMPLERBUFFER = 420,
+ FILTER = 421,
+ IMAGE1D = 422,
+ IMAGE2D = 423,
+ IMAGE3D = 424,
+ IMAGECUBE = 425,
+ IMAGE1DARRAY = 426,
+ IMAGE2DARRAY = 427,
+ IIMAGE1D = 428,
+ IIMAGE2D = 429,
+ IIMAGE3D = 430,
+ IIMAGECUBE = 431,
+ IIMAGE1DARRAY = 432,
+ IIMAGE2DARRAY = 433,
+ UIMAGE1D = 434,
+ UIMAGE2D = 435,
+ UIMAGE3D = 436,
+ UIMAGECUBE = 437,
+ UIMAGE1DARRAY = 438,
+ UIMAGE2DARRAY = 439,
+ IMAGE1DSHADOW = 440,
+ IMAGE2DSHADOW = 441,
+ IMAGEBUFFER = 442,
+ IIMAGEBUFFER = 443,
+ UIMAGEBUFFER = 444,
+ IMAGE1DARRAYSHADOW = 445,
+ IMAGE2DARRAYSHADOW = 446,
+ ROW_MAJOR = 447
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 214 of yacc.c */
+#line 52 "glsl_parser.ypp"
+
+ int n;
+ float real;
+ char *identifier;
+
+ struct ast_type_qualifier type_qualifier;
+
+ ast_node *node;
+ ast_type_specifier *type_specifier;
+ ast_fully_specified_type *fully_specified_type;
+ ast_function *function;
+ ast_parameter_declarator *parameter_declarator;
+ ast_function_definition *function_definition;
+ ast_compound_statement *compound_statement;
+ ast_expression *expression;
+ ast_declarator_list *declarator_list;
+ ast_struct_specifier *struct_specifier;
+ ast_declaration *declaration;
+
+ struct {
+ ast_node *cond;
+ ast_expression *rest;
+ } for_rest_statement;
+
+ struct {
+ ast_node *then_statement;
+ ast_node *else_statement;
+ } selection_rest_statement;
+
+
+
+/* Line 214 of yacc.c */
+#line 377 "glsl_parser.cpp"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 264 of yacc.c */
+#line 402 "glsl_parser.cpp"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 5
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 3718
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 217
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 87
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 278
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 413
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 447
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 201, 2, 2, 2, 205, 208, 2,
+ 193, 194, 203, 199, 198, 200, 197, 204, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 212, 214,
+ 206, 213, 207, 211, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 195, 2, 196, 209, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 215, 210, 216, 202, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
+ 185, 186, 187, 188, 189, 190, 191, 192
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 4, 9, 10, 14, 17, 20, 23,
+ 26, 27, 30, 36, 38, 41, 43, 45, 47, 49,
+ 51, 53, 57, 59, 64, 66, 70, 73, 76, 78,
+ 80, 82, 86, 89, 92, 95, 97, 100, 104, 107,
+ 109, 111, 113, 115, 118, 121, 124, 126, 128, 130,
+ 132, 134, 138, 142, 146, 148, 152, 156, 158, 162,
+ 166, 168, 172, 176, 180, 184, 186, 190, 194, 196,
+ 200, 202, 206, 208, 212, 214, 218, 220, 224, 226,
+ 230, 232, 238, 240, 244, 246, 248, 250, 252, 254,
+ 256, 258, 260, 262, 264, 266, 268, 272, 274, 277,
+ 280, 285, 288, 290, 292, 295, 299, 303, 306, 312,
+ 316, 319, 323, 326, 327, 329, 331, 333, 335, 337,
+ 341, 347, 354, 362, 371, 377, 379, 382, 387, 393,
+ 400, 408, 413, 416, 418, 421, 426, 428, 432, 434,
+ 438, 440, 442, 444, 446, 448, 450, 453, 455, 458,
+ 461, 465, 467, 469, 471, 473, 476, 478, 480, 483,
+ 486, 488, 490, 493, 495, 499, 504, 506, 508, 510,
+ 512, 514, 516, 518, 520, 522, 524, 526, 528, 530,
+ 532, 534, 536, 538, 540, 542, 544, 546, 548, 550,
+ 552, 554, 556, 558, 560, 562, 564, 566, 568, 570,
+ 572, 574, 576, 578, 580, 582, 584, 586, 588, 590,
+ 592, 594, 596, 598, 600, 602, 604, 606, 608, 610,
+ 612, 614, 616, 618, 624, 629, 631, 634, 638, 640,
+ 644, 646, 651, 653, 655, 657, 659, 661, 663, 665,
+ 667, 669, 671, 673, 676, 680, 682, 684, 687, 691,
+ 693, 696, 698, 701, 707, 711, 713, 715, 720, 726,
+ 730, 733, 739, 747, 754, 756, 758, 760, 761, 764,
+ 768, 771, 774, 777, 781, 784, 786, 788, 790
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 218, 0, -1, -1, 220, 222, 219, 224, -1, -1,
+ 109, 78, 113, -1, 116, 113, -1, 117, 113, -1,
+ 118, 113, -1, 119, 113, -1, -1, 222, 223, -1,
+ 110, 76, 112, 76, 113, -1, 302, -1, 224, 302,
+ -1, 76, -1, 225, -1, 78, -1, 79, -1, 77,
+ -1, 80, -1, 193, 252, 194, -1, 226, -1, 227,
+ 195, 228, 196, -1, 229, -1, 227, 197, 76, -1,
+ 227, 84, -1, 227, 85, -1, 252, -1, 230, -1,
+ 231, -1, 227, 197, 231, -1, 233, 194, -1, 232,
+ 194, -1, 234, 74, -1, 234, -1, 234, 250, -1,
+ 233, 198, 250, -1, 235, 193, -1, 273, -1, 76,
+ -1, 81, -1, 227, -1, 84, 236, -1, 85, 236,
+ -1, 237, 236, -1, 199, -1, 200, -1, 201, -1,
+ 202, -1, 236, -1, 238, 203, 236, -1, 238, 204,
+ 236, -1, 238, 205, 236, -1, 238, -1, 239, 199,
+ 238, -1, 239, 200, 238, -1, 239, -1, 240, 82,
+ 239, -1, 240, 83, 239, -1, 240, -1, 241, 206,
+ 240, -1, 241, 207, 240, -1, 241, 86, 240, -1,
+ 241, 87, 240, -1, 241, -1, 242, 88, 241, -1,
+ 242, 89, 241, -1, 242, -1, 243, 208, 242, -1,
+ 243, -1, 244, 209, 243, -1, 244, -1, 245, 210,
+ 244, -1, 245, -1, 246, 90, 245, -1, 246, -1,
+ 247, 92, 246, -1, 247, -1, 248, 91, 247, -1,
+ 248, -1, 248, 211, 252, 212, 250, -1, 249, -1,
+ 236, 251, 250, -1, 213, -1, 93, -1, 94, -1,
+ 96, -1, 95, -1, 102, -1, 97, -1, 98, -1,
+ 99, -1, 100, -1, 101, -1, 250, -1, 252, 198,
+ 250, -1, 249, -1, 255, 214, -1, 263, 214, -1,
+ 108, 277, 274, 214, -1, 256, 194, -1, 258, -1,
+ 257, -1, 258, 260, -1, 257, 198, 260, -1, 265,
+ 76, 193, -1, 273, 76, -1, 273, 76, 195, 253,
+ 196, -1, 270, 261, 259, -1, 261, 259, -1, 270,
+ 261, 262, -1, 261, 262, -1, -1, 33, -1, 34,
+ -1, 35, -1, 273, -1, 264, -1, 263, 198, 76,
+ -1, 263, 198, 76, 195, 196, -1, 263, 198, 76,
+ 195, 253, 196, -1, 263, 198, 76, 195, 196, 213,
+ 283, -1, 263, 198, 76, 195, 253, 196, 213, 283,
+ -1, 263, 198, 76, 213, 283, -1, 265, -1, 265,
+ 76, -1, 265, 76, 195, 196, -1, 265, 76, 195,
+ 253, 196, -1, 265, 76, 195, 196, 213, 283, -1,
+ 265, 76, 195, 253, 196, 213, 283, -1, 265, 76,
+ 213, 283, -1, 103, 76, -1, 273, -1, 271, 273,
+ -1, 120, 193, 267, 194, -1, 268, -1, 267, 198,
+ 268, -1, 76, -1, 76, 213, 78, -1, 40, -1,
+ 39, -1, 38, -1, 4, -1, 272, -1, 266, -1,
+ 266, 272, -1, 269, -1, 269, 272, -1, 103, 272,
+ -1, 103, 269, 272, -1, 103, -1, 4, -1, 3,
+ -1, 37, -1, 32, 37, -1, 33, -1, 34, -1,
+ 32, 33, -1, 32, 34, -1, 36, -1, 274, -1,
+ 277, 274, -1, 275, -1, 275, 195, 196, -1, 275,
+ 195, 253, 196, -1, 276, -1, 278, -1, 76, -1,
+ 74, -1, 6, -1, 7, -1, 8, -1, 5, -1,
+ 29, -1, 30, -1, 31, -1, 20, -1, 21, -1,
+ 22, -1, 23, -1, 24, -1, 25, -1, 26, -1,
+ 27, -1, 28, -1, 41, -1, 42, -1, 43, -1,
+ 44, -1, 45, -1, 46, -1, 47, -1, 48, -1,
+ 49, -1, 50, -1, 51, -1, 154, -1, 52, -1,
+ 53, -1, 54, -1, 55, -1, 156, -1, 56, -1,
+ 57, -1, 58, -1, 59, -1, 60, -1, 61, -1,
+ 62, -1, 63, -1, 64, -1, 65, -1, 66, -1,
+ 67, -1, 68, -1, 69, -1, 70, -1, 71, -1,
+ 72, -1, 106, -1, 105, -1, 104, -1, 73, 76,
+ 215, 279, 216, -1, 73, 215, 279, 216, -1, 280,
+ -1, 279, 280, -1, 273, 281, 214, -1, 282, -1,
+ 281, 198, 282, -1, 76, -1, 76, 195, 253, 196,
+ -1, 250, -1, 254, -1, 287, -1, 286, -1, 284,
+ -1, 291, -1, 292, -1, 295, -1, 296, -1, 297,
+ -1, 301, -1, 215, 216, -1, 215, 290, 216, -1,
+ 289, -1, 286, -1, 215, 216, -1, 215, 290, 216,
+ -1, 285, -1, 290, 285, -1, 214, -1, 252, 214,
+ -1, 14, 193, 252, 194, 293, -1, 285, 12, 285,
+ -1, 285, -1, 252, -1, 265, 76, 213, 283, -1,
+ 17, 193, 252, 194, 287, -1, 18, 252, 212, -1,
+ 19, 212, -1, 75, 193, 294, 194, 288, -1, 11,
+ 285, 75, 193, 252, 194, 214, -1, 13, 193, 298,
+ 300, 194, 288, -1, 291, -1, 284, -1, 294, -1,
+ -1, 299, 214, -1, 299, 214, 252, -1, 10, 214,
+ -1, 9, 214, -1, 16, 214, -1, 16, 252, 214,
+ -1, 15, 214, -1, 303, -1, 254, -1, 221, -1,
+ 255, 289, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 212, 212, 211, 218, 220, 240, 241, 242, 243,
+ 246, 248, 252, 261, 269, 280, 284, 291, 298, 305,
+ 312, 319, 326, 327, 333, 337, 344, 350, 359, 363,
+ 367, 368, 377, 378, 382, 383, 387, 393, 405, 409,
+ 415, 422, 433, 434, 440, 446, 456, 457, 458, 459,
+ 463, 464, 470, 476, 485, 486, 492, 501, 502, 508,
+ 517, 518, 524, 530, 536, 545, 546, 552, 561, 562,
+ 571, 572, 581, 582, 591, 592, 601, 602, 611, 612,
+ 621, 622, 631, 632, 641, 642, 643, 644, 645, 646,
+ 647, 648, 649, 650, 651, 655, 659, 675, 679, 683,
+ 687, 701, 705, 706, 710, 715, 723, 734, 744, 759,
+ 766, 771, 782, 795, 798, 803, 808, 817, 821, 822,
+ 831, 840, 849, 858, 867, 880, 891, 900, 909, 918,
+ 927, 936, 945, 959, 966, 977, 984, 985, 1004, 1033,
+ 1074, 1079, 1084, 1092, 1100, 1101, 1102, 1107, 1108, 1113,
+ 1118, 1124, 1132, 1137, 1142, 1147, 1153, 1158, 1163, 1168,
+ 1173, 1181, 1182, 1190, 1191, 1197, 1206, 1212, 1218, 1227,
+ 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237,
+ 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247,
+ 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257,
+ 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267,
+ 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277,
+ 1281, 1292, 1303, 1317, 1323, 1332, 1337, 1345, 1360, 1365,
+ 1373, 1379, 1388, 1392, 1398, 1399, 1403, 1404, 1405, 1406,
+ 1407, 1408, 1409, 1413, 1419, 1428, 1429, 1433, 1439, 1448,
+ 1458, 1470, 1476, 1485, 1494, 1499, 1507, 1511, 1525, 1529,
+ 1530, 1534, 1541, 1548, 1558, 1559, 1563, 1565, 1571, 1576,
+ 1585, 1591, 1597, 1603, 1609, 1618, 1619, 1620, 1624
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "ATTRIBUTE", "CONST_TOK", "BOOL_TOK",
+ "FLOAT_TOK", "INT_TOK", "UINT_TOK", "BREAK", "CONTINUE", "DO", "ELSE",
+ "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "BVEC2",
+ "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "UVEC2", "UVEC3", "UVEC4",
+ "VEC2", "VEC3", "VEC4", "CENTROID", "IN_TOK", "OUT_TOK", "INOUT_TOK",
+ "UNIFORM", "VARYING", "NOPERSPECTIVE", "FLAT", "SMOOTH", "MAT2X2",
+ "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3",
+ "MAT4X4", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE",
+ "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW",
+ "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW",
+ "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D",
+ "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D",
+ "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY",
+ "USAMPLER2DARRAY", "STRUCT", "VOID_TOK", "WHILE", "IDENTIFIER",
+ "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT",
+ "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP",
+ "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN",
+ "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN",
+ "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "INVARIANT",
+ "LOWP", "MEDIUMP", "HIGHP", "SUPERP", "PRECISION", "VERSION",
+ "EXTENSION", "LINE", "COLON", "EOL", "INTERFACE", "OUTPUT",
+ "PRAGMA_DEBUG_ON", "PRAGMA_DEBUG_OFF", "PRAGMA_OPTIMIZE_ON",
+ "PRAGMA_OPTIMIZE_OFF", "LAYOUT_TOK", "ASM", "CLASS", "UNION", "ENUM",
+ "TYPEDEF", "TEMPLATE", "THIS", "PACKED_TOK", "GOTO", "INLINE_TOK",
+ "NOINLINE", "VOLATILE", "PUBLIC_TOK", "STATIC", "EXTERN", "EXTERNAL",
+ "LONG_TOK", "SHORT_TOK", "DOUBLE_TOK", "HALF", "FIXED_TOK", "UNSIGNED",
+ "INPUT_TOK", "OUPTUT", "HVEC2", "HVEC3", "HVEC4", "DVEC2", "DVEC3",
+ "DVEC4", "FVEC2", "FVEC3", "FVEC4", "SAMPLER2DRECT", "SAMPLER3DRECT",
+ "SAMPLER2DRECTSHADOW", "SIZEOF", "CAST", "NAMESPACE", "USING",
+ "ERROR_TOK", "COMMON", "PARTITION", "ACTIVE", "SAMPLERBUFFER", "FILTER",
+ "IMAGE1D", "IMAGE2D", "IMAGE3D", "IMAGECUBE", "IMAGE1DARRAY",
+ "IMAGE2DARRAY", "IIMAGE1D", "IIMAGE2D", "IIMAGE3D", "IIMAGECUBE",
+ "IIMAGE1DARRAY", "IIMAGE2DARRAY", "UIMAGE1D", "UIMAGE2D", "UIMAGE3D",
+ "UIMAGECUBE", "UIMAGE1DARRAY", "UIMAGE2DARRAY", "IMAGE1DSHADOW",
+ "IMAGE2DSHADOW", "IMAGEBUFFER", "IIMAGEBUFFER", "UIMAGEBUFFER",
+ "IMAGE1DARRAYSHADOW", "IMAGE2DARRAYSHADOW", "ROW_MAJOR", "'('", "')'",
+ "'['", "']'", "'.'", "','", "'+'", "'-'", "'!'", "'~'", "'*'", "'/'",
+ "'%'", "'<'", "'>'", "'&'", "'^'", "'|'", "'?'", "':'", "'='", "';'",
+ "'{'", "'}'", "$accept", "translation_unit", "$@1", "version_statement",
+ "pragma_statement", "extension_statement_list", "extension_statement",
+ "external_declaration_list", "variable_identifier", "primary_expression",
+ "postfix_expression", "integer_expression", "function_call",
+ "function_call_or_method", "function_call_generic",
+ "function_call_header_no_parameters",
+ "function_call_header_with_parameters", "function_call_header",
+ "function_identifier", "unary_expression", "unary_operator",
+ "multiplicative_expression", "additive_expression", "shift_expression",
+ "relational_expression", "equality_expression", "and_expression",
+ "exclusive_or_expression", "inclusive_or_expression",
+ "logical_and_expression", "logical_xor_expression",
+ "logical_or_expression", "conditional_expression",
+ "assignment_expression", "assignment_operator", "expression",
+ "constant_expression", "declaration", "function_prototype",
+ "function_declarator", "function_header_with_parameters",
+ "function_header", "parameter_declarator", "parameter_declaration",
+ "parameter_qualifier", "parameter_type_specifier",
+ "init_declarator_list", "single_declaration", "fully_specified_type",
+ "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id",
+ "interpolation_qualifier", "parameter_type_qualifier", "type_qualifier",
+ "storage_qualifier", "type_specifier", "type_specifier_no_prec",
+ "type_specifier_nonarray", "basic_type_specifier_nonarray",
+ "precision_qualifier", "struct_specifier", "struct_declaration_list",
+ "struct_declaration", "struct_declarator_list", "struct_declarator",
+ "initializer", "declaration_statement", "statement", "simple_statement",
+ "compound_statement", "statement_no_new_scope",
+ "compound_statement_no_new_scope", "statement_list",
+ "expression_statement", "selection_statement",
+ "selection_rest_statement", "condition", "switch_statement",
+ "case_label", "iteration_statement", "for_init_statement",
+ "conditionopt", "for_rest_statement", "jump_statement",
+ "external_declaration", "function_definition", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+ 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,
+ 415, 416, 417, 418, 419, 420, 421, 422, 423, 424,
+ 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
+ 435, 436, 437, 438, 439, 440, 441, 442, 443, 444,
+ 445, 446, 447, 40, 41, 91, 93, 46, 44, 43,
+ 45, 33, 126, 42, 47, 37, 60, 62, 38, 94,
+ 124, 63, 58, 61, 59, 123, 125
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint16 yyr1[] =
+{
+ 0, 217, 219, 218, 220, 220, 221, 221, 221, 221,
+ 222, 222, 223, 224, 224, 225, 226, 226, 226, 226,
+ 226, 226, 227, 227, 227, 227, 227, 227, 228, 229,
+ 230, 230, 231, 231, 232, 232, 233, 233, 234, 235,
+ 235, 235, 236, 236, 236, 236, 237, 237, 237, 237,
+ 238, 238, 238, 238, 239, 239, 239, 240, 240, 240,
+ 241, 241, 241, 241, 241, 242, 242, 242, 243, 243,
+ 244, 244, 245, 245, 246, 246, 247, 247, 248, 248,
+ 249, 249, 250, 250, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 252, 252, 253, 254, 254,
+ 254, 255, 256, 256, 257, 257, 258, 259, 259, 260,
+ 260, 260, 260, 261, 261, 261, 261, 262, 263, 263,
+ 263, 263, 263, 263, 263, 264, 264, 264, 264, 264,
+ 264, 264, 264, 265, 265, 266, 267, 267, 268, 268,
+ 269, 269, 269, 270, 271, 271, 271, 271, 271, 271,
+ 271, 271, 272, 272, 272, 272, 272, 272, 272, 272,
+ 272, 273, 273, 274, 274, 274, 275, 275, 275, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 277, 277, 277, 278, 278, 279, 279, 280, 281, 281,
+ 282, 282, 283, 284, 285, 285, 286, 286, 286, 286,
+ 286, 286, 286, 287, 287, 288, 288, 289, 289, 290,
+ 290, 291, 291, 292, 293, 293, 294, 294, 295, 296,
+ 296, 297, 297, 297, 298, 298, 299, 299, 300, 300,
+ 301, 301, 301, 301, 301, 302, 302, 302, 303
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 4, 0, 3, 2, 2, 2, 2,
+ 0, 2, 5, 1, 2, 1, 1, 1, 1, 1,
+ 1, 3, 1, 4, 1, 3, 2, 2, 1, 1,
+ 1, 3, 2, 2, 2, 1, 2, 3, 2, 1,
+ 1, 1, 1, 2, 2, 2, 1, 1, 1, 1,
+ 1, 3, 3, 3, 1, 3, 3, 1, 3, 3,
+ 1, 3, 3, 3, 3, 1, 3, 3, 1, 3,
+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
+ 1, 5, 1, 3, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 3, 1, 2, 2,
+ 4, 2, 1, 1, 2, 3, 3, 2, 5, 3,
+ 2, 3, 2, 0, 1, 1, 1, 1, 1, 3,
+ 5, 6, 7, 8, 5, 1, 2, 4, 5, 6,
+ 7, 4, 2, 1, 2, 4, 1, 3, 1, 3,
+ 1, 1, 1, 1, 1, 1, 2, 1, 2, 2,
+ 3, 1, 1, 1, 1, 2, 1, 1, 2, 2,
+ 1, 1, 2, 1, 3, 4, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 5, 4, 1, 2, 3, 1, 3,
+ 1, 4, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 3, 1, 1, 2, 3, 1,
+ 2, 1, 2, 5, 3, 1, 1, 4, 5, 3,
+ 2, 5, 7, 6, 1, 1, 1, 0, 2, 3,
+ 2, 2, 2, 3, 2, 1, 1, 1, 2
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 4, 0, 0, 10, 0, 1, 2, 5, 0, 0,
+ 11, 0, 153, 152, 173, 170, 171, 172, 177, 178,
+ 179, 180, 181, 182, 183, 184, 185, 174, 175, 176,
+ 0, 156, 157, 160, 154, 142, 141, 140, 186, 187,
+ 188, 189, 190, 191, 192, 193, 194, 195, 196, 198,
+ 199, 200, 201, 203, 204, 205, 206, 207, 208, 209,
+ 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
+ 0, 169, 168, 151, 222, 221, 220, 0, 0, 0,
+ 0, 0, 0, 197, 202, 277, 3, 276, 0, 0,
+ 103, 113, 0, 118, 125, 145, 147, 0, 144, 133,
+ 161, 163, 166, 0, 167, 13, 275, 0, 158, 159,
+ 155, 0, 0, 132, 0, 149, 0, 6, 7, 8,
+ 9, 0, 14, 98, 0, 278, 101, 113, 143, 114,
+ 115, 116, 104, 0, 113, 0, 99, 126, 146, 148,
+ 134, 0, 162, 0, 0, 0, 0, 225, 150, 0,
+ 138, 0, 136, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 15, 19, 17, 18, 20, 41,
+ 0, 0, 0, 46, 47, 48, 49, 251, 0, 247,
+ 16, 22, 42, 24, 29, 30, 0, 0, 35, 0,
+ 50, 0, 54, 57, 60, 65, 68, 70, 72, 74,
+ 76, 78, 80, 82, 95, 0, 233, 0, 133, 236,
+ 249, 235, 234, 0, 237, 238, 239, 240, 241, 242,
+ 105, 110, 112, 117, 0, 119, 106, 0, 0, 164,
+ 50, 97, 0, 39, 12, 0, 230, 0, 228, 224,
+ 226, 100, 0, 135, 0, 271, 270, 0, 0, 0,
+ 274, 272, 0, 0, 0, 260, 0, 43, 44, 0,
+ 243, 0, 26, 27, 0, 0, 33, 32, 0, 169,
+ 36, 38, 85, 86, 88, 87, 90, 91, 92, 93,
+ 94, 89, 84, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 252, 248, 250, 107,
+ 109, 111, 0, 0, 127, 0, 232, 131, 165, 223,
+ 0, 0, 227, 139, 137, 0, 265, 264, 267, 0,
+ 273, 0, 259, 151, 256, 0, 0, 21, 244, 0,
+ 28, 25, 31, 37, 83, 51, 52, 53, 55, 56,
+ 58, 59, 63, 64, 61, 62, 66, 67, 69, 71,
+ 73, 75, 77, 79, 0, 96, 0, 120, 0, 124,
+ 0, 128, 0, 229, 0, 266, 0, 0, 0, 0,
+ 0, 0, 23, 0, 0, 0, 121, 129, 0, 231,
+ 0, 268, 0, 255, 253, 258, 0, 246, 261, 245,
+ 81, 108, 122, 0, 130, 0, 269, 263, 0, 257,
+ 123, 262, 254
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 2, 9, 3, 85, 6, 10, 86, 180, 181,
+ 182, 339, 183, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 194, 195, 196, 197, 198, 199, 200,
+ 201, 202, 203, 204, 283, 205, 232, 206, 207, 89,
+ 90, 91, 221, 132, 133, 222, 92, 93, 94, 95,
+ 151, 152, 96, 134, 97, 98, 233, 100, 101, 102,
+ 103, 104, 146, 147, 237, 238, 317, 209, 210, 211,
+ 212, 398, 399, 213, 214, 215, 394, 336, 216, 217,
+ 218, 328, 376, 377, 219, 105, 106
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -350
+static const yytype_int16 yypact[] =
+{
+ -78, -56, 54, -350, -52, -350, -37, -350, 8, 3302,
+ -350, -26, -350, -350, -350, -350, -350, -350, -350, -350,
+ -350, -350, -350, -350, -350, -350, -350, -350, -350, -350,
+ 88, -350, -350, -350, -350, -350, -350, -350, -350, -350,
+ -350, -350, -350, -350, -350, -350, -350, -350, -350, -350,
+ -350, -350, -350, -350, -350, -350, -350, -350, -350, -350,
+ -350, -350, -350, -350, -350, -350, -350, -350, -350, -350,
+ -66, -350, -350, 42, -350, -350, -350, 70, -4, 10,
+ 29, 34, -79, -350, -350, -350, 3302, -350, -19, -24,
+ -69, 5, -154, -350, 102, 16, 16, 3490, -350, -350,
+ -350, 18, -350, 3562, -350, -350, -350, 108, -350, -350,
+ -350, -8, 3490, -350, 16, -350, 3562, -350, -350, -350,
+ -350, 138, -350, -350, 387, -350, -350, 24, -350, -350,
+ -350, -350, -350, 3490, 147, 141, -350, -166, -350, -350,
+ -350, 2387, -350, 106, 3490, 144, 1772, -350, -350, 7,
+ 11, -87, -350, 14, 15, 1243, 30, 32, 20, 2004,
+ 37, 2936, 25, 39, -65, -350, -350, -350, -350, -350,
+ 2936, 2936, 2936, -350, -350, -350, -350, -350, 601, -350,
+ -350, -350, -59, -350, -350, -350, 28, -82, 3119, 43,
+ -30, 2936, -11, -2, 118, -74, 114, 35, 31, 36,
+ 148, 152, -77, -350, -350, -115, -350, 40, 52, -350,
+ -350, -350, -350, 815, -350, -350, -350, -350, -350, -350,
+ -350, -350, -350, 172, 3490, -180, -350, 2570, 2936, -350,
+ -350, -350, 53, -350, -350, 1888, 55, -113, -350, -350,
+ -350, -350, 173, -350, 138, -350, -350, 178, 1656, 2936,
+ -350, -350, -108, 2936, -161, -350, 2204, -350, -350, -68,
+ -350, 1029, -350, -350, 2936, 3418, -350, -350, 2936, 61,
+ -350, -350, -350, -350, -350, -350, -350, -350, -350, -350,
+ -350, -350, -350, 2936, -350, 2936, 2936, 2936, 2936, 2936,
+ 2936, 2936, 2936, 2936, 2936, 2936, 2936, 2936, 2936, 2936,
+ 2936, 2936, 2936, 2936, 2936, 2936, -350, -350, -350, 63,
+ -350, -350, 2753, 2936, 46, 60, -350, -350, -350, -350,
+ 2936, 144, -350, -350, -350, 67, -350, -350, 2204, -55,
+ -350, -54, -350, 238, 65, 188, 71, -350, -350, 72,
+ 65, 73, -350, -350, -350, -350, -350, -350, -11, -11,
+ -2, -2, 118, 118, 118, 118, -74, -74, 114, 35,
+ 31, 36, 148, 152, -157, -350, 2936, 56, 83, -350,
+ 2936, 68, 84, -350, 2936, -350, 69, 90, 1243, 74,
+ 77, 1456, -350, 2936, 86, 2936, 79, -350, 2936, -350,
+ -53, 2936, 1456, 255, -350, -350, 2936, -350, -350, -350,
+ -350, -350, -350, 2936, -350, 80, 65, -350, 1243, -350,
+ -350, -350, -350
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -350, -350, -350, -350, -350, -350, -350, -350, -350, -350,
+ -350, -350, -350, -350, 22, -350, -350, -350, -350, -135,
+ -350, -83, -81, -104, -85, -13, -6, -5, -3, -1,
+ -7, -350, -133, -97, -350, -156, -193, 9, 12, -350,
+ -350, -350, 76, 170, 168, 81, -350, -350, -239, -350,
+ -350, 59, -71, -350, -350, -72, -9, 1, -350, -350,
+ 227, -350, 163, -139, -350, -12, -283, 62, -151, -349,
+ -67, -84, 223, 135, 66, -350, -350, -10, -350, -350,
+ -350, -350, -350, -350, -350, 229, -350
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -169
+static const yytype_int16 yytable[] =
+{
+ 99, 115, 114, 252, 247, 254, 230, 240, 231, 128,
+ 111, -168, 292, 293, 303, 312, 259, 335, 87, 12,
+ 13, 88, 4, 138, 139, 262, 263, 226, 128, 227,
+ 369, 1, 397, 313, 315, 257, 258, 305, 129, 130,
+ 131, 305, 148, 397, 135, 12, 13, 228, 30, 31,
+ 32, 332, 33, 34, 5, 383, 284, 129, 130, 131,
+ 136, 7, 308, 272, 273, 274, 275, 276, 277, 278,
+ 279, 280, 281, 8, 30, 31, 32, 99, 33, 34,
+ 35, 36, 37, 305, 11, 321, 107, 387, 140, 335,
+ 305, 270, 230, 329, 231, 87, 240, 331, 88, 306,
+ 334, 322, 402, 145, 142, 404, 330, 243, 340, 117,
+ 308, 244, 267, 409, 121, 208, 268, 149, 113, 368,
+ 410, 108, 109, 118, 223, 110, 337, 372, -40, 127,
+ 305, 316, 294, 295, 304, 145, 264, 145, 265, 378,
+ 379, 405, 119, 305, 305, 305, 208, 120, 364, 112,
+ 345, 346, 347, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 208,
+ 126, 343, 334, 384, 74, 75, 76, 230, 137, 231,
+ 129, 130, 131, 282, 143, 230, 344, 231, 352, 353,
+ 354, 355, 285, 286, 287, 123, 124, 288, 289, -102,
+ 290, 291, 296, 297, 208, 348, 349, 144, 365, 350,
+ 351, 356, 357, 141, 150, 223, 316, 225, 390, 234,
+ 236, 241, 266, 248, 242, 249, 145, 393, 245, 246,
+ 253, 230, 256, 231, 250, 406, 271, 255, 301, 208,
+ 299, 12, 13, 298, 302, -39, 300, 208, 309, 318,
+ 320, 323, 208, 325, 123, -34, 371, 412, 366, 370,
+ 374, 115, 114, 305, 380, 381, -40, 408, 382, 385,
+ 30, 31, 32, 316, 33, 34, 35, 36, 37, 386,
+ 389, 388, 401, 391, 392, 358, 400, 342, 316, 178,
+ 396, 316, 403, 359, 411, 360, 363, 220, 361, 316,
+ 310, 362, 224, 324, 116, 311, 316, 235, 407, 373,
+ 326, 125, 395, 261, 327, 122, 0, 0, 375, 208,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 208,
+ 0, 0, 208, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 208, 0, 0, 0, 0, 0, 0,
+ 12, 13, 14, 15, 16, 17, 153, 154, 155, 208,
+ 156, 157, 158, 159, 160, 161, 162, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 0, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 163, 164, 165, 166, 167, 168, 169, 0,
+ 0, 170, 171, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 73, 74, 75, 76, 0, 77, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 82, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 83, 0, 84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 172, 0, 0, 0, 0, 0, 173, 174, 175, 176,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 177, 178, 179, 12, 13, 14, 15, 16, 17,
+ 153, 154, 155, 0, 156, 157, 158, 159, 160, 161,
+ 162, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 0, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 163, 164, 165, 166,
+ 167, 168, 169, 0, 0, 170, 171, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 73, 74, 75, 76, 0, 77,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 82, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 83, 0, 84, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 172, 0, 0, 0, 0, 0,
+ 173, 174, 175, 176, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 177, 178, 260, 12, 13,
+ 14, 15, 16, 17, 153, 154, 155, 0, 156, 157,
+ 158, 159, 160, 161, 162, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 0, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 163, 164, 165, 166, 167, 168, 169, 0, 0, 170,
+ 171, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 73, 74,
+ 75, 76, 0, 77, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 82, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 83,
+ 0, 84, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 172, 0,
+ 0, 0, 0, 0, 173, 174, 175, 176, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 177,
+ 178, 307, 12, 13, 14, 15, 16, 17, 153, 154,
+ 155, 0, 156, 157, 158, 159, 160, 161, 162, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 0, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 163, 164, 165, 166, 167, 168,
+ 169, 0, 0, 170, 171, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 73, 74, 75, 76, 0, 77, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 82,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 83, 0, 84, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 172, 0, 0, 0, 0, 0, 173, 174,
+ 175, 176, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 177, 178, 338, 12, 13, 14, 15,
+ 16, 17, 153, 154, 155, 0, 156, 157, 158, 159,
+ 160, 161, 162, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 0, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 163, 164,
+ 165, 166, 167, 168, 169, 0, 0, 170, 171, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 73, 74, 75, 76,
+ 0, 77, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 82, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 83, 0, 84,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 172, 0, 0, 0,
+ 0, 0, 173, 174, 175, 176, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 177, 178, 12,
+ 13, 14, 15, 16, 17, 153, 154, 155, 0, 156,
+ 157, 158, 159, 160, 161, 162, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 0, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 163, 164, 165, 166, 167, 168, 169, 0, 0,
+ 170, 171, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,
+ 74, 75, 76, 0, 77, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 82, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 83, 0, 84, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 172,
+ 0, 0, 0, 0, 0, 173, 174, 175, 176, 12,
+ 13, 14, 15, 16, 17, 0, 0, 0, 0, 0,
+ 177, 124, 0, 0, 0, 0, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 0, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 0, 164, 165, 166, 167, 168, 169, 0, 0,
+ 170, 171, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,
+ 74, 75, 76, 0, 77, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 82, 14, 15, 16,
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 0, 0, 0, 0, 0, 0,
+ 83, 0, 84, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 0, 72, 172,
+ 0, 0, 0, 0, 0, 173, 174, 175, 176, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 177, 0, 0, 0, 0, 0, 74, 75, 76, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 14, 15, 16, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 0, 0, 0, 0, 0, 0, 83, 0, 84, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 0, 72, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 239, 0,
+ 0, 0, 74, 75, 76, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+ 15, 16, 17, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 0, 0, 0, 0,
+ 0, 0, 83, 0, 84, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 0,
+ 164, 165, 166, 167, 168, 169, 0, 0, 170, 171,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 319, 0, 0, 0, 74, 75,
+ 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 83, 0,
+ 84, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 172, 0, 0,
+ 0, 0, 0, 173, 174, 175, 176, 12, 13, 14,
+ 15, 16, 17, 0, 0, 0, 0, 0, 251, 0,
+ 0, 0, 0, 0, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 0,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 0,
+ 164, 165, 166, 167, 168, 169, 0, 0, 170, 171,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 333, 74, 75,
+ 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 82, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 83, 0,
+ 84, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 14, 15, 16, 17, 0, 172, 0, 0,
+ 0, 0, 0, 173, 174, 175, 176, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 0, 164, 165, 166, 167, 168, 169, 0,
+ 0, 170, 171, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 74, 75, 76, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 83, 0, 84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 14, 15, 16, 17, 0,
+ 172, 0, 0, 229, 0, 0, 173, 174, 175, 176,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 0, 164, 165, 166, 167,
+ 168, 169, 0, 0, 170, 171, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 74, 75, 76, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 83, 0, 84, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 14, 15,
+ 16, 17, 0, 172, 0, 0, 314, 0, 0, 173,
+ 174, 175, 176, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 0, 164,
+ 165, 166, 167, 168, 169, 0, 0, 170, 171, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 74, 75, 76,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 83, 0, 84,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 14, 15, 16, 17, 0, 172, 0, 0, 367,
+ 0, 0, 173, 174, 175, 176, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 0, 164, 165, 166, 167, 168, 169, 0, 0,
+ 170, 171, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 74, 75, 76, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 83, 0, 84, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 14, 15, 16, 17, 0, 172,
+ 0, 0, 0, 0, 0, 173, 174, 175, 176, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 269, 0, 164, 165, 166, 167, 168,
+ 169, 0, 0, 170, 171, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 74, 75, 76, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 83, 0, 84, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 12, 13, 14, 15, 16,
+ 17, 0, 172, 0, 0, 0, 0, 0, 173, 174,
+ 175, 176, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 0, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 0, 72, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 73, 74, 75, 76, 0,
+ 77, 0, 0, 0, 0, 0, 0, 0, 78, 79,
+ 80, 81, 82, 14, 15, 16, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 0, 0, 0, 0, 0, 0, 83, 0, 84, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 0, 341, 14, 15, 16, 17, 169,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 74, 75, 76, 0, 0, 0, 0, 0,
+ 0, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 0, 72, 14, 15, 16,
+ 17, 0, 83, 0, 84, 0, 0, 0, 0, 0,
+ 0, 0, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 74, 75, 76, 0, 0, 0,
+ 0, 0, 0, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 0, 72, 0,
+ 0, 0, 0, 0, 83, 0, 84, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 83, 0, 84
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 9, 73, 73, 159, 155, 161, 141, 146, 141, 4,
+ 76, 76, 86, 87, 91, 195, 172, 256, 9, 3,
+ 4, 9, 78, 95, 96, 84, 85, 193, 4, 195,
+ 313, 109, 381, 213, 227, 170, 171, 198, 33, 34,
+ 35, 198, 114, 392, 198, 3, 4, 213, 32, 33,
+ 34, 212, 36, 37, 0, 212, 191, 33, 34, 35,
+ 214, 113, 213, 93, 94, 95, 96, 97, 98, 99,
+ 100, 101, 102, 110, 32, 33, 34, 86, 36, 37,
+ 38, 39, 40, 198, 76, 198, 112, 370, 97, 328,
+ 198, 188, 227, 249, 227, 86, 235, 253, 86, 214,
+ 256, 214, 385, 112, 103, 388, 214, 194, 264, 113,
+ 261, 198, 194, 396, 193, 124, 198, 116, 76, 312,
+ 403, 33, 34, 113, 133, 37, 194, 320, 193, 198,
+ 198, 228, 206, 207, 211, 144, 195, 146, 197, 194,
+ 194, 194, 113, 198, 198, 198, 155, 113, 304, 215,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 178,
+ 194, 268, 328, 366, 104, 105, 106, 312, 76, 312,
+ 33, 34, 35, 213, 76, 320, 283, 320, 292, 293,
+ 294, 295, 203, 204, 205, 214, 215, 199, 200, 194,
+ 82, 83, 88, 89, 213, 288, 289, 215, 305, 290,
+ 291, 296, 297, 195, 76, 224, 313, 76, 374, 113,
+ 76, 214, 194, 193, 213, 193, 235, 378, 214, 214,
+ 193, 366, 193, 366, 214, 391, 193, 212, 90, 248,
+ 209, 3, 4, 208, 92, 193, 210, 256, 76, 196,
+ 195, 78, 261, 75, 214, 194, 196, 408, 195, 213,
+ 193, 333, 333, 198, 76, 194, 193, 12, 196, 213,
+ 32, 33, 34, 370, 36, 37, 38, 39, 40, 196,
+ 196, 213, 196, 214, 194, 298, 383, 265, 385, 215,
+ 213, 388, 213, 299, 214, 300, 303, 127, 301, 396,
+ 224, 302, 134, 244, 77, 224, 403, 144, 392, 321,
+ 248, 88, 379, 178, 248, 86, -1, -1, 328, 328,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 378,
+ -1, -1, 381, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 392, -1, -1, -1, -1, -1, -1,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 408,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, -1, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, -1,
+ -1, 84, 85, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 103, 104, 105, 106, -1, 108, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 120, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 154, -1, 156, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 193, -1, -1, -1, -1, -1, 199, 200, 201, 202,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 214, 215, 216, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, -1, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, -1, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, -1, -1, 84, 85, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 103, 104, 105, 106, -1, 108,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 120, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 154, -1, 156, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 193, -1, -1, -1, -1, -1,
+ 199, 200, 201, 202, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 214, 215, 216, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, -1, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ -1, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, -1, -1, 84,
+ 85, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 103, 104,
+ 105, 106, -1, 108, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 120, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 154,
+ -1, 156, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 193, -1,
+ -1, -1, -1, -1, 199, 200, 201, 202, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 214,
+ 215, 216, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, -1, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, -1, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, -1, -1, 84, 85, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 103, 104, 105, 106, -1, 108, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 120,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 154, -1, 156, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 193, -1, -1, -1, -1, -1, 199, 200,
+ 201, 202, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 214, 215, 216, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, -1, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, -1, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, -1, -1, 84, 85, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 103, 104, 105, 106,
+ -1, 108, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 120, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 154, -1, 156,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 193, -1, -1, -1,
+ -1, -1, 199, 200, 201, 202, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 214, 215, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, -1, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, -1, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, -1, -1,
+ 84, 85, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 103,
+ 104, 105, 106, -1, 108, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 120, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 154, -1, 156, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 193,
+ -1, -1, -1, -1, -1, 199, 200, 201, 202, 3,
+ 4, 5, 6, 7, 8, -1, -1, -1, -1, -1,
+ 214, 215, -1, -1, -1, -1, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, -1, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, -1, 76, 77, 78, 79, 80, 81, -1, -1,
+ 84, 85, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 103,
+ 104, 105, 106, -1, 108, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 120, 5, 6, 7,
+ 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, -1, -1, -1, -1, -1, -1,
+ 154, -1, 156, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, -1, 76, 193,
+ -1, -1, -1, -1, -1, 199, 200, 201, 202, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 214, -1, -1, -1, -1, -1, 104, 105, 106, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 5, 6, 7, 8, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ -1, -1, -1, -1, -1, -1, 154, -1, 156, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, -1, 76, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 216, -1,
+ -1, -1, 104, 105, 106, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 5,
+ 6, 7, 8, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
+ -1, -1, 154, -1, 156, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, -1,
+ 76, 77, 78, 79, 80, 81, -1, -1, 84, 85,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 216, -1, -1, -1, 104, 105,
+ 106, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 154, -1,
+ 156, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 193, -1, -1,
+ -1, -1, -1, 199, 200, 201, 202, 3, 4, 5,
+ 6, 7, 8, -1, -1, -1, -1, -1, 214, -1,
+ -1, -1, -1, -1, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, -1,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, -1,
+ 76, 77, 78, 79, 80, 81, -1, -1, 84, 85,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 103, 104, 105,
+ 106, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 120, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 154, -1,
+ 156, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 5, 6, 7, 8, -1, 193, -1, -1,
+ -1, -1, -1, 199, 200, 201, 202, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, -1, 76, 77, 78, 79, 80, 81, -1,
+ -1, 84, 85, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 104, 105, 106, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 154, -1, 156, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 5, 6, 7, 8, -1,
+ 193, -1, -1, 196, -1, -1, 199, 200, 201, 202,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, -1, 76, 77, 78, 79,
+ 80, 81, -1, -1, 84, 85, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 104, 105, 106, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 154, -1, 156, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 5, 6,
+ 7, 8, -1, 193, -1, -1, 196, -1, -1, 199,
+ 200, 201, 202, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74, -1, 76,
+ 77, 78, 79, 80, 81, -1, -1, 84, 85, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 104, 105, 106,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 154, -1, 156,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 5, 6, 7, 8, -1, 193, -1, -1, 196,
+ -1, -1, 199, 200, 201, 202, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, -1, 76, 77, 78, 79, 80, 81, -1, -1,
+ 84, 85, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 104, 105, 106, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 154, -1, 156, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 5, 6, 7, 8, -1, 193,
+ -1, -1, -1, -1, -1, 199, 200, 201, 202, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, -1, 76, 77, 78, 79, 80,
+ 81, -1, -1, 84, 85, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 104, 105, 106, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 154, -1, 156, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 3, 4, 5, 6, 7,
+ 8, -1, 193, -1, -1, -1, -1, -1, 199, 200,
+ 201, 202, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, -1, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, -1, 76, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 103, 104, 105, 106, -1,
+ 108, -1, -1, -1, -1, -1, -1, -1, 116, 117,
+ 118, 119, 120, 5, 6, 7, 8, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ -1, -1, -1, -1, -1, -1, 154, -1, 156, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, -1, 76, 5, 6, 7, 8, 81,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 104, 105, 106, -1, -1, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, -1, 76, 5, 6, 7,
+ 8, -1, 154, -1, 156, -1, -1, -1, -1, -1,
+ -1, -1, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 104, 105, 106, -1, -1, -1,
+ -1, -1, -1, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, -1, 76, -1,
+ -1, -1, -1, -1, 154, -1, 156, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 154, -1, 156
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint16 yystos[] =
+{
+ 0, 109, 218, 220, 78, 0, 222, 113, 110, 219,
+ 223, 76, 3, 4, 5, 6, 7, 8, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 76, 103, 104, 105, 106, 108, 116, 117,
+ 118, 119, 120, 154, 156, 221, 224, 254, 255, 256,
+ 257, 258, 263, 264, 265, 266, 269, 271, 272, 273,
+ 274, 275, 276, 277, 278, 302, 303, 112, 33, 34,
+ 37, 76, 215, 76, 269, 272, 277, 113, 113, 113,
+ 113, 193, 302, 214, 215, 289, 194, 198, 4, 33,
+ 34, 35, 260, 261, 270, 198, 214, 76, 272, 272,
+ 273, 195, 274, 76, 215, 273, 279, 280, 272, 274,
+ 76, 267, 268, 9, 10, 11, 13, 14, 15, 16,
+ 17, 18, 19, 75, 76, 77, 78, 79, 80, 81,
+ 84, 85, 193, 199, 200, 201, 202, 214, 215, 216,
+ 225, 226, 227, 229, 230, 231, 232, 233, 234, 235,
+ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
+ 246, 247, 248, 249, 250, 252, 254, 255, 273, 284,
+ 285, 286, 287, 290, 291, 292, 295, 296, 297, 301,
+ 260, 259, 262, 273, 261, 76, 193, 195, 213, 196,
+ 236, 249, 253, 273, 113, 279, 76, 281, 282, 216,
+ 280, 214, 213, 194, 198, 214, 214, 285, 193, 193,
+ 214, 214, 252, 193, 252, 212, 193, 236, 236, 252,
+ 216, 290, 84, 85, 195, 197, 194, 194, 198, 74,
+ 250, 193, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 213, 251, 236, 203, 204, 205, 199, 200,
+ 82, 83, 86, 87, 206, 207, 88, 89, 208, 209,
+ 210, 90, 92, 91, 211, 198, 214, 216, 285, 76,
+ 259, 262, 195, 213, 196, 253, 250, 283, 196, 216,
+ 195, 198, 214, 78, 268, 75, 284, 291, 298, 252,
+ 214, 252, 212, 103, 252, 265, 294, 194, 216, 228,
+ 252, 76, 231, 250, 250, 236, 236, 236, 238, 238,
+ 239, 239, 240, 240, 240, 240, 241, 241, 242, 243,
+ 244, 245, 246, 247, 252, 250, 195, 196, 253, 283,
+ 213, 196, 253, 282, 193, 294, 299, 300, 194, 194,
+ 76, 194, 196, 212, 253, 213, 196, 283, 213, 196,
+ 252, 214, 194, 285, 293, 287, 213, 286, 288, 289,
+ 250, 196, 283, 213, 283, 194, 252, 288, 12, 283,
+ 283, 214, 285
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. However,
+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated
+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+ discussed. */
+
+#define YYFAIL goto yyerrlab
+#if defined YYFAIL
+ /* This is here to suppress warnings from the GCC cpp's
+ -Wunused-macros. Normally we don't worry about that warning, but
+ some users do, and we want to make it easy for users to remove
+ YYFAIL uses, which will produce warnings from Bison 2.5. */
+#endif
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, scanner)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location, state); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct _mesa_glsl_parse_state *state;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+ YYUSE (state);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct _mesa_glsl_parse_state *state;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct _mesa_glsl_parse_state *state)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, state)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+ struct _mesa_glsl_parse_state *state;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) , state);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule, state); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct _mesa_glsl_parse_state *state)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, state)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+ struct _mesa_glsl_parse_state *state;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ YYUSE (state);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+/* Prevent warnings from -Wmissing-prototypes. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (struct _mesa_glsl_parse_state *state);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse. |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (struct _mesa_glsl_parse_state *state)
+#else
+int
+yyparse (state)
+ struct _mesa_glsl_parse_state *state;
+#endif
+#endif
+{
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc;
+
+ /* Number of syntax errors so far. */
+ int yynerrs;
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[3];
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yyls = yylsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+ yyssp = yyss;
+ yyvsp = yyvs;
+ yylsp = yyls;
+
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+/* User initialization code. */
+
+/* Line 1251 of yacc.c */
+#line 41 "glsl_parser.ypp"
+{
+ yylloc.first_line = 1;
+ yylloc.first_column = 1;
+ yylloc.last_line = 1;
+ yylloc.last_column = 1;
+ yylloc.source = 0;
+}
+
+/* Line 1251 of yacc.c */
+#line 2635 "glsl_parser.cpp"
+ yylsp[0] = yylloc;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+
+/* Line 1464 of yacc.c */
+#line 212 "glsl_parser.ypp"
+ {
+ _mesa_glsl_initialize_types(state);
+ ;}
+ break;
+
+ case 5:
+
+/* Line 1464 of yacc.c */
+#line 221 "glsl_parser.ypp"
+ {
+ switch ((yyvsp[(2) - (3)].n)) {
+ case 100:
+ state->es_shader = true;
+ case 110:
+ case 120:
+ case 130:
+ /* FINISHME: Check against implementation support versions. */
+ state->language_version = (yyvsp[(2) - (3)].n);
+ break;
+ default:
+ _mesa_glsl_error(& (yylsp[(2) - (3)]), state, "Shading language version"
+ "%u is not supported\n", (yyvsp[(2) - (3)].n));
+ break;
+ }
+ ;}
+ break;
+
+ case 12:
+
+/* Line 1464 of yacc.c */
+#line 253 "glsl_parser.ypp"
+ {
+ if (!_mesa_glsl_process_extension((yyvsp[(2) - (5)].identifier), & (yylsp[(2) - (5)]), (yyvsp[(4) - (5)].identifier), & (yylsp[(4) - (5)]), state)) {
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 13:
+
+/* Line 1464 of yacc.c */
+#line 262 "glsl_parser.ypp"
+ {
+ /* FINISHME: The NULL test is only required because 'precision'
+ * FINISHME: statements are not yet supported.
+ */
+ if ((yyvsp[(1) - (1)].node) != NULL)
+ state->translation_unit.push_tail(& (yyvsp[(1) - (1)].node)->link);
+ ;}
+ break;
+
+ case 14:
+
+/* Line 1464 of yacc.c */
+#line 270 "glsl_parser.ypp"
+ {
+ /* FINISHME: The NULL test is only required because 'precision'
+ * FINISHME: statements are not yet supported.
+ */
+ if ((yyvsp[(2) - (2)].node) != NULL)
+ state->translation_unit.push_tail(& (yyvsp[(2) - (2)].node)->link);
+ ;}
+ break;
+
+ case 16:
+
+/* Line 1464 of yacc.c */
+#line 285 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->primary_expression.identifier = (yyvsp[(1) - (1)].identifier);
+ ;}
+ break;
+
+ case 17:
+
+/* Line 1464 of yacc.c */
+#line 292 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->primary_expression.int_constant = (yyvsp[(1) - (1)].n);
+ ;}
+ break;
+
+ case 18:
+
+/* Line 1464 of yacc.c */
+#line 299 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->primary_expression.uint_constant = (yyvsp[(1) - (1)].n);
+ ;}
+ break;
+
+ case 19:
+
+/* Line 1464 of yacc.c */
+#line 306 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->primary_expression.float_constant = (yyvsp[(1) - (1)].real);
+ ;}
+ break;
+
+ case 20:
+
+/* Line 1464 of yacc.c */
+#line 313 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->primary_expression.bool_constant = (yyvsp[(1) - (1)].n);
+ ;}
+ break;
+
+ case 21:
+
+/* Line 1464 of yacc.c */
+#line 320 "glsl_parser.ypp"
+ {
+ (yyval.expression) = (yyvsp[(2) - (3)].expression);
+ ;}
+ break;
+
+ case 23:
+
+/* Line 1464 of yacc.c */
+#line 328 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_array_index, (yyvsp[(1) - (4)].expression), (yyvsp[(3) - (4)].expression), NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 24:
+
+/* Line 1464 of yacc.c */
+#line 334 "glsl_parser.ypp"
+ {
+ (yyval.expression) = (yyvsp[(1) - (1)].expression);
+ ;}
+ break;
+
+ case 25:
+
+/* Line 1464 of yacc.c */
+#line 338 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->primary_expression.identifier = (yyvsp[(3) - (3)].identifier);
+ ;}
+ break;
+
+ case 26:
+
+/* Line 1464 of yacc.c */
+#line 345 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_post_inc, (yyvsp[(1) - (2)].expression), NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 27:
+
+/* Line 1464 of yacc.c */
+#line 351 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_post_dec, (yyvsp[(1) - (2)].expression), NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 31:
+
+/* Line 1464 of yacc.c */
+#line 369 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 36:
+
+/* Line 1464 of yacc.c */
+#line 388 "glsl_parser.ypp"
+ {
+ (yyval.expression) = (yyvsp[(1) - (2)].expression);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->expressions.push_tail(& (yyvsp[(2) - (2)].expression)->link);
+ ;}
+ break;
+
+ case 37:
+
+/* Line 1464 of yacc.c */
+#line 394 "glsl_parser.ypp"
+ {
+ (yyval.expression) = (yyvsp[(1) - (3)].expression);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link);
+ ;}
+ break;
+
+ case 39:
+
+/* Line 1464 of yacc.c */
+#line 410 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_function_expression((yyvsp[(1) - (1)].type_specifier));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 40:
+
+/* Line 1464 of yacc.c */
+#line 416 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier));
+ (yyval.expression) = new(ctx) ast_function_expression(callee);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 41:
+
+/* Line 1464 of yacc.c */
+#line 423 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier));
+ (yyval.expression) = new(ctx) ast_function_expression(callee);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 43:
+
+/* Line 1464 of yacc.c */
+#line 435 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_pre_inc, (yyvsp[(2) - (2)].expression), NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 44:
+
+/* Line 1464 of yacc.c */
+#line 441 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_pre_dec, (yyvsp[(2) - (2)].expression), NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 45:
+
+/* Line 1464 of yacc.c */
+#line 447 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].expression), NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 46:
+
+/* Line 1464 of yacc.c */
+#line 456 "glsl_parser.ypp"
+ { (yyval.n) = ast_plus; ;}
+ break;
+
+ case 47:
+
+/* Line 1464 of yacc.c */
+#line 457 "glsl_parser.ypp"
+ { (yyval.n) = ast_neg; ;}
+ break;
+
+ case 48:
+
+/* Line 1464 of yacc.c */
+#line 458 "glsl_parser.ypp"
+ { (yyval.n) = ast_logic_not; ;}
+ break;
+
+ case 49:
+
+/* Line 1464 of yacc.c */
+#line 459 "glsl_parser.ypp"
+ { (yyval.n) = ast_bit_not; ;}
+ break;
+
+ case 51:
+
+/* Line 1464 of yacc.c */
+#line 465 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_mul, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 52:
+
+/* Line 1464 of yacc.c */
+#line 471 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_div, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 53:
+
+/* Line 1464 of yacc.c */
+#line 477 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_mod, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 55:
+
+/* Line 1464 of yacc.c */
+#line 487 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_add, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 56:
+
+/* Line 1464 of yacc.c */
+#line 493 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_sub, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 58:
+
+/* Line 1464 of yacc.c */
+#line 503 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_lshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 59:
+
+/* Line 1464 of yacc.c */
+#line 509 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_rshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 61:
+
+/* Line 1464 of yacc.c */
+#line 519 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_less, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 62:
+
+/* Line 1464 of yacc.c */
+#line 525 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_greater, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 63:
+
+/* Line 1464 of yacc.c */
+#line 531 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_lequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 64:
+
+/* Line 1464 of yacc.c */
+#line 537 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_gequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 66:
+
+/* Line 1464 of yacc.c */
+#line 547 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_equal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 67:
+
+/* Line 1464 of yacc.c */
+#line 553 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_nequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 69:
+
+/* Line 1464 of yacc.c */
+#line 563 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 71:
+
+/* Line 1464 of yacc.c */
+#line 573 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 73:
+
+/* Line 1464 of yacc.c */
+#line 583 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 75:
+
+/* Line 1464 of yacc.c */
+#line 593 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 77:
+
+/* Line 1464 of yacc.c */
+#line 603 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 79:
+
+/* Line 1464 of yacc.c */
+#line 613 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 81:
+
+/* Line 1464 of yacc.c */
+#line 623 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression(ast_conditional, (yyvsp[(1) - (5)].expression), (yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].expression));
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 83:
+
+/* Line 1464 of yacc.c */
+#line 633 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.expression) = new(ctx) ast_expression((yyvsp[(2) - (3)].n), (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL);
+ (yyval.expression)->set_location(yylloc);
+ ;}
+ break;
+
+ case 84:
+
+/* Line 1464 of yacc.c */
+#line 641 "glsl_parser.ypp"
+ { (yyval.n) = ast_assign; ;}
+ break;
+
+ case 85:
+
+/* Line 1464 of yacc.c */
+#line 642 "glsl_parser.ypp"
+ { (yyval.n) = ast_mul_assign; ;}
+ break;
+
+ case 86:
+
+/* Line 1464 of yacc.c */
+#line 643 "glsl_parser.ypp"
+ { (yyval.n) = ast_div_assign; ;}
+ break;
+
+ case 87:
+
+/* Line 1464 of yacc.c */
+#line 644 "glsl_parser.ypp"
+ { (yyval.n) = ast_mod_assign; ;}
+ break;
+
+ case 88:
+
+/* Line 1464 of yacc.c */
+#line 645 "glsl_parser.ypp"
+ { (yyval.n) = ast_add_assign; ;}
+ break;
+
+ case 89:
+
+/* Line 1464 of yacc.c */
+#line 646 "glsl_parser.ypp"
+ { (yyval.n) = ast_sub_assign; ;}
+ break;
+
+ case 90:
+
+/* Line 1464 of yacc.c */
+#line 647 "glsl_parser.ypp"
+ { (yyval.n) = ast_ls_assign; ;}
+ break;
+
+ case 91:
+
+/* Line 1464 of yacc.c */
+#line 648 "glsl_parser.ypp"
+ { (yyval.n) = ast_rs_assign; ;}
+ break;
+
+ case 92:
+
+/* Line 1464 of yacc.c */
+#line 649 "glsl_parser.ypp"
+ { (yyval.n) = ast_and_assign; ;}
+ break;
+
+ case 93:
+
+/* Line 1464 of yacc.c */
+#line 650 "glsl_parser.ypp"
+ { (yyval.n) = ast_xor_assign; ;}
+ break;
+
+ case 94:
+
+/* Line 1464 of yacc.c */
+#line 651 "glsl_parser.ypp"
+ { (yyval.n) = ast_or_assign; ;}
+ break;
+
+ case 95:
+
+/* Line 1464 of yacc.c */
+#line 656 "glsl_parser.ypp"
+ {
+ (yyval.expression) = (yyvsp[(1) - (1)].expression);
+ ;}
+ break;
+
+ case 96:
+
+/* Line 1464 of yacc.c */
+#line 660 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ if ((yyvsp[(1) - (3)].expression)->oper != ast_sequence) {
+ (yyval.expression) = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL);
+ (yyval.expression)->set_location(yylloc);
+ (yyval.expression)->expressions.push_tail(& (yyvsp[(1) - (3)].expression)->link);
+ } else {
+ (yyval.expression) = (yyvsp[(1) - (3)].expression);
+ }
+
+ (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link);
+ ;}
+ break;
+
+ case 98:
+
+/* Line 1464 of yacc.c */
+#line 680 "glsl_parser.ypp"
+ {
+ (yyval.node) = (yyvsp[(1) - (2)].function);
+ ;}
+ break;
+
+ case 99:
+
+/* Line 1464 of yacc.c */
+#line 684 "glsl_parser.ypp"
+ {
+ (yyval.node) = (yyvsp[(1) - (2)].declarator_list);
+ ;}
+ break;
+
+ case 100:
+
+/* Line 1464 of yacc.c */
+#line 688 "glsl_parser.ypp"
+ {
+ if (((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_float)
+ && ((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_int)) {
+ _mesa_glsl_error(& (yylsp[(3) - (4)]), state, "global precision qualifier can "
+ "only be applied to `int' or `float'\n");
+ YYERROR;
+ }
+
+ (yyval.node) = NULL; /* FINISHME */
+ ;}
+ break;
+
+ case 104:
+
+/* Line 1464 of yacc.c */
+#line 711 "glsl_parser.ypp"
+ {
+ (yyval.function) = (yyvsp[(1) - (2)].function);
+ (yyval.function)->parameters.push_tail(& (yyvsp[(2) - (2)].parameter_declarator)->link);
+ ;}
+ break;
+
+ case 105:
+
+/* Line 1464 of yacc.c */
+#line 716 "glsl_parser.ypp"
+ {
+ (yyval.function) = (yyvsp[(1) - (3)].function);
+ (yyval.function)->parameters.push_tail(& (yyvsp[(3) - (3)].parameter_declarator)->link);
+ ;}
+ break;
+
+ case 106:
+
+/* Line 1464 of yacc.c */
+#line 724 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.function) = new(ctx) ast_function();
+ (yyval.function)->set_location(yylloc);
+ (yyval.function)->return_type = (yyvsp[(1) - (3)].fully_specified_type);
+ (yyval.function)->identifier = (yyvsp[(2) - (3)].identifier);
+ ;}
+ break;
+
+ case 107:
+
+/* Line 1464 of yacc.c */
+#line 735 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
+ (yyval.parameter_declarator)->set_location(yylloc);
+ (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
+ (yyval.parameter_declarator)->type->set_location(yylloc);
+ (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (2)].type_specifier);
+ (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (2)].identifier);
+ ;}
+ break;
+
+ case 108:
+
+/* Line 1464 of yacc.c */
+#line 745 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
+ (yyval.parameter_declarator)->set_location(yylloc);
+ (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
+ (yyval.parameter_declarator)->type->set_location(yylloc);
+ (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (5)].type_specifier);
+ (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (5)].identifier);
+ (yyval.parameter_declarator)->is_array = true;
+ (yyval.parameter_declarator)->array_size = (yyvsp[(4) - (5)].expression);
+ ;}
+ break;
+
+ case 109:
+
+/* Line 1464 of yacc.c */
+#line 760 "glsl_parser.ypp"
+ {
+ (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i;
+
+ (yyval.parameter_declarator) = (yyvsp[(3) - (3)].parameter_declarator);
+ (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier);
+ ;}
+ break;
+
+ case 110:
+
+/* Line 1464 of yacc.c */
+#line 767 "glsl_parser.ypp"
+ {
+ (yyval.parameter_declarator) = (yyvsp[(2) - (2)].parameter_declarator);
+ (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier);
+ ;}
+ break;
+
+ case 111:
+
+/* Line 1464 of yacc.c */
+#line 772 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i;
+
+ (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
+ (yyval.parameter_declarator)->set_location(yylloc);
+ (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
+ (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier);
+ (yyval.parameter_declarator)->type->specifier = (yyvsp[(3) - (3)].type_specifier);
+ ;}
+ break;
+
+ case 112:
+
+/* Line 1464 of yacc.c */
+#line 783 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator();
+ (yyval.parameter_declarator)->set_location(yylloc);
+ (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type();
+ (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier);
+ (yyval.parameter_declarator)->type->specifier = (yyvsp[(2) - (2)].type_specifier);
+ ;}
+ break;
+
+ case 113:
+
+/* Line 1464 of yacc.c */
+#line 795 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ ;}
+ break;
+
+ case 114:
+
+/* Line 1464 of yacc.c */
+#line 799 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.in = 1;
+ ;}
+ break;
+
+ case 115:
+
+/* Line 1464 of yacc.c */
+#line 804 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.out = 1;
+ ;}
+ break;
+
+ case 116:
+
+/* Line 1464 of yacc.c */
+#line 809 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.in = 1;
+ (yyval.type_qualifier).flags.q.out = 1;
+ ;}
+ break;
+
+ case 119:
+
+/* Line 1464 of yacc.c */
+#line 823 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (3)].identifier), false, NULL, NULL);
+ decl->set_location(yylloc);
+
+ (yyval.declarator_list) = (yyvsp[(1) - (3)].declarator_list);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 120:
+
+/* Line 1464 of yacc.c */
+#line 832 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), true, NULL, NULL);
+ decl->set_location(yylloc);
+
+ (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 121:
+
+/* Line 1464 of yacc.c */
+#line 841 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (6)].identifier), true, (yyvsp[(5) - (6)].expression), NULL);
+ decl->set_location(yylloc);
+
+ (yyval.declarator_list) = (yyvsp[(1) - (6)].declarator_list);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 122:
+
+/* Line 1464 of yacc.c */
+#line 850 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (7)].identifier), true, NULL, (yyvsp[(7) - (7)].expression));
+ decl->set_location(yylloc);
+
+ (yyval.declarator_list) = (yyvsp[(1) - (7)].declarator_list);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 123:
+
+/* Line 1464 of yacc.c */
+#line 859 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (8)].identifier), true, (yyvsp[(5) - (8)].expression), (yyvsp[(8) - (8)].expression));
+ decl->set_location(yylloc);
+
+ (yyval.declarator_list) = (yyvsp[(1) - (8)].declarator_list);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 124:
+
+/* Line 1464 of yacc.c */
+#line 868 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), false, NULL, (yyvsp[(5) - (5)].expression));
+ decl->set_location(yylloc);
+
+ (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 125:
+
+/* Line 1464 of yacc.c */
+#line 881 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ if ((yyvsp[(1) - (1)].fully_specified_type)->specifier->type_specifier != ast_struct) {
+ _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "empty declaration list\n");
+ YYERROR;
+ } else {
+ (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (1)].fully_specified_type));
+ (yyval.declarator_list)->set_location(yylloc);
+ }
+ ;}
+ break;
+
+ case 126:
+
+/* Line 1464 of yacc.c */
+#line 892 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL);
+
+ (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (2)].fully_specified_type));
+ (yyval.declarator_list)->set_location(yylloc);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 127:
+
+/* Line 1464 of yacc.c */
+#line 901 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), true, NULL, NULL);
+
+ (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type));
+ (yyval.declarator_list)->set_location(yylloc);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 128:
+
+/* Line 1464 of yacc.c */
+#line 910 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (5)].identifier), true, (yyvsp[(4) - (5)].expression), NULL);
+
+ (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (5)].fully_specified_type));
+ (yyval.declarator_list)->set_location(yylloc);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 129:
+
+/* Line 1464 of yacc.c */
+#line 919 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (6)].identifier), true, NULL, (yyvsp[(6) - (6)].expression));
+
+ (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (6)].fully_specified_type));
+ (yyval.declarator_list)->set_location(yylloc);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 130:
+
+/* Line 1464 of yacc.c */
+#line 928 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (7)].identifier), true, (yyvsp[(4) - (7)].expression), (yyvsp[(7) - (7)].expression));
+
+ (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (7)].fully_specified_type));
+ (yyval.declarator_list)->set_location(yylloc);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 131:
+
+/* Line 1464 of yacc.c */
+#line 937 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression));
+
+ (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type));
+ (yyval.declarator_list)->set_location(yylloc);
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 132:
+
+/* Line 1464 of yacc.c */
+#line 946 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL);
+
+ (yyval.declarator_list) = new(ctx) ast_declarator_list(NULL);
+ (yyval.declarator_list)->set_location(yylloc);
+ (yyval.declarator_list)->invariant = true;
+
+ (yyval.declarator_list)->declarations.push_tail(&decl->link);
+ ;}
+ break;
+
+ case 133:
+
+/* Line 1464 of yacc.c */
+#line 960 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type();
+ (yyval.fully_specified_type)->set_location(yylloc);
+ (yyval.fully_specified_type)->specifier = (yyvsp[(1) - (1)].type_specifier);
+ ;}
+ break;
+
+ case 134:
+
+/* Line 1464 of yacc.c */
+#line 967 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type();
+ (yyval.fully_specified_type)->set_location(yylloc);
+ (yyval.fully_specified_type)->qualifier = (yyvsp[(1) - (2)].type_qualifier);
+ (yyval.fully_specified_type)->specifier = (yyvsp[(2) - (2)].type_specifier);
+ ;}
+ break;
+
+ case 135:
+
+/* Line 1464 of yacc.c */
+#line 978 "glsl_parser.ypp"
+ {
+ (yyval.type_qualifier) = (yyvsp[(3) - (4)].type_qualifier);
+ ;}
+ break;
+
+ case 137:
+
+/* Line 1464 of yacc.c */
+#line 986 "glsl_parser.ypp"
+ {
+ if (((yyvsp[(1) - (3)].type_qualifier).flags.i & (yyvsp[(3) - (3)].type_qualifier).flags.i) != 0) {
+ _mesa_glsl_error(& (yylsp[(3) - (3)]), state,
+ "duplicate layout qualifiers used\n");
+ YYERROR;
+ }
+
+ (yyval.type_qualifier).flags.i = (yyvsp[(1) - (3)].type_qualifier).flags.i | (yyvsp[(3) - (3)].type_qualifier).flags.i;
+
+ if ((yyvsp[(1) - (3)].type_qualifier).flags.q.explicit_location)
+ (yyval.type_qualifier).location = (yyvsp[(1) - (3)].type_qualifier).location;
+
+ if ((yyvsp[(3) - (3)].type_qualifier).flags.q.explicit_location)
+ (yyval.type_qualifier).location = (yyvsp[(3) - (3)].type_qualifier).location;
+ ;}
+ break;
+
+ case 138:
+
+/* Line 1464 of yacc.c */
+#line 1005 "glsl_parser.ypp"
+ {
+ bool got_one = false;
+
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+
+ if (state->ARB_fragment_coord_conventions_enable) {
+ if (strcmp((yyvsp[(1) - (1)].identifier), "origin_upper_left") == 0) {
+ got_one = true;
+ (yyval.type_qualifier).flags.q.origin_upper_left = 1;
+ } else if (strcmp((yyvsp[(1) - (1)].identifier), "pixel_center_integer") == 0) {
+ got_one = true;
+ (yyval.type_qualifier).flags.q.pixel_center_integer = 1;
+ }
+ }
+
+ /* If the identifier didn't match any known layout identifiers,
+ * emit an error.
+ */
+ if (!got_one) {
+ _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "unrecognized layout identifier "
+ "`%s'\n", (yyvsp[(1) - (1)].identifier));
+ YYERROR;
+ } else if (state->ARB_fragment_coord_conventions_warn) {
+ _mesa_glsl_warning(& (yylsp[(1) - (1)]), state,
+ "GL_ARB_fragment_coord_conventions layout "
+ "identifier `%s' used\n", (yyvsp[(1) - (1)].identifier));
+ }
+ ;}
+ break;
+
+ case 139:
+
+/* Line 1464 of yacc.c */
+#line 1034 "glsl_parser.ypp"
+ {
+ bool got_one = false;
+
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+
+ if (state->ARB_explicit_attrib_location_enable) {
+ /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
+ * FINISHME: GLSL 1.30 (or later) are supported.
+ */
+ if (strcmp("location", (yyvsp[(1) - (3)].identifier)) == 0) {
+ got_one = true;
+
+ (yyval.type_qualifier).flags.q.explicit_location = 1;
+
+ if ((yyvsp[(3) - (3)].n) >= 0) {
+ (yyval.type_qualifier).location = (yyvsp[(3) - (3)].n);
+ } else {
+ _mesa_glsl_error(& (yylsp[(3) - (3)]), state,
+ "invalid location %d specified\n", (yyvsp[(3) - (3)].n));
+ YYERROR;
+ }
+ }
+ }
+
+ /* If the identifier didn't match any known layout identifiers,
+ * emit an error.
+ */
+ if (!got_one) {
+ _mesa_glsl_error(& (yylsp[(1) - (3)]), state, "unrecognized layout identifier "
+ "`%s'\n", (yyvsp[(1) - (3)].identifier));
+ YYERROR;
+ } else if (state->ARB_explicit_attrib_location_warn) {
+ _mesa_glsl_warning(& (yylsp[(1) - (3)]), state,
+ "GL_ARB_explicit_attrib_location layout "
+ "identifier `%s' used\n", (yyvsp[(1) - (3)].identifier));
+ }
+ ;}
+ break;
+
+ case 140:
+
+/* Line 1464 of yacc.c */
+#line 1075 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.smooth = 1;
+ ;}
+ break;
+
+ case 141:
+
+/* Line 1464 of yacc.c */
+#line 1080 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.flat = 1;
+ ;}
+ break;
+
+ case 142:
+
+/* Line 1464 of yacc.c */
+#line 1085 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.noperspective = 1;
+ ;}
+ break;
+
+ case 143:
+
+/* Line 1464 of yacc.c */
+#line 1093 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.constant = 1;
+ ;}
+ break;
+
+ case 146:
+
+/* Line 1464 of yacc.c */
+#line 1103 "glsl_parser.ypp"
+ {
+ (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier);
+ (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i;
+ ;}
+ break;
+
+ case 148:
+
+/* Line 1464 of yacc.c */
+#line 1109 "glsl_parser.ypp"
+ {
+ (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier);
+ (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i;
+ ;}
+ break;
+
+ case 149:
+
+/* Line 1464 of yacc.c */
+#line 1114 "glsl_parser.ypp"
+ {
+ (yyval.type_qualifier) = (yyvsp[(2) - (2)].type_qualifier);
+ (yyval.type_qualifier).flags.q.invariant = 1;
+ ;}
+ break;
+
+ case 150:
+
+/* Line 1464 of yacc.c */
+#line 1119 "glsl_parser.ypp"
+ {
+ (yyval.type_qualifier) = (yyvsp[(2) - (3)].type_qualifier);
+ (yyval.type_qualifier).flags.i |= (yyvsp[(3) - (3)].type_qualifier).flags.i;
+ (yyval.type_qualifier).flags.q.invariant = 1;
+ ;}
+ break;
+
+ case 151:
+
+/* Line 1464 of yacc.c */
+#line 1125 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.invariant = 1;
+ ;}
+ break;
+
+ case 152:
+
+/* Line 1464 of yacc.c */
+#line 1133 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.constant = 1;
+ ;}
+ break;
+
+ case 153:
+
+/* Line 1464 of yacc.c */
+#line 1138 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.attribute = 1;
+ ;}
+ break;
+
+ case 154:
+
+/* Line 1464 of yacc.c */
+#line 1143 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.varying = 1;
+ ;}
+ break;
+
+ case 155:
+
+/* Line 1464 of yacc.c */
+#line 1148 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.centroid = 1;
+ (yyval.type_qualifier).flags.q.varying = 1;
+ ;}
+ break;
+
+ case 156:
+
+/* Line 1464 of yacc.c */
+#line 1154 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.in = 1;
+ ;}
+ break;
+
+ case 157:
+
+/* Line 1464 of yacc.c */
+#line 1159 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.out = 1;
+ ;}
+ break;
+
+ case 158:
+
+/* Line 1464 of yacc.c */
+#line 1164 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.in = 1;
+ ;}
+ break;
+
+ case 159:
+
+/* Line 1464 of yacc.c */
+#line 1169 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.out = 1;
+ ;}
+ break;
+
+ case 160:
+
+/* Line 1464 of yacc.c */
+#line 1174 "glsl_parser.ypp"
+ {
+ memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier)));
+ (yyval.type_qualifier).flags.q.uniform = 1;
+ ;}
+ break;
+
+ case 162:
+
+/* Line 1464 of yacc.c */
+#line 1183 "glsl_parser.ypp"
+ {
+ (yyval.type_specifier) = (yyvsp[(2) - (2)].type_specifier);
+ (yyval.type_specifier)->precision = (yyvsp[(1) - (2)].n);
+ ;}
+ break;
+
+ case 164:
+
+/* Line 1464 of yacc.c */
+#line 1192 "glsl_parser.ypp"
+ {
+ (yyval.type_specifier) = (yyvsp[(1) - (3)].type_specifier);
+ (yyval.type_specifier)->is_array = true;
+ (yyval.type_specifier)->array_size = NULL;
+ ;}
+ break;
+
+ case 165:
+
+/* Line 1464 of yacc.c */
+#line 1198 "glsl_parser.ypp"
+ {
+ (yyval.type_specifier) = (yyvsp[(1) - (4)].type_specifier);
+ (yyval.type_specifier)->is_array = true;
+ (yyval.type_specifier)->array_size = (yyvsp[(3) - (4)].expression);
+ ;}
+ break;
+
+ case 166:
+
+/* Line 1464 of yacc.c */
+#line 1207 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].n));
+ (yyval.type_specifier)->set_location(yylloc);
+ ;}
+ break;
+
+ case 167:
+
+/* Line 1464 of yacc.c */
+#line 1213 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].struct_specifier));
+ (yyval.type_specifier)->set_location(yylloc);
+ ;}
+ break;
+
+ case 168:
+
+/* Line 1464 of yacc.c */
+#line 1219 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].identifier));
+ (yyval.type_specifier)->set_location(yylloc);
+ ;}
+ break;
+
+ case 169:
+
+/* Line 1464 of yacc.c */
+#line 1227 "glsl_parser.ypp"
+ { (yyval.n) = ast_void; ;}
+ break;
+
+ case 170:
+
+/* Line 1464 of yacc.c */
+#line 1228 "glsl_parser.ypp"
+ { (yyval.n) = ast_float; ;}
+ break;
+
+ case 171:
+
+/* Line 1464 of yacc.c */
+#line 1229 "glsl_parser.ypp"
+ { (yyval.n) = ast_int; ;}
+ break;
+
+ case 172:
+
+/* Line 1464 of yacc.c */
+#line 1230 "glsl_parser.ypp"
+ { (yyval.n) = ast_uint; ;}
+ break;
+
+ case 173:
+
+/* Line 1464 of yacc.c */
+#line 1231 "glsl_parser.ypp"
+ { (yyval.n) = ast_bool; ;}
+ break;
+
+ case 174:
+
+/* Line 1464 of yacc.c */
+#line 1232 "glsl_parser.ypp"
+ { (yyval.n) = ast_vec2; ;}
+ break;
+
+ case 175:
+
+/* Line 1464 of yacc.c */
+#line 1233 "glsl_parser.ypp"
+ { (yyval.n) = ast_vec3; ;}
+ break;
+
+ case 176:
+
+/* Line 1464 of yacc.c */
+#line 1234 "glsl_parser.ypp"
+ { (yyval.n) = ast_vec4; ;}
+ break;
+
+ case 177:
+
+/* Line 1464 of yacc.c */
+#line 1235 "glsl_parser.ypp"
+ { (yyval.n) = ast_bvec2; ;}
+ break;
+
+ case 178:
+
+/* Line 1464 of yacc.c */
+#line 1236 "glsl_parser.ypp"
+ { (yyval.n) = ast_bvec3; ;}
+ break;
+
+ case 179:
+
+/* Line 1464 of yacc.c */
+#line 1237 "glsl_parser.ypp"
+ { (yyval.n) = ast_bvec4; ;}
+ break;
+
+ case 180:
+
+/* Line 1464 of yacc.c */
+#line 1238 "glsl_parser.ypp"
+ { (yyval.n) = ast_ivec2; ;}
+ break;
+
+ case 181:
+
+/* Line 1464 of yacc.c */
+#line 1239 "glsl_parser.ypp"
+ { (yyval.n) = ast_ivec3; ;}
+ break;
+
+ case 182:
+
+/* Line 1464 of yacc.c */
+#line 1240 "glsl_parser.ypp"
+ { (yyval.n) = ast_ivec4; ;}
+ break;
+
+ case 183:
+
+/* Line 1464 of yacc.c */
+#line 1241 "glsl_parser.ypp"
+ { (yyval.n) = ast_uvec2; ;}
+ break;
+
+ case 184:
+
+/* Line 1464 of yacc.c */
+#line 1242 "glsl_parser.ypp"
+ { (yyval.n) = ast_uvec3; ;}
+ break;
+
+ case 185:
+
+/* Line 1464 of yacc.c */
+#line 1243 "glsl_parser.ypp"
+ { (yyval.n) = ast_uvec4; ;}
+ break;
+
+ case 186:
+
+/* Line 1464 of yacc.c */
+#line 1244 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat2; ;}
+ break;
+
+ case 187:
+
+/* Line 1464 of yacc.c */
+#line 1245 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat2x3; ;}
+ break;
+
+ case 188:
+
+/* Line 1464 of yacc.c */
+#line 1246 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat2x4; ;}
+ break;
+
+ case 189:
+
+/* Line 1464 of yacc.c */
+#line 1247 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat3x2; ;}
+ break;
+
+ case 190:
+
+/* Line 1464 of yacc.c */
+#line 1248 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat3; ;}
+ break;
+
+ case 191:
+
+/* Line 1464 of yacc.c */
+#line 1249 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat3x4; ;}
+ break;
+
+ case 192:
+
+/* Line 1464 of yacc.c */
+#line 1250 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat4x2; ;}
+ break;
+
+ case 193:
+
+/* Line 1464 of yacc.c */
+#line 1251 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat4x3; ;}
+ break;
+
+ case 194:
+
+/* Line 1464 of yacc.c */
+#line 1252 "glsl_parser.ypp"
+ { (yyval.n) = ast_mat4; ;}
+ break;
+
+ case 195:
+
+/* Line 1464 of yacc.c */
+#line 1253 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler1d; ;}
+ break;
+
+ case 196:
+
+/* Line 1464 of yacc.c */
+#line 1254 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler2d; ;}
+ break;
+
+ case 197:
+
+/* Line 1464 of yacc.c */
+#line 1255 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler2drect; ;}
+ break;
+
+ case 198:
+
+/* Line 1464 of yacc.c */
+#line 1256 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler3d; ;}
+ break;
+
+ case 199:
+
+/* Line 1464 of yacc.c */
+#line 1257 "glsl_parser.ypp"
+ { (yyval.n) = ast_samplercube; ;}
+ break;
+
+ case 200:
+
+/* Line 1464 of yacc.c */
+#line 1258 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler1dshadow; ;}
+ break;
+
+ case 201:
+
+/* Line 1464 of yacc.c */
+#line 1259 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler2dshadow; ;}
+ break;
+
+ case 202:
+
+/* Line 1464 of yacc.c */
+#line 1260 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler2drectshadow; ;}
+ break;
+
+ case 203:
+
+/* Line 1464 of yacc.c */
+#line 1261 "glsl_parser.ypp"
+ { (yyval.n) = ast_samplercubeshadow; ;}
+ break;
+
+ case 204:
+
+/* Line 1464 of yacc.c */
+#line 1262 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler1darray; ;}
+ break;
+
+ case 205:
+
+/* Line 1464 of yacc.c */
+#line 1263 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler2darray; ;}
+ break;
+
+ case 206:
+
+/* Line 1464 of yacc.c */
+#line 1264 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler1darrayshadow; ;}
+ break;
+
+ case 207:
+
+/* Line 1464 of yacc.c */
+#line 1265 "glsl_parser.ypp"
+ { (yyval.n) = ast_sampler2darrayshadow; ;}
+ break;
+
+ case 208:
+
+/* Line 1464 of yacc.c */
+#line 1266 "glsl_parser.ypp"
+ { (yyval.n) = ast_isampler1d; ;}
+ break;
+
+ case 209:
+
+/* Line 1464 of yacc.c */
+#line 1267 "glsl_parser.ypp"
+ { (yyval.n) = ast_isampler2d; ;}
+ break;
+
+ case 210:
+
+/* Line 1464 of yacc.c */
+#line 1268 "glsl_parser.ypp"
+ { (yyval.n) = ast_isampler3d; ;}
+ break;
+
+ case 211:
+
+/* Line 1464 of yacc.c */
+#line 1269 "glsl_parser.ypp"
+ { (yyval.n) = ast_isamplercube; ;}
+ break;
+
+ case 212:
+
+/* Line 1464 of yacc.c */
+#line 1270 "glsl_parser.ypp"
+ { (yyval.n) = ast_isampler1darray; ;}
+ break;
+
+ case 213:
+
+/* Line 1464 of yacc.c */
+#line 1271 "glsl_parser.ypp"
+ { (yyval.n) = ast_isampler2darray; ;}
+ break;
+
+ case 214:
+
+/* Line 1464 of yacc.c */
+#line 1272 "glsl_parser.ypp"
+ { (yyval.n) = ast_usampler1d; ;}
+ break;
+
+ case 215:
+
+/* Line 1464 of yacc.c */
+#line 1273 "glsl_parser.ypp"
+ { (yyval.n) = ast_usampler2d; ;}
+ break;
+
+ case 216:
+
+/* Line 1464 of yacc.c */
+#line 1274 "glsl_parser.ypp"
+ { (yyval.n) = ast_usampler3d; ;}
+ break;
+
+ case 217:
+
+/* Line 1464 of yacc.c */
+#line 1275 "glsl_parser.ypp"
+ { (yyval.n) = ast_usamplercube; ;}
+ break;
+
+ case 218:
+
+/* Line 1464 of yacc.c */
+#line 1276 "glsl_parser.ypp"
+ { (yyval.n) = ast_usampler1darray; ;}
+ break;
+
+ case 219:
+
+/* Line 1464 of yacc.c */
+#line 1277 "glsl_parser.ypp"
+ { (yyval.n) = ast_usampler2darray; ;}
+ break;
+
+ case 220:
+
+/* Line 1464 of yacc.c */
+#line 1281 "glsl_parser.ypp"
+ {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& (yylsp[(1) - (1)]), state,
+ "precision qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ (yyval.n) = ast_precision_high;
+ ;}
+ break;
+
+ case 221:
+
+/* Line 1464 of yacc.c */
+#line 1292 "glsl_parser.ypp"
+ {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& (yylsp[(1) - (1)]), state,
+ "precision qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ (yyval.n) = ast_precision_medium;
+ ;}
+ break;
+
+ case 222:
+
+/* Line 1464 of yacc.c */
+#line 1303 "glsl_parser.ypp"
+ {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& (yylsp[(1) - (1)]), state,
+ "precision qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ (yyval.n) = ast_precision_low;
+ ;}
+ break;
+
+ case 223:
+
+/* Line 1464 of yacc.c */
+#line 1318 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.struct_specifier) = new(ctx) ast_struct_specifier((yyvsp[(2) - (5)].identifier), (yyvsp[(4) - (5)].node));
+ (yyval.struct_specifier)->set_location(yylloc);
+ ;}
+ break;
+
+ case 224:
+
+/* Line 1464 of yacc.c */
+#line 1324 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.struct_specifier) = new(ctx) ast_struct_specifier(NULL, (yyvsp[(3) - (4)].node));
+ (yyval.struct_specifier)->set_location(yylloc);
+ ;}
+ break;
+
+ case 225:
+
+/* Line 1464 of yacc.c */
+#line 1333 "glsl_parser.ypp"
+ {
+ (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list);
+ (yyvsp[(1) - (1)].declarator_list)->link.self_link();
+ ;}
+ break;
+
+ case 226:
+
+/* Line 1464 of yacc.c */
+#line 1338 "glsl_parser.ypp"
+ {
+ (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node);
+ (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link);
+ ;}
+ break;
+
+ case 227:
+
+/* Line 1464 of yacc.c */
+#line 1346 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
+ type->set_location(yylloc);
+
+ type->specifier = (yyvsp[(1) - (3)].type_specifier);
+ (yyval.declarator_list) = new(ctx) ast_declarator_list(type);
+ (yyval.declarator_list)->set_location(yylloc);
+
+ (yyval.declarator_list)->declarations.push_degenerate_list_at_head(& (yyvsp[(2) - (3)].declaration)->link);
+ ;}
+ break;
+
+ case 228:
+
+/* Line 1464 of yacc.c */
+#line 1361 "glsl_parser.ypp"
+ {
+ (yyval.declaration) = (yyvsp[(1) - (1)].declaration);
+ (yyvsp[(1) - (1)].declaration)->link.self_link();
+ ;}
+ break;
+
+ case 229:
+
+/* Line 1464 of yacc.c */
+#line 1366 "glsl_parser.ypp"
+ {
+ (yyval.declaration) = (yyvsp[(1) - (3)].declaration);
+ (yyval.declaration)->link.insert_before(& (yyvsp[(3) - (3)].declaration)->link);
+ ;}
+ break;
+
+ case 230:
+
+/* Line 1464 of yacc.c */
+#line 1374 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (1)].identifier), false, NULL, NULL);
+ (yyval.declaration)->set_location(yylloc);
+ ;}
+ break;
+
+ case 231:
+
+/* Line 1464 of yacc.c */
+#line 1380 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (4)].identifier), true, (yyvsp[(3) - (4)].expression), NULL);
+ (yyval.declaration)->set_location(yylloc);
+ ;}
+ break;
+
+ case 234:
+
+/* Line 1464 of yacc.c */
+#line 1398 "glsl_parser.ypp"
+ { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;}
+ break;
+
+ case 239:
+
+/* Line 1464 of yacc.c */
+#line 1406 "glsl_parser.ypp"
+ { (yyval.node) = NULL; ;}
+ break;
+
+ case 240:
+
+/* Line 1464 of yacc.c */
+#line 1407 "glsl_parser.ypp"
+ { (yyval.node) = NULL; ;}
+ break;
+
+ case 243:
+
+/* Line 1464 of yacc.c */
+#line 1414 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.compound_statement) = new(ctx) ast_compound_statement(true, NULL);
+ (yyval.compound_statement)->set_location(yylloc);
+ ;}
+ break;
+
+ case 244:
+
+/* Line 1464 of yacc.c */
+#line 1420 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.compound_statement) = new(ctx) ast_compound_statement(true, (yyvsp[(2) - (3)].node));
+ (yyval.compound_statement)->set_location(yylloc);
+ ;}
+ break;
+
+ case 245:
+
+/* Line 1464 of yacc.c */
+#line 1428 "glsl_parser.ypp"
+ { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;}
+ break;
+
+ case 247:
+
+/* Line 1464 of yacc.c */
+#line 1434 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.compound_statement) = new(ctx) ast_compound_statement(false, NULL);
+ (yyval.compound_statement)->set_location(yylloc);
+ ;}
+ break;
+
+ case 248:
+
+/* Line 1464 of yacc.c */
+#line 1440 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.compound_statement) = new(ctx) ast_compound_statement(false, (yyvsp[(2) - (3)].node));
+ (yyval.compound_statement)->set_location(yylloc);
+ ;}
+ break;
+
+ case 249:
+
+/* Line 1464 of yacc.c */
+#line 1449 "glsl_parser.ypp"
+ {
+ if ((yyvsp[(1) - (1)].node) == NULL) {
+ _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "<nil> statement\n");
+ assert((yyvsp[(1) - (1)].node) != NULL);
+ }
+
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ (yyval.node)->link.self_link();
+ ;}
+ break;
+
+ case 250:
+
+/* Line 1464 of yacc.c */
+#line 1459 "glsl_parser.ypp"
+ {
+ if ((yyvsp[(2) - (2)].node) == NULL) {
+ _mesa_glsl_error(& (yylsp[(2) - (2)]), state, "<nil> statement\n");
+ assert((yyvsp[(2) - (2)].node) != NULL);
+ }
+ (yyval.node) = (yyvsp[(1) - (2)].node);
+ (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].node)->link);
+ ;}
+ break;
+
+ case 251:
+
+/* Line 1464 of yacc.c */
+#line 1471 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_expression_statement(NULL);
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 252:
+
+/* Line 1464 of yacc.c */
+#line 1477 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_expression_statement((yyvsp[(1) - (2)].expression));
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 253:
+
+/* Line 1464 of yacc.c */
+#line 1486 "glsl_parser.ypp"
+ {
+ (yyval.node) = new(state) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].selection_rest_statement).then_statement,
+ (yyvsp[(5) - (5)].selection_rest_statement).else_statement);
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 254:
+
+/* Line 1464 of yacc.c */
+#line 1495 "glsl_parser.ypp"
+ {
+ (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (3)].node);
+ (yyval.selection_rest_statement).else_statement = (yyvsp[(3) - (3)].node);
+ ;}
+ break;
+
+ case 255:
+
+/* Line 1464 of yacc.c */
+#line 1500 "glsl_parser.ypp"
+ {
+ (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (1)].node);
+ (yyval.selection_rest_statement).else_statement = NULL;
+ ;}
+ break;
+
+ case 256:
+
+/* Line 1464 of yacc.c */
+#line 1508 "glsl_parser.ypp"
+ {
+ (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression);
+ ;}
+ break;
+
+ case 257:
+
+/* Line 1464 of yacc.c */
+#line 1512 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression));
+ ast_declarator_list *declarator = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type));
+ decl->set_location(yylloc);
+ declarator->set_location(yylloc);
+
+ declarator->declarations.push_tail(&decl->link);
+ (yyval.node) = declarator;
+ ;}
+ break;
+
+ case 261:
+
+/* Line 1464 of yacc.c */
+#line 1535 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while,
+ NULL, (yyvsp[(3) - (5)].node), NULL, (yyvsp[(5) - (5)].node));
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 262:
+
+/* Line 1464 of yacc.c */
+#line 1542 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while,
+ NULL, (yyvsp[(5) - (7)].expression), NULL, (yyvsp[(2) - (7)].node));
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 263:
+
+/* Line 1464 of yacc.c */
+#line 1549 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for,
+ (yyvsp[(3) - (6)].node), (yyvsp[(4) - (6)].for_rest_statement).cond, (yyvsp[(4) - (6)].for_rest_statement).rest, (yyvsp[(6) - (6)].node));
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 267:
+
+/* Line 1464 of yacc.c */
+#line 1565 "glsl_parser.ypp"
+ {
+ (yyval.node) = NULL;
+ ;}
+ break;
+
+ case 268:
+
+/* Line 1464 of yacc.c */
+#line 1572 "glsl_parser.ypp"
+ {
+ (yyval.for_rest_statement).cond = (yyvsp[(1) - (2)].node);
+ (yyval.for_rest_statement).rest = NULL;
+ ;}
+ break;
+
+ case 269:
+
+/* Line 1464 of yacc.c */
+#line 1577 "glsl_parser.ypp"
+ {
+ (yyval.for_rest_statement).cond = (yyvsp[(1) - (3)].node);
+ (yyval.for_rest_statement).rest = (yyvsp[(3) - (3)].expression);
+ ;}
+ break;
+
+ case 270:
+
+/* Line 1464 of yacc.c */
+#line 1586 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL);
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 271:
+
+/* Line 1464 of yacc.c */
+#line 1592 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL);
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 272:
+
+/* Line 1464 of yacc.c */
+#line 1598 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL);
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 273:
+
+/* Line 1464 of yacc.c */
+#line 1604 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, (yyvsp[(2) - (3)].expression));
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 274:
+
+/* Line 1464 of yacc.c */
+#line 1610 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL);
+ (yyval.node)->set_location(yylloc);
+ ;}
+ break;
+
+ case 275:
+
+/* Line 1464 of yacc.c */
+#line 1618 "glsl_parser.ypp"
+ { (yyval.node) = (yyvsp[(1) - (1)].function_definition); ;}
+ break;
+
+ case 276:
+
+/* Line 1464 of yacc.c */
+#line 1619 "glsl_parser.ypp"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); ;}
+ break;
+
+ case 277:
+
+/* Line 1464 of yacc.c */
+#line 1620 "glsl_parser.ypp"
+ { (yyval.node) = NULL; ;}
+ break;
+
+ case 278:
+
+/* Line 1464 of yacc.c */
+#line 1625 "glsl_parser.ypp"
+ {
+ void *ctx = state;
+ (yyval.function_definition) = new(ctx) ast_function_definition();
+ (yyval.function_definition)->set_location(yylloc);
+ (yyval.function_definition)->prototype = (yyvsp[(1) - (2)].function);
+ (yyval.function_definition)->body = (yyvsp[(2) - (2)].compound_statement);
+ ;}
+ break;
+
+
+
+/* Line 1464 of yacc.c */
+#line 5090 "glsl_parser.cpp"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, state, YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (&yylloc, state, yymsg);
+ }
+ else
+ {
+ yyerror (&yylloc, state, YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+ yyerror_range[1] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc, state);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[1] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp, state);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+ yyerror_range[2] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, state, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc, state);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp, state);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
diff --git a/mesalib/src/glsl/glsl_parser.h b/mesalib/src/glsl/glsl_parser.h index 4a780375b..6fd70d4cb 100644 --- a/mesalib/src/glsl/glsl_parser.h +++ b/mesalib/src/glsl/glsl_parser.h @@ -1,298 +1,297 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2009, 2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ATTRIBUTE = 258, - CONST_TOK = 259, - BOOL_TOK = 260, - FLOAT_TOK = 261, - INT_TOK = 262, - UINT_TOK = 263, - BREAK = 264, - CONTINUE = 265, - DO = 266, - ELSE = 267, - FOR = 268, - IF = 269, - DISCARD = 270, - RETURN = 271, - SWITCH = 272, - CASE = 273, - DEFAULT = 274, - BVEC2 = 275, - BVEC3 = 276, - BVEC4 = 277, - IVEC2 = 278, - IVEC3 = 279, - IVEC4 = 280, - UVEC2 = 281, - UVEC3 = 282, - UVEC4 = 283, - VEC2 = 284, - VEC3 = 285, - VEC4 = 286, - CENTROID = 287, - IN_TOK = 288, - OUT_TOK = 289, - INOUT_TOK = 290, - UNIFORM = 291, - VARYING = 292, - NOPERSPECTIVE = 293, - FLAT = 294, - SMOOTH = 295, - MAT2X2 = 296, - MAT2X3 = 297, - MAT2X4 = 298, - MAT3X2 = 299, - MAT3X3 = 300, - MAT3X4 = 301, - MAT4X2 = 302, - MAT4X3 = 303, - MAT4X4 = 304, - SAMPLER1D = 305, - SAMPLER2D = 306, - SAMPLER3D = 307, - SAMPLERCUBE = 308, - SAMPLER1DSHADOW = 309, - SAMPLER2DSHADOW = 310, - SAMPLERCUBESHADOW = 311, - SAMPLER1DARRAY = 312, - SAMPLER2DARRAY = 313, - SAMPLER1DARRAYSHADOW = 314, - SAMPLER2DARRAYSHADOW = 315, - ISAMPLER1D = 316, - ISAMPLER2D = 317, - ISAMPLER3D = 318, - ISAMPLERCUBE = 319, - ISAMPLER1DARRAY = 320, - ISAMPLER2DARRAY = 321, - USAMPLER1D = 322, - USAMPLER2D = 323, - USAMPLER3D = 324, - USAMPLERCUBE = 325, - USAMPLER1DARRAY = 326, - USAMPLER2DARRAY = 327, - STRUCT = 328, - VOID_TOK = 329, - WHILE = 330, - IDENTIFIER = 331, - FLOATCONSTANT = 332, - INTCONSTANT = 333, - UINTCONSTANT = 334, - BOOLCONSTANT = 335, - FIELD_SELECTION = 336, - LEFT_OP = 337, - RIGHT_OP = 338, - INC_OP = 339, - DEC_OP = 340, - LE_OP = 341, - GE_OP = 342, - EQ_OP = 343, - NE_OP = 344, - AND_OP = 345, - OR_OP = 346, - XOR_OP = 347, - MUL_ASSIGN = 348, - DIV_ASSIGN = 349, - ADD_ASSIGN = 350, - MOD_ASSIGN = 351, - LEFT_ASSIGN = 352, - RIGHT_ASSIGN = 353, - AND_ASSIGN = 354, - XOR_ASSIGN = 355, - OR_ASSIGN = 356, - SUB_ASSIGN = 357, - INVARIANT = 358, - LOWP = 359, - MEDIUMP = 360, - HIGHP = 361, - SUPERP = 362, - PRECISION = 363, - VERSION = 364, - EXTENSION = 365, - LINE = 366, - COLON = 367, - EOL = 368, - INTERFACE = 369, - OUTPUT = 370, - PRAGMA_DEBUG_ON = 371, - PRAGMA_DEBUG_OFF = 372, - PRAGMA_OPTIMIZE_ON = 373, - PRAGMA_OPTIMIZE_OFF = 374, - LAYOUT_TOK = 375, - ASM = 376, - CLASS = 377, - UNION = 378, - ENUM = 379, - TYPEDEF = 380, - TEMPLATE = 381, - THIS = 382, - PACKED_TOK = 383, - GOTO = 384, - INLINE_TOK = 385, - NOINLINE = 386, - VOLATILE = 387, - PUBLIC_TOK = 388, - STATIC = 389, - EXTERN = 390, - EXTERNAL = 391, - LONG_TOK = 392, - SHORT_TOK = 393, - DOUBLE_TOK = 394, - HALF = 395, - FIXED_TOK = 396, - UNSIGNED = 397, - INPUT_TOK = 398, - OUPTUT = 399, - HVEC2 = 400, - HVEC3 = 401, - HVEC4 = 402, - DVEC2 = 403, - DVEC3 = 404, - DVEC4 = 405, - FVEC2 = 406, - FVEC3 = 407, - FVEC4 = 408, - SAMPLER2DRECT = 409, - SAMPLER3DRECT = 410, - SAMPLER2DRECTSHADOW = 411, - SIZEOF = 412, - CAST = 413, - NAMESPACE = 414, - USING = 415, - ERROR_TOK = 416, - COMMON = 417, - PARTITION = 418, - ACTIVE = 419, - SAMPLERBUFFER = 420, - FILTER = 421, - IMAGE1D = 422, - IMAGE2D = 423, - IMAGE3D = 424, - IMAGECUBE = 425, - IMAGE1DARRAY = 426, - IMAGE2DARRAY = 427, - IIMAGE1D = 428, - IIMAGE2D = 429, - IIMAGE3D = 430, - IIMAGECUBE = 431, - IIMAGE1DARRAY = 432, - IIMAGE2DARRAY = 433, - UIMAGE1D = 434, - UIMAGE2D = 435, - UIMAGE3D = 436, - UIMAGECUBE = 437, - UIMAGE1DARRAY = 438, - UIMAGE2DARRAY = 439, - IMAGE1DSHADOW = 440, - IMAGE2DSHADOW = 441, - IMAGEBUFFER = 442, - IIMAGEBUFFER = 443, - UIMAGEBUFFER = 444, - ROW_MAJOR = 445 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 1685 of yacc.c */ -#line 52 "glsl_parser.ypp" - - int n; - float real; - char *identifier; - - union { - struct ast_type_qualifier q; - unsigned i; - } type_qualifier; - - ast_node *node; - ast_type_specifier *type_specifier; - ast_fully_specified_type *fully_specified_type; - ast_function *function; - ast_parameter_declarator *parameter_declarator; - ast_function_definition *function_definition; - ast_compound_statement *compound_statement; - ast_expression *expression; - ast_declarator_list *declarator_list; - ast_struct_specifier *struct_specifier; - ast_declaration *declaration; - - struct { - ast_node *cond; - ast_expression *rest; - } for_rest_statement; - - struct { - ast_node *then_statement; - ast_node *else_statement; - } selection_rest_statement; - - - -/* Line 1685 of yacc.c */ -#line 276 "glsl_parser.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - +/* A Bison parser, made by GNU Bison 2.4.3. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ATTRIBUTE = 258,
+ CONST_TOK = 259,
+ BOOL_TOK = 260,
+ FLOAT_TOK = 261,
+ INT_TOK = 262,
+ UINT_TOK = 263,
+ BREAK = 264,
+ CONTINUE = 265,
+ DO = 266,
+ ELSE = 267,
+ FOR = 268,
+ IF = 269,
+ DISCARD = 270,
+ RETURN = 271,
+ SWITCH = 272,
+ CASE = 273,
+ DEFAULT = 274,
+ BVEC2 = 275,
+ BVEC3 = 276,
+ BVEC4 = 277,
+ IVEC2 = 278,
+ IVEC3 = 279,
+ IVEC4 = 280,
+ UVEC2 = 281,
+ UVEC3 = 282,
+ UVEC4 = 283,
+ VEC2 = 284,
+ VEC3 = 285,
+ VEC4 = 286,
+ CENTROID = 287,
+ IN_TOK = 288,
+ OUT_TOK = 289,
+ INOUT_TOK = 290,
+ UNIFORM = 291,
+ VARYING = 292,
+ NOPERSPECTIVE = 293,
+ FLAT = 294,
+ SMOOTH = 295,
+ MAT2X2 = 296,
+ MAT2X3 = 297,
+ MAT2X4 = 298,
+ MAT3X2 = 299,
+ MAT3X3 = 300,
+ MAT3X4 = 301,
+ MAT4X2 = 302,
+ MAT4X3 = 303,
+ MAT4X4 = 304,
+ SAMPLER1D = 305,
+ SAMPLER2D = 306,
+ SAMPLER3D = 307,
+ SAMPLERCUBE = 308,
+ SAMPLER1DSHADOW = 309,
+ SAMPLER2DSHADOW = 310,
+ SAMPLERCUBESHADOW = 311,
+ SAMPLER1DARRAY = 312,
+ SAMPLER2DARRAY = 313,
+ SAMPLER1DARRAYSHADOW = 314,
+ SAMPLER2DARRAYSHADOW = 315,
+ ISAMPLER1D = 316,
+ ISAMPLER2D = 317,
+ ISAMPLER3D = 318,
+ ISAMPLERCUBE = 319,
+ ISAMPLER1DARRAY = 320,
+ ISAMPLER2DARRAY = 321,
+ USAMPLER1D = 322,
+ USAMPLER2D = 323,
+ USAMPLER3D = 324,
+ USAMPLERCUBE = 325,
+ USAMPLER1DARRAY = 326,
+ USAMPLER2DARRAY = 327,
+ STRUCT = 328,
+ VOID_TOK = 329,
+ WHILE = 330,
+ IDENTIFIER = 331,
+ FLOATCONSTANT = 332,
+ INTCONSTANT = 333,
+ UINTCONSTANT = 334,
+ BOOLCONSTANT = 335,
+ FIELD_SELECTION = 336,
+ LEFT_OP = 337,
+ RIGHT_OP = 338,
+ INC_OP = 339,
+ DEC_OP = 340,
+ LE_OP = 341,
+ GE_OP = 342,
+ EQ_OP = 343,
+ NE_OP = 344,
+ AND_OP = 345,
+ OR_OP = 346,
+ XOR_OP = 347,
+ MUL_ASSIGN = 348,
+ DIV_ASSIGN = 349,
+ ADD_ASSIGN = 350,
+ MOD_ASSIGN = 351,
+ LEFT_ASSIGN = 352,
+ RIGHT_ASSIGN = 353,
+ AND_ASSIGN = 354,
+ XOR_ASSIGN = 355,
+ OR_ASSIGN = 356,
+ SUB_ASSIGN = 357,
+ INVARIANT = 358,
+ LOWP = 359,
+ MEDIUMP = 360,
+ HIGHP = 361,
+ SUPERP = 362,
+ PRECISION = 363,
+ VERSION = 364,
+ EXTENSION = 365,
+ LINE = 366,
+ COLON = 367,
+ EOL = 368,
+ INTERFACE = 369,
+ OUTPUT = 370,
+ PRAGMA_DEBUG_ON = 371,
+ PRAGMA_DEBUG_OFF = 372,
+ PRAGMA_OPTIMIZE_ON = 373,
+ PRAGMA_OPTIMIZE_OFF = 374,
+ LAYOUT_TOK = 375,
+ ASM = 376,
+ CLASS = 377,
+ UNION = 378,
+ ENUM = 379,
+ TYPEDEF = 380,
+ TEMPLATE = 381,
+ THIS = 382,
+ PACKED_TOK = 383,
+ GOTO = 384,
+ INLINE_TOK = 385,
+ NOINLINE = 386,
+ VOLATILE = 387,
+ PUBLIC_TOK = 388,
+ STATIC = 389,
+ EXTERN = 390,
+ EXTERNAL = 391,
+ LONG_TOK = 392,
+ SHORT_TOK = 393,
+ DOUBLE_TOK = 394,
+ HALF = 395,
+ FIXED_TOK = 396,
+ UNSIGNED = 397,
+ INPUT_TOK = 398,
+ OUPTUT = 399,
+ HVEC2 = 400,
+ HVEC3 = 401,
+ HVEC4 = 402,
+ DVEC2 = 403,
+ DVEC3 = 404,
+ DVEC4 = 405,
+ FVEC2 = 406,
+ FVEC3 = 407,
+ FVEC4 = 408,
+ SAMPLER2DRECT = 409,
+ SAMPLER3DRECT = 410,
+ SAMPLER2DRECTSHADOW = 411,
+ SIZEOF = 412,
+ CAST = 413,
+ NAMESPACE = 414,
+ USING = 415,
+ ERROR_TOK = 416,
+ COMMON = 417,
+ PARTITION = 418,
+ ACTIVE = 419,
+ SAMPLERBUFFER = 420,
+ FILTER = 421,
+ IMAGE1D = 422,
+ IMAGE2D = 423,
+ IMAGE3D = 424,
+ IMAGECUBE = 425,
+ IMAGE1DARRAY = 426,
+ IMAGE2DARRAY = 427,
+ IIMAGE1D = 428,
+ IIMAGE2D = 429,
+ IIMAGE3D = 430,
+ IIMAGECUBE = 431,
+ IIMAGE1DARRAY = 432,
+ IIMAGE2DARRAY = 433,
+ UIMAGE1D = 434,
+ UIMAGE2D = 435,
+ UIMAGE3D = 436,
+ UIMAGECUBE = 437,
+ UIMAGE1DARRAY = 438,
+ UIMAGE2DARRAY = 439,
+ IMAGE1DSHADOW = 440,
+ IMAGE2DSHADOW = 441,
+ IMAGEBUFFER = 442,
+ IIMAGEBUFFER = 443,
+ UIMAGEBUFFER = 444,
+ IMAGE1DARRAYSHADOW = 445,
+ IMAGE2DARRAYSHADOW = 446,
+ ROW_MAJOR = 447
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1685 of yacc.c */
+#line 52 "glsl_parser.ypp"
+
+ int n;
+ float real;
+ char *identifier;
+
+ struct ast_type_qualifier type_qualifier;
+
+ ast_node *node;
+ ast_type_specifier *type_specifier;
+ ast_fully_specified_type *fully_specified_type;
+ ast_function *function;
+ ast_parameter_declarator *parameter_declarator;
+ ast_function_definition *function_definition;
+ ast_compound_statement *compound_statement;
+ ast_expression *expression;
+ ast_declarator_list *declarator_list;
+ ast_struct_specifier *struct_specifier;
+ ast_declaration *declaration;
+
+ struct {
+ ast_node *cond;
+ ast_expression *rest;
+ } for_rest_statement;
+
+ struct {
+ ast_node *then_statement;
+ ast_node *else_statement;
+ } selection_rest_statement;
+
+
+
+/* Line 1685 of yacc.c */
+#line 275 "glsl_parser.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/mesalib/src/glsl/glsl_parser.ypp b/mesalib/src/glsl/glsl_parser.ypp index 0df1e480c..c72da6116 100644 --- a/mesalib/src/glsl/glsl_parser.ypp +++ b/mesalib/src/glsl/glsl_parser.ypp @@ -1,1503 +1,1632 @@ -%{ -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_types.h" - -#define YYLEX_PARAM state->scanner - -%} - -%pure-parser -%error-verbose - -%locations -%initial-action { - @$.first_line = 1; - @$.first_column = 1; - @$.last_line = 1; - @$.last_column = 1; - @$.source = 0; -} - -%lex-param {void *scanner} -%parse-param {struct _mesa_glsl_parse_state *state} - -%union { - int n; - float real; - char *identifier; - - union { - struct ast_type_qualifier q; - unsigned i; - } type_qualifier; - - ast_node *node; - ast_type_specifier *type_specifier; - ast_fully_specified_type *fully_specified_type; - ast_function *function; - ast_parameter_declarator *parameter_declarator; - ast_function_definition *function_definition; - ast_compound_statement *compound_statement; - ast_expression *expression; - ast_declarator_list *declarator_list; - ast_struct_specifier *struct_specifier; - ast_declaration *declaration; - - struct { - ast_node *cond; - ast_expression *rest; - } for_rest_statement; - - struct { - ast_node *then_statement; - ast_node *else_statement; - } selection_rest_statement; -} - -%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK -%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT -%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 -%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING -%token NOPERSPECTIVE FLAT SMOOTH -%token MAT2X2 MAT2X3 MAT2X4 -%token MAT3X2 MAT3X3 MAT3X4 -%token MAT4X2 MAT4X3 MAT4X4 -%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW -%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW -%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE -%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D -%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY -%token STRUCT VOID_TOK WHILE -%token <identifier> IDENTIFIER -%token <real> FLOATCONSTANT -%token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT -%token <identifier> FIELD_SELECTION -%token LEFT_OP RIGHT_OP -%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP -%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN -%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN -%token SUB_ASSIGN -%token INVARIANT -%token LOWP MEDIUMP HIGHP SUPERP PRECISION - -%token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT -%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF -%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF -%token LAYOUT_TOK - - /* Reserved words that are not actually used in the grammar. - */ -%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO -%token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL -%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT -%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 -%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW -%token SIZEOF CAST NAMESPACE USING - -%token ERROR_TOK - -%token COMMON PARTITION ACTIVE SAMPLERBUFFER FILTER -%token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY -%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY -%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY -%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER -%token ROW_MAJOR - -%type <identifier> variable_identifier -%type <node> statement -%type <node> statement_list -%type <node> simple_statement -%type <n> precision_qualifier -%type <type_qualifier> type_qualifier -%type <type_qualifier> storage_qualifier -%type <type_qualifier> interpolation_qualifier -%type <type_qualifier> opt_layout_qualifier layout_qualifier -%type <type_qualifier> layout_qualifier_id_list layout_qualifier_id -%type <type_specifier> type_specifier -%type <type_specifier> type_specifier_no_prec -%type <type_specifier> type_specifier_nonarray -%type <n> basic_type_specifier_nonarray -%type <fully_specified_type> fully_specified_type -%type <function> function_prototype -%type <function> function_header -%type <function> function_header_with_parameters -%type <function> function_declarator -%type <parameter_declarator> parameter_declarator -%type <parameter_declarator> parameter_declaration -%type <type_qualifier> parameter_qualifier -%type <type_qualifier> parameter_type_qualifier -%type <type_specifier> parameter_type_specifier -%type <function_definition> function_definition -%type <compound_statement> compound_statement_no_new_scope -%type <compound_statement> compound_statement -%type <node> statement_no_new_scope -%type <node> expression_statement -%type <expression> expression -%type <expression> primary_expression -%type <expression> assignment_expression -%type <expression> conditional_expression -%type <expression> logical_or_expression -%type <expression> logical_xor_expression -%type <expression> logical_and_expression -%type <expression> inclusive_or_expression -%type <expression> exclusive_or_expression -%type <expression> and_expression -%type <expression> equality_expression -%type <expression> relational_expression -%type <expression> shift_expression -%type <expression> additive_expression -%type <expression> multiplicative_expression -%type <expression> unary_expression -%type <expression> constant_expression -%type <expression> integer_expression -%type <expression> postfix_expression -%type <expression> function_call_header_with_parameters -%type <expression> function_call_header_no_parameters -%type <expression> function_call_header -%type <expression> function_call_generic -%type <expression> function_call_or_method -%type <expression> function_call -%type <n> assignment_operator -%type <n> unary_operator -%type <expression> function_identifier -%type <node> external_declaration -%type <declarator_list> init_declarator_list -%type <declarator_list> single_declaration -%type <expression> initializer -%type <node> declaration -%type <node> declaration_statement -%type <node> jump_statement -%type <struct_specifier> struct_specifier -%type <node> struct_declaration_list -%type <declarator_list> struct_declaration -%type <declaration> struct_declarator -%type <declaration> struct_declarator_list -%type <node> selection_statement -%type <selection_rest_statement> selection_rest_statement -%type <node> iteration_statement -%type <node> condition -%type <node> conditionopt -%type <node> for_init_statement -%type <for_rest_statement> for_rest_statement -%% - -translation_unit: - version_statement extension_statement_list - { - _mesa_glsl_initialize_types(state); - } - external_declaration_list - ; - -version_statement: - /* blank - no #version specified: defaults are already set */ - | VERSION INTCONSTANT EOL - { - switch ($2) { - case 100: - state->es_shader = true; - case 110: - case 120: - case 130: - /* FINISHME: Check against implementation support versions. */ - state->language_version = $2; - break; - default: - _mesa_glsl_error(& @2, state, "Shading language version" - "%u is not supported\n", $2); - break; - } - } - ; - -pragma_statement: - PRAGMA_DEBUG_ON EOL - | PRAGMA_DEBUG_OFF EOL - | PRAGMA_OPTIMIZE_ON EOL - | PRAGMA_OPTIMIZE_OFF EOL - ; - -extension_statement_list: - - | extension_statement_list extension_statement - ; - -extension_statement: - EXTENSION IDENTIFIER COLON IDENTIFIER EOL - { - if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) { - YYERROR; - } - } - ; - -external_declaration_list: - external_declaration - { - /* FINISHME: The NULL test is only required because 'precision' - * FINISHME: statements are not yet supported. - */ - if ($1 != NULL) - state->translation_unit.push_tail(& $1->link); - } - | external_declaration_list external_declaration - { - /* FINISHME: The NULL test is only required because 'precision' - * FINISHME: statements are not yet supported. - */ - if ($2 != NULL) - state->translation_unit.push_tail(& $2->link); - } - ; - -variable_identifier: - IDENTIFIER - ; - -primary_expression: - variable_identifier - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.identifier = $1; - } - | INTCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.int_constant = $1; - } - | UINTCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.uint_constant = $1; - } - | FLOATCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.float_constant = $1; - } - | BOOLCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.bool_constant = $1; - } - | '(' expression ')' - { - $$ = $2; - } - ; - -postfix_expression: - primary_expression - | postfix_expression '[' integer_expression ']' - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); - $$->set_location(yylloc); - } - | function_call - { - $$ = $1; - } - | postfix_expression '.' IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.identifier = $3; - } - | postfix_expression INC_OP - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); - $$->set_location(yylloc); - } - | postfix_expression DEC_OP - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); - $$->set_location(yylloc); - } - ; - -integer_expression: - expression - ; - -function_call: - function_call_or_method - ; - -function_call_or_method: - function_call_generic - | postfix_expression '.' function_call_generic - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); - $$->set_location(yylloc); - } - ; - -function_call_generic: - function_call_header_with_parameters ')' - | function_call_header_no_parameters ')' - ; - -function_call_header_no_parameters: - function_call_header VOID_TOK - | function_call_header - ; - -function_call_header_with_parameters: - function_call_header assignment_expression - { - $$ = $1; - $$->set_location(yylloc); - $$->expressions.push_tail(& $2->link); - } - | function_call_header_with_parameters ',' assignment_expression - { - $$ = $1; - $$->set_location(yylloc); - $$->expressions.push_tail(& $3->link); - } - ; - - // Grammar Note: Constructors look like functions, but lexical - // analysis recognized most of them as keywords. They are now - // recognized through "type_specifier". -function_call_header: - function_identifier '(' - ; - -function_identifier: - type_specifier - { - void *ctx = state; - $$ = new(ctx) ast_function_expression($1); - $$->set_location(yylloc); - } - | IDENTIFIER - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression($1); - $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); - } - | FIELD_SELECTION - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression($1); - $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); - } - ; - - // Grammar Note: No traditional style type casts. -unary_expression: - postfix_expression - | INC_OP unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); - $$->set_location(yylloc); - } - | DEC_OP unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); - $$->set_location(yylloc); - } - | unary_operator unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression($1, $2, NULL, NULL); - $$->set_location(yylloc); - } - ; - - // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. -unary_operator: - '+' { $$ = ast_plus; } - | '-' { $$ = ast_neg; } - | '!' { $$ = ast_logic_not; } - | '~' { $$ = ast_bit_not; } - ; - -multiplicative_expression: - unary_expression - | multiplicative_expression '*' unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); - $$->set_location(yylloc); - } - | multiplicative_expression '/' unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); - $$->set_location(yylloc); - } - | multiplicative_expression '%' unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); - $$->set_location(yylloc); - } - ; - -additive_expression: - multiplicative_expression - | additive_expression '+' multiplicative_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); - $$->set_location(yylloc); - } - | additive_expression '-' multiplicative_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); - $$->set_location(yylloc); - } - ; - -shift_expression: - additive_expression - | shift_expression LEFT_OP additive_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); - $$->set_location(yylloc); - } - | shift_expression RIGHT_OP additive_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); - $$->set_location(yylloc); - } - ; - -relational_expression: - shift_expression - | relational_expression '<' shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); - $$->set_location(yylloc); - } - | relational_expression '>' shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); - $$->set_location(yylloc); - } - | relational_expression LE_OP shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); - $$->set_location(yylloc); - } - | relational_expression GE_OP shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); - $$->set_location(yylloc); - } - ; - -equality_expression: - relational_expression - | equality_expression EQ_OP relational_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); - $$->set_location(yylloc); - } - | equality_expression NE_OP relational_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); - $$->set_location(yylloc); - } - ; - -and_expression: - equality_expression - | and_expression '&' equality_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); - $$->set_location(yylloc); - } - ; - -exclusive_or_expression: - and_expression - | exclusive_or_expression '^' and_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); - $$->set_location(yylloc); - } - ; - -inclusive_or_expression: - exclusive_or_expression - | inclusive_or_expression '|' exclusive_or_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); - $$->set_location(yylloc); - } - ; - -logical_and_expression: - inclusive_or_expression - | logical_and_expression AND_OP inclusive_or_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); - $$->set_location(yylloc); - } - ; - -logical_xor_expression: - logical_and_expression - | logical_xor_expression XOR_OP logical_and_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); - $$->set_location(yylloc); - } - ; - -logical_or_expression: - logical_xor_expression - | logical_or_expression OR_OP logical_xor_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); - $$->set_location(yylloc); - } - ; - -conditional_expression: - logical_or_expression - | logical_or_expression '?' expression ':' assignment_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); - $$->set_location(yylloc); - } - ; - -assignment_expression: - conditional_expression - | unary_expression assignment_operator assignment_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression($2, $1, $3, NULL); - $$->set_location(yylloc); - } - ; - -assignment_operator: - '=' { $$ = ast_assign; } - | MUL_ASSIGN { $$ = ast_mul_assign; } - | DIV_ASSIGN { $$ = ast_div_assign; } - | MOD_ASSIGN { $$ = ast_mod_assign; } - | ADD_ASSIGN { $$ = ast_add_assign; } - | SUB_ASSIGN { $$ = ast_sub_assign; } - | LEFT_ASSIGN { $$ = ast_ls_assign; } - | RIGHT_ASSIGN { $$ = ast_rs_assign; } - | AND_ASSIGN { $$ = ast_and_assign; } - | XOR_ASSIGN { $$ = ast_xor_assign; } - | OR_ASSIGN { $$ = ast_or_assign; } - ; - -expression: - assignment_expression - { - $$ = $1; - } - | expression ',' assignment_expression - { - void *ctx = state; - if ($1->oper != ast_sequence) { - $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->expressions.push_tail(& $1->link); - } else { - $$ = $1; - } - - $$->expressions.push_tail(& $3->link); - } - ; - -constant_expression: - conditional_expression - ; - -declaration: - function_prototype ';' - { - $$ = $1; - } - | init_declarator_list ';' - { - $$ = $1; - } - | PRECISION precision_qualifier type_specifier_no_prec ';' - { - if (($3->type_specifier != ast_float) - && ($3->type_specifier != ast_int)) { - _mesa_glsl_error(& @3, state, "global precision qualifier can " - "only be applied to `int' or `float'\n"); - YYERROR; - } - - $$ = NULL; /* FINISHME */ - } - ; - -function_prototype: - function_declarator ')' - ; - -function_declarator: - function_header - | function_header_with_parameters - ; - -function_header_with_parameters: - function_header parameter_declaration - { - $$ = $1; - $$->parameters.push_tail(& $2->link); - } - | function_header_with_parameters ',' parameter_declaration - { - $$ = $1; - $$->parameters.push_tail(& $3->link); - } - ; - -function_header: - fully_specified_type IDENTIFIER '(' - { - void *ctx = state; - $$ = new(ctx) ast_function(); - $$->set_location(yylloc); - $$->return_type = $1; - $$->identifier = $2; - } - ; - -parameter_declarator: - type_specifier IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); - $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); - $$->type->specifier = $1; - $$->identifier = $2; - } - | type_specifier IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); - $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); - $$->type->specifier = $1; - $$->identifier = $2; - $$->is_array = true; - $$->array_size = $4; - } - ; - -parameter_declaration: - parameter_type_qualifier parameter_qualifier parameter_declarator - { - $1.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 = 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 = 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_TOK { $$.i = 0; $$.q.in = 1; } - | OUT_TOK { $$.i = 0; $$.q.out = 1; } - | INOUT_TOK { $$.i = 0; $$.q.in = 1; $$.q.out = 1; } - ; - -parameter_type_specifier: - type_specifier - ; - -init_declarator_list: - single_declaration - | init_declarator_list ',' IDENTIFIER - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - ; - - // Grammar Note: No 'enum', or 'typedef'. -single_declaration: - fully_specified_type - { - void *ctx = state; - if ($1->specifier->type_specifier != ast_struct) { - _mesa_glsl_error(& @1, state, "empty declaration list\n"); - YYERROR; - } else { - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - } - } - | fully_specified_type IDENTIFIER - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | INVARIANT IDENTIFIER // Vertex only. - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); - - $$ = new(ctx) ast_declarator_list(NULL); - $$->set_location(yylloc); - $$->invariant = true; - - $$->declarations.push_tail(&decl->link); - } - ; - -fully_specified_type: - type_specifier - { - void *ctx = state; - $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); - $$->specifier = $1; - } - | type_qualifier type_specifier - { - void *ctx = state; - $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); - $$->qualifier = $1.q; - $$->specifier = $2; - } - ; - -opt_layout_qualifier: - { $$.i = 0; } - | layout_qualifier - ; - -layout_qualifier: - LAYOUT_TOK '(' layout_qualifier_id_list ')' - { - $$ = $3; - } - ; - -layout_qualifier_id_list: - layout_qualifier_id - | layout_qualifier_id_list ',' layout_qualifier_id - { - $$.i = $1.i | $3.i; - } - ; - -layout_qualifier_id: - IDENTIFIER - { - $$.i = 0; - - if (state->ARB_fragment_coord_conventions_enable) { - bool got_one = false; - - if (strcmp($1, "origin_upper_left") == 0) { - got_one = true; - $$.q.origin_upper_left = 1; - } else if (strcmp($1, "pixel_center_integer") == 0) { - got_one = true; - $$.q.pixel_center_integer = 1; - } - - if (state->ARB_fragment_coord_conventions_warn && got_one) { - _mesa_glsl_warning(& @1, state, - "GL_ARB_fragment_coord_conventions layout " - "identifier `%s' used\n", $1); - } - } - - /* If the identifier didn't match any known layout identifiers, - * emit an error. - */ - if ($$.i == 0) { - _mesa_glsl_error(& @1, state, "unrecognized layout identifier " - "`%s'\n", $1); - YYERROR; - } - } - ; - -interpolation_qualifier: - SMOOTH { $$.i = 0; $$.q.smooth = 1; } - | FLAT { $$.i = 0; $$.q.flat = 1; } - | NOPERSPECTIVE { $$.i = 0; $$.q.noperspective = 1; } - ; - -parameter_type_qualifier: - CONST_TOK { $$.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_TOK { $$.i = 0; $$.q.constant = 1; } - | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; } - | opt_layout_qualifier VARYING { $$.i = $1.i; $$.q.varying = 1; } - | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; } - | opt_layout_qualifier IN_TOK { $$.i = 0; $$.q.in = 1; } - | OUT_TOK { $$.i = 0; $$.q.out = 1; } - | CENTROID IN_TOK { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; } - | CENTROID OUT_TOK { $$.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 = state; - $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); - } - | struct_specifier - { - void *ctx = state; - $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); - } - | IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); - } - ; - -basic_type_specifier_nonarray: - VOID_TOK { $$ = ast_void; } - | FLOAT_TOK { $$ = ast_float; } - | INT_TOK { $$ = ast_int; } - | UINT_TOK { $$ = ast_uint; } - | BOOL_TOK { $$ = ast_bool; } - | VEC2 { $$ = ast_vec2; } - | VEC3 { $$ = ast_vec3; } - | VEC4 { $$ = ast_vec4; } - | BVEC2 { $$ = ast_bvec2; } - | BVEC3 { $$ = ast_bvec3; } - | BVEC4 { $$ = ast_bvec4; } - | IVEC2 { $$ = ast_ivec2; } - | IVEC3 { $$ = ast_ivec3; } - | IVEC4 { $$ = ast_ivec4; } - | UVEC2 { $$ = ast_uvec2; } - | UVEC3 { $$ = ast_uvec3; } - | UVEC4 { $$ = ast_uvec4; } - | MAT2X2 { $$ = ast_mat2; } - | MAT2X3 { $$ = ast_mat2x3; } - | MAT2X4 { $$ = ast_mat2x4; } - | MAT3X2 { $$ = ast_mat3x2; } - | MAT3X3 { $$ = ast_mat3; } - | MAT3X4 { $$ = ast_mat3x4; } - | MAT4X2 { $$ = ast_mat4x2; } - | MAT4X3 { $$ = ast_mat4x3; } - | MAT4X4 { $$ = ast_mat4; } - | SAMPLER1D { $$ = ast_sampler1d; } - | SAMPLER2D { $$ = ast_sampler2d; } - | SAMPLER2DRECT { $$ = ast_sampler2drect; } - | SAMPLER3D { $$ = ast_sampler3d; } - | SAMPLERCUBE { $$ = ast_samplercube; } - | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; } - | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; } - | SAMPLER2DRECTSHADOW { $$ = ast_sampler2drectshadow; } - | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; } - | SAMPLER1DARRAY { $$ = ast_sampler1darray; } - | SAMPLER2DARRAY { $$ = ast_sampler2darray; } - | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; } - | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; } - | ISAMPLER1D { $$ = ast_isampler1d; } - | ISAMPLER2D { $$ = ast_isampler2d; } - | ISAMPLER3D { $$ = ast_isampler3d; } - | ISAMPLERCUBE { $$ = ast_isamplercube; } - | ISAMPLER1DARRAY { $$ = ast_isampler1darray; } - | ISAMPLER2DARRAY { $$ = ast_isampler2darray; } - | USAMPLER1D { $$ = ast_usampler1d; } - | USAMPLER2D { $$ = ast_usampler2d; } - | USAMPLER3D { $$ = ast_usampler3d; } - | USAMPLERCUBE { $$ = ast_usamplercube; } - | USAMPLER1DARRAY { $$ = ast_usampler1darray; } - | USAMPLER2DARRAY { $$ = ast_usampler2darray; } - ; - -precision_qualifier: - HIGHP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision qualifier forbidden " - "in GLSL %d.%d (1.30 or later " - "required)\n", - state->language_version / 100, - state->language_version % 100); - - $$ = ast_precision_high; - } - | MEDIUMP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision 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->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision 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 = state; - $$ = new(ctx) ast_struct_specifier($2, $4); - $$->set_location(yylloc); - } - | STRUCT '{' struct_declaration_list '}' - { - void *ctx = state; - $$ = new(ctx) ast_struct_specifier(NULL, $3); - $$->set_location(yylloc); - } - ; - -struct_declaration_list: - struct_declaration - { - $$ = (ast_node *) $1; - $1->link.self_link(); - } - | struct_declaration_list struct_declaration - { - $$ = (ast_node *) $1; - $$->link.insert_before(& $2->link); - } - ; - -struct_declaration: - type_specifier struct_declarator_list ';' - { - void *ctx = state; - ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); - type->set_location(yylloc); - - type->specifier = $1; - $$ = new(ctx) ast_declarator_list(type); - $$->set_location(yylloc); - - $$->declarations.push_degenerate_list_at_head(& $2->link); - } - ; - -struct_declarator_list: - struct_declarator - { - $$ = $1; - $1->link.self_link(); - } - | struct_declarator_list ',' struct_declarator - { - $$ = $1; - $$->link.insert_before(& $3->link); - } - ; - -struct_declarator: - IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_declaration($1, false, NULL, NULL); - $$->set_location(yylloc); - } - | IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - $$ = new(ctx) ast_declaration($1, true, $3, NULL); - $$->set_location(yylloc); - } - ; - -initializer: - assignment_expression - ; - -declaration_statement: - declaration - ; - - // Grammar Note: labeled statements for SWITCH only; 'goto' is not - // supported. -statement: - compound_statement { $$ = (ast_node *) $1; } - | simple_statement - ; - -simple_statement: - declaration_statement - | expression_statement - | selection_statement - | switch_statement { $$ = NULL; } - | case_label { $$ = NULL; } - | iteration_statement - | jump_statement - ; - -compound_statement: - '{' '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(true, NULL); - $$->set_location(yylloc); - } - | '{' statement_list '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(true, $2); - $$->set_location(yylloc); - } - ; - -statement_no_new_scope: - compound_statement_no_new_scope { $$ = (ast_node *) $1; } - | simple_statement - ; - -compound_statement_no_new_scope: - '{' '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(false, NULL); - $$->set_location(yylloc); - } - | '{' statement_list '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(false, $2); - $$->set_location(yylloc); - } - ; - -statement_list: - statement - { - if ($1 == NULL) { - _mesa_glsl_error(& @1, state, "<nil> statement\n"); - assert($1 != NULL); - } - - $$ = $1; - $$->link.self_link(); - } - | statement_list statement - { - if ($2 == NULL) { - _mesa_glsl_error(& @2, state, "<nil> statement\n"); - assert($2 != NULL); - } - $$ = $1; - $$->link.insert_before(& $2->link); - } - ; - -expression_statement: - ';' - { - void *ctx = state; - $$ = new(ctx) ast_expression_statement(NULL); - $$->set_location(yylloc); - } - | expression ';' - { - void *ctx = state; - $$ = new(ctx) ast_expression_statement($1); - $$->set_location(yylloc); - } - ; - -selection_statement: - IF '(' expression ')' selection_rest_statement - { - $$ = new(state) ast_selection_statement($3, $5.then_statement, - $5.else_statement); - $$->set_location(yylloc); - } - ; - -selection_rest_statement: - statement ELSE statement - { - $$.then_statement = $1; - $$.else_statement = $3; - } - | statement - { - $$.then_statement = $1; - $$.else_statement = NULL; - } - ; - -condition: - expression - { - $$ = (ast_node *) $1; - } - | fully_specified_type IDENTIFIER '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); - ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); - decl->set_location(yylloc); - declarator->set_location(yylloc); - - declarator->declarations.push_tail(&decl->link); - $$ = declarator; - } - ; - -switch_statement: - SWITCH '(' expression ')' compound_statement - ; - -case_label: - CASE expression ':' - | DEFAULT ':' - ; - -iteration_statement: - WHILE '(' condition ')' statement_no_new_scope - { - void *ctx = state; - $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, - NULL, $3, NULL, $5); - $$->set_location(yylloc); - } - | DO statement WHILE '(' expression ')' ';' - { - void *ctx = state; - $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, - NULL, $5, NULL, $2); - $$->set_location(yylloc); - } - | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope - { - void *ctx = state; - $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, - $3, $4.cond, $4.rest, $6); - $$->set_location(yylloc); - } - ; - -for_init_statement: - expression_statement - | declaration_statement - ; - -conditionopt: - condition - | /* empty */ - { - $$ = NULL; - } - ; - -for_rest_statement: - conditionopt ';' - { - $$.cond = $1; - $$.rest = NULL; - } - | conditionopt ';' expression - { - $$.cond = $1; - $$.rest = $3; - } - ; - - // Grammar Note: No 'goto'. Gotos are not supported. -jump_statement: - CONTINUE ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); - $$->set_location(yylloc); - } - | BREAK ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); - $$->set_location(yylloc); - } - | RETURN ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); - $$->set_location(yylloc); - } - | RETURN expression ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); - $$->set_location(yylloc); - } - | DISCARD ';' // Fragment shader only. - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); - $$->set_location(yylloc); - } - ; - -external_declaration: - function_definition { $$ = $1; } - | declaration { $$ = $1; } - | pragma_statement { $$ = NULL; } - ; - -function_definition: - function_prototype compound_statement_no_new_scope - { - void *ctx = state; - $$ = new(ctx) ast_function_definition(); - $$->set_location(yylloc); - $$->prototype = $1; - $$->body = $2; - } - ; +%{
+/*
+ * Copyright © 2008, 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "ast.h"
+#include "glsl_parser_extras.h"
+#include "glsl_types.h"
+
+#define YYLEX_PARAM state->scanner
+
+%}
+
+%pure-parser
+%error-verbose
+
+%locations
+%initial-action {
+ @$.first_line = 1;
+ @$.first_column = 1;
+ @$.last_line = 1;
+ @$.last_column = 1;
+ @$.source = 0;
+}
+
+%lex-param {void *scanner}
+%parse-param {struct _mesa_glsl_parse_state *state}
+
+%union {
+ int n;
+ float real;
+ char *identifier;
+
+ struct ast_type_qualifier type_qualifier;
+
+ ast_node *node;
+ ast_type_specifier *type_specifier;
+ ast_fully_specified_type *fully_specified_type;
+ ast_function *function;
+ ast_parameter_declarator *parameter_declarator;
+ ast_function_definition *function_definition;
+ ast_compound_statement *compound_statement;
+ ast_expression *expression;
+ ast_declarator_list *declarator_list;
+ ast_struct_specifier *struct_specifier;
+ ast_declaration *declaration;
+
+ struct {
+ ast_node *cond;
+ ast_expression *rest;
+ } for_rest_statement;
+
+ struct {
+ ast_node *then_statement;
+ ast_node *else_statement;
+ } selection_rest_statement;
+}
+
+%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK
+%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
+%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
+%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING
+%token NOPERSPECTIVE FLAT SMOOTH
+%token MAT2X2 MAT2X3 MAT2X4
+%token MAT3X2 MAT3X3 MAT3X4
+%token MAT4X2 MAT4X3 MAT4X4
+%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
+%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW
+%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE
+%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D
+%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY
+%token STRUCT VOID_TOK WHILE
+%token <identifier> IDENTIFIER
+%token <real> FLOATCONSTANT
+%token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT
+%token <identifier> FIELD_SELECTION
+%token LEFT_OP RIGHT_OP
+%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
+%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
+%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
+%token SUB_ASSIGN
+%token INVARIANT
+%token LOWP MEDIUMP HIGHP SUPERP PRECISION
+
+%token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT
+%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF
+%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF
+%token LAYOUT_TOK
+
+ /* Reserved words that are not actually used in the grammar.
+ */
+%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO
+%token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL
+%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT
+%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
+%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW
+%token SIZEOF CAST NAMESPACE USING
+
+%token ERROR_TOK
+
+%token COMMON PARTITION ACTIVE SAMPLERBUFFER FILTER
+%token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY
+%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY
+%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY
+%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
+%token IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW
+%token ROW_MAJOR
+
+%type <identifier> variable_identifier
+%type <node> statement
+%type <node> statement_list
+%type <node> simple_statement
+%type <n> precision_qualifier
+%type <type_qualifier> type_qualifier
+%type <type_qualifier> storage_qualifier
+%type <type_qualifier> interpolation_qualifier
+%type <type_qualifier> layout_qualifier
+%type <type_qualifier> layout_qualifier_id_list layout_qualifier_id
+%type <type_specifier> type_specifier
+%type <type_specifier> type_specifier_no_prec
+%type <type_specifier> type_specifier_nonarray
+%type <n> basic_type_specifier_nonarray
+%type <fully_specified_type> fully_specified_type
+%type <function> function_prototype
+%type <function> function_header
+%type <function> function_header_with_parameters
+%type <function> function_declarator
+%type <parameter_declarator> parameter_declarator
+%type <parameter_declarator> parameter_declaration
+%type <type_qualifier> parameter_qualifier
+%type <type_qualifier> parameter_type_qualifier
+%type <type_specifier> parameter_type_specifier
+%type <function_definition> function_definition
+%type <compound_statement> compound_statement_no_new_scope
+%type <compound_statement> compound_statement
+%type <node> statement_no_new_scope
+%type <node> expression_statement
+%type <expression> expression
+%type <expression> primary_expression
+%type <expression> assignment_expression
+%type <expression> conditional_expression
+%type <expression> logical_or_expression
+%type <expression> logical_xor_expression
+%type <expression> logical_and_expression
+%type <expression> inclusive_or_expression
+%type <expression> exclusive_or_expression
+%type <expression> and_expression
+%type <expression> equality_expression
+%type <expression> relational_expression
+%type <expression> shift_expression
+%type <expression> additive_expression
+%type <expression> multiplicative_expression
+%type <expression> unary_expression
+%type <expression> constant_expression
+%type <expression> integer_expression
+%type <expression> postfix_expression
+%type <expression> function_call_header_with_parameters
+%type <expression> function_call_header_no_parameters
+%type <expression> function_call_header
+%type <expression> function_call_generic
+%type <expression> function_call_or_method
+%type <expression> function_call
+%type <n> assignment_operator
+%type <n> unary_operator
+%type <expression> function_identifier
+%type <node> external_declaration
+%type <declarator_list> init_declarator_list
+%type <declarator_list> single_declaration
+%type <expression> initializer
+%type <node> declaration
+%type <node> declaration_statement
+%type <node> jump_statement
+%type <struct_specifier> struct_specifier
+%type <node> struct_declaration_list
+%type <declarator_list> struct_declaration
+%type <declaration> struct_declarator
+%type <declaration> struct_declarator_list
+%type <node> selection_statement
+%type <selection_rest_statement> selection_rest_statement
+%type <node> iteration_statement
+%type <node> condition
+%type <node> conditionopt
+%type <node> for_init_statement
+%type <for_rest_statement> for_rest_statement
+%%
+
+translation_unit:
+ version_statement extension_statement_list
+ {
+ _mesa_glsl_initialize_types(state);
+ }
+ external_declaration_list
+ ;
+
+version_statement:
+ /* blank - no #version specified: defaults are already set */
+ | VERSION INTCONSTANT EOL
+ {
+ switch ($2) {
+ case 100:
+ state->es_shader = true;
+ case 110:
+ case 120:
+ case 130:
+ /* FINISHME: Check against implementation support versions. */
+ state->language_version = $2;
+ break;
+ default:
+ _mesa_glsl_error(& @2, state, "Shading language version"
+ "%u is not supported\n", $2);
+ break;
+ }
+ }
+ ;
+
+pragma_statement:
+ PRAGMA_DEBUG_ON EOL
+ | PRAGMA_DEBUG_OFF EOL
+ | PRAGMA_OPTIMIZE_ON EOL
+ | PRAGMA_OPTIMIZE_OFF EOL
+ ;
+
+extension_statement_list:
+
+ | extension_statement_list extension_statement
+ ;
+
+extension_statement:
+ EXTENSION IDENTIFIER COLON IDENTIFIER EOL
+ {
+ if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) {
+ YYERROR;
+ }
+ }
+ ;
+
+external_declaration_list:
+ external_declaration
+ {
+ /* FINISHME: The NULL test is only required because 'precision'
+ * FINISHME: statements are not yet supported.
+ */
+ if ($1 != NULL)
+ state->translation_unit.push_tail(& $1->link);
+ }
+ | external_declaration_list external_declaration
+ {
+ /* FINISHME: The NULL test is only required because 'precision'
+ * FINISHME: statements are not yet supported.
+ */
+ if ($2 != NULL)
+ state->translation_unit.push_tail(& $2->link);
+ }
+ ;
+
+variable_identifier:
+ IDENTIFIER
+ ;
+
+primary_expression:
+ variable_identifier
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.identifier = $1;
+ }
+ | INTCONSTANT
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.int_constant = $1;
+ }
+ | UINTCONSTANT
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.uint_constant = $1;
+ }
+ | FLOATCONSTANT
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.float_constant = $1;
+ }
+ | BOOLCONSTANT
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.bool_constant = $1;
+ }
+ | '(' expression ')'
+ {
+ $$ = $2;
+ }
+ ;
+
+postfix_expression:
+ primary_expression
+ | postfix_expression '[' integer_expression ']'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL);
+ $$->set_location(yylloc);
+ }
+ | function_call
+ {
+ $$ = $1;
+ }
+ | postfix_expression '.' IDENTIFIER
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->primary_expression.identifier = $3;
+ }
+ | postfix_expression INC_OP
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | postfix_expression DEC_OP
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ ;
+
+integer_expression:
+ expression
+ ;
+
+function_call:
+ function_call_or_method
+ ;
+
+function_call_or_method:
+ function_call_generic
+ | postfix_expression '.' function_call_generic
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL);
+ $$->set_location(yylloc);
+ }
+ ;
+
+function_call_generic:
+ function_call_header_with_parameters ')'
+ | function_call_header_no_parameters ')'
+ ;
+
+function_call_header_no_parameters:
+ function_call_header VOID_TOK
+ | function_call_header
+ ;
+
+function_call_header_with_parameters:
+ function_call_header assignment_expression
+ {
+ $$ = $1;
+ $$->set_location(yylloc);
+ $$->expressions.push_tail(& $2->link);
+ }
+ | function_call_header_with_parameters ',' assignment_expression
+ {
+ $$ = $1;
+ $$->set_location(yylloc);
+ $$->expressions.push_tail(& $3->link);
+ }
+ ;
+
+ // Grammar Note: Constructors look like functions, but lexical
+ // analysis recognized most of them as keywords. They are now
+ // recognized through "type_specifier".
+function_call_header:
+ function_identifier '('
+ ;
+
+function_identifier:
+ type_specifier
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_function_expression($1);
+ $$->set_location(yylloc);
+ }
+ | IDENTIFIER
+ {
+ void *ctx = state;
+ ast_expression *callee = new(ctx) ast_expression($1);
+ $$ = new(ctx) ast_function_expression(callee);
+ $$->set_location(yylloc);
+ }
+ | FIELD_SELECTION
+ {
+ void *ctx = state;
+ ast_expression *callee = new(ctx) ast_expression($1);
+ $$ = new(ctx) ast_function_expression(callee);
+ $$->set_location(yylloc);
+ }
+ ;
+
+ // Grammar Note: No traditional style type casts.
+unary_expression:
+ postfix_expression
+ | INC_OP unary_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | DEC_OP unary_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | unary_operator unary_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression($1, $2, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ ;
+
+ // Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
+unary_operator:
+ '+' { $$ = ast_plus; }
+ | '-' { $$ = ast_neg; }
+ | '!' { $$ = ast_logic_not; }
+ | '~' { $$ = ast_bit_not; }
+ ;
+
+multiplicative_expression:
+ unary_expression
+ | multiplicative_expression '*' unary_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | multiplicative_expression '/' unary_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_div, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | multiplicative_expression '%' unary_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+additive_expression:
+ multiplicative_expression
+ | additive_expression '+' multiplicative_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_add, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | additive_expression '-' multiplicative_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+shift_expression:
+ additive_expression
+ | shift_expression LEFT_OP additive_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | shift_expression RIGHT_OP additive_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+relational_expression:
+ shift_expression
+ | relational_expression '<' shift_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_less, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | relational_expression '>' shift_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | relational_expression LE_OP shift_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | relational_expression GE_OP shift_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+equality_expression:
+ relational_expression
+ | equality_expression EQ_OP relational_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3);
+ $$->set_location(yylloc);
+ }
+ | equality_expression NE_OP relational_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+and_expression:
+ equality_expression
+ | and_expression '&' equality_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+exclusive_or_expression:
+ and_expression
+ | exclusive_or_expression '^' and_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+inclusive_or_expression:
+ exclusive_or_expression
+ | inclusive_or_expression '|' exclusive_or_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+logical_and_expression:
+ inclusive_or_expression
+ | logical_and_expression AND_OP inclusive_or_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+logical_xor_expression:
+ logical_and_expression
+ | logical_xor_expression XOR_OP logical_and_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+logical_or_expression:
+ logical_xor_expression
+ | logical_or_expression OR_OP logical_xor_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+conditional_expression:
+ logical_or_expression
+ | logical_or_expression '?' expression ':' assignment_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5);
+ $$->set_location(yylloc);
+ }
+ ;
+
+assignment_expression:
+ conditional_expression
+ | unary_expression assignment_operator assignment_expression
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression($2, $1, $3, NULL);
+ $$->set_location(yylloc);
+ }
+ ;
+
+assignment_operator:
+ '=' { $$ = ast_assign; }
+ | MUL_ASSIGN { $$ = ast_mul_assign; }
+ | DIV_ASSIGN { $$ = ast_div_assign; }
+ | MOD_ASSIGN { $$ = ast_mod_assign; }
+ | ADD_ASSIGN { $$ = ast_add_assign; }
+ | SUB_ASSIGN { $$ = ast_sub_assign; }
+ | LEFT_ASSIGN { $$ = ast_ls_assign; }
+ | RIGHT_ASSIGN { $$ = ast_rs_assign; }
+ | AND_ASSIGN { $$ = ast_and_assign; }
+ | XOR_ASSIGN { $$ = ast_xor_assign; }
+ | OR_ASSIGN { $$ = ast_or_assign; }
+ ;
+
+expression:
+ assignment_expression
+ {
+ $$ = $1;
+ }
+ | expression ',' assignment_expression
+ {
+ void *ctx = state;
+ if ($1->oper != ast_sequence) {
+ $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL);
+ $$->set_location(yylloc);
+ $$->expressions.push_tail(& $1->link);
+ } else {
+ $$ = $1;
+ }
+
+ $$->expressions.push_tail(& $3->link);
+ }
+ ;
+
+constant_expression:
+ conditional_expression
+ ;
+
+declaration:
+ function_prototype ';'
+ {
+ $$ = $1;
+ }
+ | init_declarator_list ';'
+ {
+ $$ = $1;
+ }
+ | PRECISION precision_qualifier type_specifier_no_prec ';'
+ {
+ if (($3->type_specifier != ast_float)
+ && ($3->type_specifier != ast_int)) {
+ _mesa_glsl_error(& @3, state, "global precision qualifier can "
+ "only be applied to `int' or `float'\n");
+ YYERROR;
+ }
+
+ $$ = NULL; /* FINISHME */
+ }
+ ;
+
+function_prototype:
+ function_declarator ')'
+ ;
+
+function_declarator:
+ function_header
+ | function_header_with_parameters
+ ;
+
+function_header_with_parameters:
+ function_header parameter_declaration
+ {
+ $$ = $1;
+ $$->parameters.push_tail(& $2->link);
+ }
+ | function_header_with_parameters ',' parameter_declaration
+ {
+ $$ = $1;
+ $$->parameters.push_tail(& $3->link);
+ }
+ ;
+
+function_header:
+ fully_specified_type IDENTIFIER '('
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_function();
+ $$->set_location(yylloc);
+ $$->return_type = $1;
+ $$->identifier = $2;
+ }
+ ;
+
+parameter_declarator:
+ type_specifier IDENTIFIER
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_parameter_declarator();
+ $$->set_location(yylloc);
+ $$->type = new(ctx) ast_fully_specified_type();
+ $$->type->set_location(yylloc);
+ $$->type->specifier = $1;
+ $$->identifier = $2;
+ }
+ | type_specifier IDENTIFIER '[' constant_expression ']'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_parameter_declarator();
+ $$->set_location(yylloc);
+ $$->type = new(ctx) ast_fully_specified_type();
+ $$->type->set_location(yylloc);
+ $$->type->specifier = $1;
+ $$->identifier = $2;
+ $$->is_array = true;
+ $$->array_size = $4;
+ }
+ ;
+
+parameter_declaration:
+ parameter_type_qualifier parameter_qualifier parameter_declarator
+ {
+ $1.flags.i |= $2.flags.i;
+
+ $$ = $3;
+ $$->type->qualifier = $1;
+ }
+ | parameter_qualifier parameter_declarator
+ {
+ $$ = $2;
+ $$->type->qualifier = $1;
+ }
+ | parameter_type_qualifier parameter_qualifier parameter_type_specifier
+ {
+ void *ctx = state;
+ $1.flags.i |= $2.flags.i;
+
+ $$ = new(ctx) ast_parameter_declarator();
+ $$->set_location(yylloc);
+ $$->type = new(ctx) ast_fully_specified_type();
+ $$->type->qualifier = $1;
+ $$->type->specifier = $3;
+ }
+ | parameter_qualifier parameter_type_specifier
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_parameter_declarator();
+ $$->set_location(yylloc);
+ $$->type = new(ctx) ast_fully_specified_type();
+ $$->type->qualifier = $1;
+ $$->type->specifier = $2;
+ }
+ ;
+
+parameter_qualifier:
+ /* empty */
+ {
+ memset(& $$, 0, sizeof($$));
+ }
+ | IN_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.in = 1;
+ }
+ | OUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.out = 1;
+ }
+ | INOUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.in = 1;
+ $$.flags.q.out = 1;
+ }
+ ;
+
+parameter_type_specifier:
+ type_specifier
+ ;
+
+init_declarator_list:
+ single_declaration
+ | init_declarator_list ',' IDENTIFIER
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ }
+ | init_declarator_list ',' IDENTIFIER '[' ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ }
+ | init_declarator_list ',' IDENTIFIER '[' constant_expression ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ }
+ | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ }
+ | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ }
+ | init_declarator_list ',' IDENTIFIER '=' initializer
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ }
+ ;
+
+ // Grammar Note: No 'enum', or 'typedef'.
+single_declaration:
+ fully_specified_type
+ {
+ void *ctx = state;
+ if ($1->specifier->type_specifier != ast_struct) {
+ _mesa_glsl_error(& @1, state, "empty declaration list\n");
+ YYERROR;
+ } else {
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ }
+ }
+ | fully_specified_type IDENTIFIER
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | fully_specified_type IDENTIFIER '[' ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | fully_specified_type IDENTIFIER '[' constant_expression ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | fully_specified_type IDENTIFIER '[' ']' '=' initializer
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | fully_specified_type IDENTIFIER '=' initializer
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | INVARIANT IDENTIFIER // Vertex only.
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
+
+ $$ = new(ctx) ast_declarator_list(NULL);
+ $$->set_location(yylloc);
+ $$->invariant = true;
+
+ $$->declarations.push_tail(&decl->link);
+ }
+ ;
+
+fully_specified_type:
+ type_specifier
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_fully_specified_type();
+ $$->set_location(yylloc);
+ $$->specifier = $1;
+ }
+ | type_qualifier type_specifier
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_fully_specified_type();
+ $$->set_location(yylloc);
+ $$->qualifier = $1;
+ $$->specifier = $2;
+ }
+ ;
+
+layout_qualifier:
+ LAYOUT_TOK '(' layout_qualifier_id_list ')'
+ {
+ $$ = $3;
+ }
+ ;
+
+layout_qualifier_id_list:
+ layout_qualifier_id
+ | layout_qualifier_id_list ',' layout_qualifier_id
+ {
+ if (($1.flags.i & $3.flags.i) != 0) {
+ _mesa_glsl_error(& @3, state,
+ "duplicate layout qualifiers used\n");
+ YYERROR;
+ }
+
+ $$.flags.i = $1.flags.i | $3.flags.i;
+
+ if ($1.flags.q.explicit_location)
+ $$.location = $1.location;
+
+ if ($3.flags.q.explicit_location)
+ $$.location = $3.location;
+ }
+ ;
+
+layout_qualifier_id:
+ IDENTIFIER
+ {
+ bool got_one = false;
+
+ memset(& $$, 0, sizeof($$));
+
+ if (state->ARB_fragment_coord_conventions_enable) {
+ if (strcmp($1, "origin_upper_left") == 0) {
+ got_one = true;
+ $$.flags.q.origin_upper_left = 1;
+ } else if (strcmp($1, "pixel_center_integer") == 0) {
+ got_one = true;
+ $$.flags.q.pixel_center_integer = 1;
+ }
+ }
+
+ /* If the identifier didn't match any known layout identifiers,
+ * emit an error.
+ */
+ if (!got_one) {
+ _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+ "`%s'\n", $1);
+ YYERROR;
+ } else if (state->ARB_fragment_coord_conventions_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "GL_ARB_fragment_coord_conventions layout "
+ "identifier `%s' used\n", $1);
+ }
+ }
+ | IDENTIFIER '=' INTCONSTANT
+ {
+ bool got_one = false;
+
+ memset(& $$, 0, sizeof($$));
+
+ if (state->ARB_explicit_attrib_location_enable) {
+ /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
+ * FINISHME: GLSL 1.30 (or later) are supported.
+ */
+ if (strcmp("location", $1) == 0) {
+ got_one = true;
+
+ $$.flags.q.explicit_location = 1;
+
+ if ($3 >= 0) {
+ $$.location = $3;
+ } else {
+ _mesa_glsl_error(& @3, state,
+ "invalid location %d specified\n", $3);
+ YYERROR;
+ }
+ }
+ }
+
+ /* If the identifier didn't match any known layout identifiers,
+ * emit an error.
+ */
+ if (!got_one) {
+ _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+ "`%s'\n", $1);
+ YYERROR;
+ } else if (state->ARB_explicit_attrib_location_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "GL_ARB_explicit_attrib_location layout "
+ "identifier `%s' used\n", $1);
+ }
+ }
+ ;
+
+interpolation_qualifier:
+ SMOOTH
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.smooth = 1;
+ }
+ | FLAT
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.flat = 1;
+ }
+ | NOPERSPECTIVE
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.noperspective = 1;
+ }
+ ;
+
+parameter_type_qualifier:
+ CONST_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.constant = 1;
+ }
+ ;
+
+type_qualifier:
+ storage_qualifier
+ | layout_qualifier
+ | layout_qualifier storage_qualifier
+ {
+ $$ = $1;
+ $$.flags.i |= $2.flags.i;
+ }
+ | interpolation_qualifier
+ | interpolation_qualifier storage_qualifier
+ {
+ $$ = $1;
+ $$.flags.i |= $2.flags.i;
+ }
+ | INVARIANT storage_qualifier
+ {
+ $$ = $2;
+ $$.flags.q.invariant = 1;
+ }
+ | INVARIANT interpolation_qualifier storage_qualifier
+ {
+ $$ = $2;
+ $$.flags.i |= $3.flags.i;
+ $$.flags.q.invariant = 1;
+ }
+ | INVARIANT
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.invariant = 1;
+ }
+ ;
+
+storage_qualifier:
+ CONST_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.constant = 1;
+ }
+ | ATTRIBUTE
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.attribute = 1;
+ }
+ | VARYING
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.varying = 1;
+ }
+ | CENTROID VARYING
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.centroid = 1;
+ $$.flags.q.varying = 1;
+ }
+ | IN_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.in = 1;
+ }
+ | OUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.out = 1;
+ }
+ | CENTROID IN_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.centroid = 1; $$.flags.q.in = 1;
+ }
+ | CENTROID OUT_TOK
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.centroid = 1; $$.flags.q.out = 1;
+ }
+ | UNIFORM
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.uniform = 1;
+ }
+ ;
+
+type_specifier:
+ type_specifier_no_prec
+ | precision_qualifier type_specifier_no_prec
+ {
+ $$ = $2;
+ $$->precision = $1;
+ }
+ ;
+
+type_specifier_no_prec:
+ type_specifier_nonarray
+ | type_specifier_nonarray '[' ']'
+ {
+ $$ = $1;
+ $$->is_array = true;
+ $$->array_size = NULL;
+ }
+ | type_specifier_nonarray '[' constant_expression ']'
+ {
+ $$ = $1;
+ $$->is_array = true;
+ $$->array_size = $3;
+ }
+ ;
+
+type_specifier_nonarray:
+ basic_type_specifier_nonarray
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_type_specifier($1);
+ $$->set_location(yylloc);
+ }
+ | struct_specifier
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_type_specifier($1);
+ $$->set_location(yylloc);
+ }
+ | IDENTIFIER
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_type_specifier($1);
+ $$->set_location(yylloc);
+ }
+ ;
+
+basic_type_specifier_nonarray:
+ VOID_TOK { $$ = ast_void; }
+ | FLOAT_TOK { $$ = ast_float; }
+ | INT_TOK { $$ = ast_int; }
+ | UINT_TOK { $$ = ast_uint; }
+ | BOOL_TOK { $$ = ast_bool; }
+ | VEC2 { $$ = ast_vec2; }
+ | VEC3 { $$ = ast_vec3; }
+ | VEC4 { $$ = ast_vec4; }
+ | BVEC2 { $$ = ast_bvec2; }
+ | BVEC3 { $$ = ast_bvec3; }
+ | BVEC4 { $$ = ast_bvec4; }
+ | IVEC2 { $$ = ast_ivec2; }
+ | IVEC3 { $$ = ast_ivec3; }
+ | IVEC4 { $$ = ast_ivec4; }
+ | UVEC2 { $$ = ast_uvec2; }
+ | UVEC3 { $$ = ast_uvec3; }
+ | UVEC4 { $$ = ast_uvec4; }
+ | MAT2X2 { $$ = ast_mat2; }
+ | MAT2X3 { $$ = ast_mat2x3; }
+ | MAT2X4 { $$ = ast_mat2x4; }
+ | MAT3X2 { $$ = ast_mat3x2; }
+ | MAT3X3 { $$ = ast_mat3; }
+ | MAT3X4 { $$ = ast_mat3x4; }
+ | MAT4X2 { $$ = ast_mat4x2; }
+ | MAT4X3 { $$ = ast_mat4x3; }
+ | MAT4X4 { $$ = ast_mat4; }
+ | SAMPLER1D { $$ = ast_sampler1d; }
+ | SAMPLER2D { $$ = ast_sampler2d; }
+ | SAMPLER2DRECT { $$ = ast_sampler2drect; }
+ | SAMPLER3D { $$ = ast_sampler3d; }
+ | SAMPLERCUBE { $$ = ast_samplercube; }
+ | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; }
+ | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; }
+ | SAMPLER2DRECTSHADOW { $$ = ast_sampler2drectshadow; }
+ | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; }
+ | SAMPLER1DARRAY { $$ = ast_sampler1darray; }
+ | SAMPLER2DARRAY { $$ = ast_sampler2darray; }
+ | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; }
+ | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; }
+ | ISAMPLER1D { $$ = ast_isampler1d; }
+ | ISAMPLER2D { $$ = ast_isampler2d; }
+ | ISAMPLER3D { $$ = ast_isampler3d; }
+ | ISAMPLERCUBE { $$ = ast_isamplercube; }
+ | ISAMPLER1DARRAY { $$ = ast_isampler1darray; }
+ | ISAMPLER2DARRAY { $$ = ast_isampler2darray; }
+ | USAMPLER1D { $$ = ast_usampler1d; }
+ | USAMPLER2D { $$ = ast_usampler2d; }
+ | USAMPLER3D { $$ = ast_usampler3d; }
+ | USAMPLERCUBE { $$ = ast_usamplercube; }
+ | USAMPLER1DARRAY { $$ = ast_usampler1darray; }
+ | USAMPLER2DARRAY { $$ = ast_usampler2darray; }
+ ;
+
+precision_qualifier:
+ HIGHP {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precision qualifier forbidden "
+ "in GLSL %d.%d (1.30 or later "
+ "required)\n",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ $$ = ast_precision_high;
+ }
+ | MEDIUMP {
+ if (!state->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precision 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->es_shader && state->language_version < 130)
+ _mesa_glsl_error(& @1, state,
+ "precision 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 = state;
+ $$ = new(ctx) ast_struct_specifier($2, $4);
+ $$->set_location(yylloc);
+ }
+ | STRUCT '{' struct_declaration_list '}'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_struct_specifier(NULL, $3);
+ $$->set_location(yylloc);
+ }
+ ;
+
+struct_declaration_list:
+ struct_declaration
+ {
+ $$ = (ast_node *) $1;
+ $1->link.self_link();
+ }
+ | struct_declaration_list struct_declaration
+ {
+ $$ = (ast_node *) $1;
+ $$->link.insert_before(& $2->link);
+ }
+ ;
+
+struct_declaration:
+ type_specifier struct_declarator_list ';'
+ {
+ void *ctx = state;
+ ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
+ type->set_location(yylloc);
+
+ type->specifier = $1;
+ $$ = new(ctx) ast_declarator_list(type);
+ $$->set_location(yylloc);
+
+ $$->declarations.push_degenerate_list_at_head(& $2->link);
+ }
+ ;
+
+struct_declarator_list:
+ struct_declarator
+ {
+ $$ = $1;
+ $1->link.self_link();
+ }
+ | struct_declarator_list ',' struct_declarator
+ {
+ $$ = $1;
+ $$->link.insert_before(& $3->link);
+ }
+ ;
+
+struct_declarator:
+ IDENTIFIER
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_declaration($1, false, NULL, NULL);
+ $$->set_location(yylloc);
+ }
+ | IDENTIFIER '[' constant_expression ']'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_declaration($1, true, $3, NULL);
+ $$->set_location(yylloc);
+ }
+ ;
+
+initializer:
+ assignment_expression
+ ;
+
+declaration_statement:
+ declaration
+ ;
+
+ // Grammar Note: labeled statements for SWITCH only; 'goto' is not
+ // supported.
+statement:
+ compound_statement { $$ = (ast_node *) $1; }
+ | simple_statement
+ ;
+
+simple_statement:
+ declaration_statement
+ | expression_statement
+ | selection_statement
+ | switch_statement { $$ = NULL; }
+ | case_label { $$ = NULL; }
+ | iteration_statement
+ | jump_statement
+ ;
+
+compound_statement:
+ '{' '}'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_compound_statement(true, NULL);
+ $$->set_location(yylloc);
+ }
+ | '{' statement_list '}'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_compound_statement(true, $2);
+ $$->set_location(yylloc);
+ }
+ ;
+
+statement_no_new_scope:
+ compound_statement_no_new_scope { $$ = (ast_node *) $1; }
+ | simple_statement
+ ;
+
+compound_statement_no_new_scope:
+ '{' '}'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_compound_statement(false, NULL);
+ $$->set_location(yylloc);
+ }
+ | '{' statement_list '}'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_compound_statement(false, $2);
+ $$->set_location(yylloc);
+ }
+ ;
+
+statement_list:
+ statement
+ {
+ if ($1 == NULL) {
+ _mesa_glsl_error(& @1, state, "<nil> statement\n");
+ assert($1 != NULL);
+ }
+
+ $$ = $1;
+ $$->link.self_link();
+ }
+ | statement_list statement
+ {
+ if ($2 == NULL) {
+ _mesa_glsl_error(& @2, state, "<nil> statement\n");
+ assert($2 != NULL);
+ }
+ $$ = $1;
+ $$->link.insert_before(& $2->link);
+ }
+ ;
+
+expression_statement:
+ ';'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_statement(NULL);
+ $$->set_location(yylloc);
+ }
+ | expression ';'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_expression_statement($1);
+ $$->set_location(yylloc);
+ }
+ ;
+
+selection_statement:
+ IF '(' expression ')' selection_rest_statement
+ {
+ $$ = new(state) ast_selection_statement($3, $5.then_statement,
+ $5.else_statement);
+ $$->set_location(yylloc);
+ }
+ ;
+
+selection_rest_statement:
+ statement ELSE statement
+ {
+ $$.then_statement = $1;
+ $$.else_statement = $3;
+ }
+ | statement
+ {
+ $$.then_statement = $1;
+ $$.else_statement = NULL;
+ }
+ ;
+
+condition:
+ expression
+ {
+ $$ = (ast_node *) $1;
+ }
+ | fully_specified_type IDENTIFIER '=' initializer
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4);
+ ast_declarator_list *declarator = new(ctx) ast_declarator_list($1);
+ decl->set_location(yylloc);
+ declarator->set_location(yylloc);
+
+ declarator->declarations.push_tail(&decl->link);
+ $$ = declarator;
+ }
+ ;
+
+switch_statement:
+ SWITCH '(' expression ')' compound_statement
+ ;
+
+case_label:
+ CASE expression ':'
+ | DEFAULT ':'
+ ;
+
+iteration_statement:
+ WHILE '(' condition ')' statement_no_new_scope
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while,
+ NULL, $3, NULL, $5);
+ $$->set_location(yylloc);
+ }
+ | DO statement WHILE '(' expression ')' ';'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while,
+ NULL, $5, NULL, $2);
+ $$->set_location(yylloc);
+ }
+ | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for,
+ $3, $4.cond, $4.rest, $6);
+ $$->set_location(yylloc);
+ }
+ ;
+
+for_init_statement:
+ expression_statement
+ | declaration_statement
+ ;
+
+conditionopt:
+ condition
+ | /* empty */
+ {
+ $$ = NULL;
+ }
+ ;
+
+for_rest_statement:
+ conditionopt ';'
+ {
+ $$.cond = $1;
+ $$.rest = NULL;
+ }
+ | conditionopt ';' expression
+ {
+ $$.cond = $1;
+ $$.rest = $3;
+ }
+ ;
+
+ // Grammar Note: No 'goto'. Gotos are not supported.
+jump_statement:
+ CONTINUE ';'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL);
+ $$->set_location(yylloc);
+ }
+ | BREAK ';'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL);
+ $$->set_location(yylloc);
+ }
+ | RETURN ';'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL);
+ $$->set_location(yylloc);
+ }
+ | RETURN expression ';'
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2);
+ $$->set_location(yylloc);
+ }
+ | DISCARD ';' // Fragment shader only.
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL);
+ $$->set_location(yylloc);
+ }
+ ;
+
+external_declaration:
+ function_definition { $$ = $1; }
+ | declaration { $$ = $1; }
+ | pragma_statement { $$ = NULL; }
+ ;
+
+function_definition:
+ function_prototype compound_statement_no_new_scope
+ {
+ void *ctx = state;
+ $$ = new(ctx) ast_function_definition();
+ $$->set_location(yylloc);
+ $$->prototype = $1;
+ $$->body = $2;
+ }
+ ;
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 33ea664bc..b320e6798 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -1,762 +1,777 @@ -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <assert.h> - -extern "C" { -#include <talloc.h> -#include "main/core.h" /* for struct __GLcontextRec */ -} - -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_parser.h" -#include "ir_optimization.h" -#include "loop_analysis.h" - -_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct __GLcontextRec *ctx, - GLenum target, void *mem_ctx) -{ - switch (target) { - case GL_VERTEX_SHADER: this->target = vertex_shader; break; - case GL_FRAGMENT_SHADER: this->target = fragment_shader; break; - case GL_GEOMETRY_SHADER: this->target = geometry_shader; break; - } - - this->scanner = NULL; - this->translation_unit.make_empty(); - this->symbols = new(mem_ctx) glsl_symbol_table; - this->info_log = talloc_strdup(mem_ctx, ""); - this->error = false; - this->loop_or_switch_nesting = NULL; - - /* Set default language version and extensions */ - this->language_version = 110; - this->es_shader = false; - this->ARB_texture_rectangle_enable = true; - - /* OpenGL ES 2.0 has different defaults from desktop GL. */ - if (ctx->API == API_OPENGLES2) { - this->language_version = 100; - this->es_shader = true; - this->ARB_texture_rectangle_enable = false; - } - - this->extensions = &ctx->Extensions; - - this->Const.MaxLights = ctx->Const.MaxLights; - this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes; - this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits; - this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; - this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs; - this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents; - this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4; - this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits; - this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; - this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; - this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents; - - this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; -} - -const char * -_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) -{ - switch (target) { - case vertex_shader: return "vertex"; - case fragment_shader: return "fragment"; - case geometry_shader: return "geometry"; - case ir_shader: break; - } - - assert(!"Should not get here."); - return "unknown"; -} - - -void -_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, - const char *fmt, ...) -{ - va_list ap; - - state->error = true; - - assert(state->info_log != NULL); - state->info_log = talloc_asprintf_append(state->info_log, - "%u:%u(%u): error: ", - locp->source, - locp->first_line, - locp->first_column); - va_start(ap, fmt); - state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap); - va_end(ap); - state->info_log = talloc_strdup_append(state->info_log, "\n"); -} - - -void -_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, - const char *fmt, ...) -{ - va_list ap; - - assert(state->info_log != NULL); - state->info_log = talloc_asprintf_append(state->info_log, - "%u:%u(%u): warning: ", - locp->source, - locp->first_line, - locp->first_column); - va_start(ap, fmt); - state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap); - va_end(ap); - state->info_log = talloc_strdup_append(state->info_log, "\n"); -} - - -bool -_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, - const char *behavior, YYLTYPE *behavior_locp, - _mesa_glsl_parse_state *state) -{ - enum { - extension_disable, - extension_enable, - extension_require, - extension_warn - } ext_mode; - - if (strcmp(behavior, "warn") == 0) { - ext_mode = extension_warn; - } else if (strcmp(behavior, "require") == 0) { - ext_mode = extension_require; - } else if (strcmp(behavior, "enable") == 0) { - ext_mode = extension_enable; - } else if (strcmp(behavior, "disable") == 0) { - ext_mode = extension_disable; - } else { - _mesa_glsl_error(behavior_locp, state, - "Unknown extension behavior `%s'", - behavior); - return false; - } - - bool unsupported = false; - - if (strcmp(name, "all") == 0) { - if ((ext_mode == extension_enable) || (ext_mode == extension_require)) { - _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", - (ext_mode == extension_enable) - ? "enable" : "require"); - return false; - } - } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) { - /* This extension is only supported in fragment shaders. - */ - if (state->target != fragment_shader) { - unsupported = true; - } else { - state->ARB_draw_buffers_enable = (ext_mode != extension_disable); - state->ARB_draw_buffers_warn = (ext_mode == extension_warn); - } - } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) { - state->ARB_fragment_coord_conventions_enable = - (ext_mode != extension_disable); - state->ARB_fragment_coord_conventions_warn = - (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_fragment_coord_conventions; - } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) { - state->ARB_texture_rectangle_enable = (ext_mode != extension_disable); - state->ARB_texture_rectangle_warn = (ext_mode == extension_warn); - } else if (strcmp(name, "GL_EXT_texture_array") == 0) { - state->EXT_texture_array_enable = (ext_mode != extension_disable); - state->EXT_texture_array_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->EXT_texture_array; - } else { - 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) -{ - this->location.source = 0; - this->location.line = 0; - this->location.column = 0; -} - - -static void -ast_opt_array_size_print(bool is_array, const ast_expression *array_size) -{ - if (is_array) { - printf("[ "); - - if (array_size) - array_size->print(); - - printf("] "); - } -} - - -void -ast_compound_statement::print(void) const -{ - printf("{\n"); - - foreach_list_const(n, &this->statements) { - ast_node *ast = exec_node_data(ast_node, n, link); - ast->print(); - } - - printf("}\n"); -} - - -ast_compound_statement::ast_compound_statement(int new_scope, - ast_node *statements) -{ - this->new_scope = new_scope; - - if (statements != NULL) { - this->statements.push_degenerate_list_at_head(&statements->link); - } -} - - -void -ast_expression::print(void) const -{ - switch (oper) { - case ast_assign: - case ast_mul_assign: - case ast_div_assign: - case ast_mod_assign: - case ast_add_assign: - case ast_sub_assign: - case ast_ls_assign: - case ast_rs_assign: - case ast_and_assign: - case ast_xor_assign: - case ast_or_assign: - subexpressions[0]->print(); - printf("%s ", operator_string(oper)); - subexpressions[1]->print(); - break; - - case ast_field_selection: - subexpressions[0]->print(); - printf(". %s ", primary_expression.identifier); - break; - - case ast_plus: - case ast_neg: - case ast_bit_not: - case ast_logic_not: - case ast_pre_inc: - case ast_pre_dec: - printf("%s ", operator_string(oper)); - subexpressions[0]->print(); - break; - - case ast_post_inc: - case ast_post_dec: - subexpressions[0]->print(); - printf("%s ", operator_string(oper)); - break; - - case ast_conditional: - subexpressions[0]->print(); - printf("? "); - subexpressions[1]->print(); - printf(": "); - subexpressions[1]->print(); - break; - - case ast_array_index: - subexpressions[0]->print(); - printf("[ "); - subexpressions[1]->print(); - printf("] "); - break; - - case ast_function_call: { - subexpressions[0]->print(); - printf("( "); - - foreach_list_const (n, &this->expressions) { - if (n != this->expressions.get_head()) - printf(", "); - - ast_node *ast = exec_node_data(ast_node, n, link); - ast->print(); - } - - printf(") "); - break; - } - - case ast_identifier: - printf("%s ", primary_expression.identifier); - break; - - case ast_int_constant: - printf("%d ", primary_expression.int_constant); - break; - - case ast_uint_constant: - printf("%u ", primary_expression.uint_constant); - break; - - case ast_float_constant: - printf("%f ", primary_expression.float_constant); - break; - - case ast_bool_constant: - printf("%s ", - primary_expression.bool_constant - ? "true" : "false"); - break; - - case ast_sequence: { - printf("( "); - foreach_list_const(n, & this->expressions) { - if (n != this->expressions.get_head()) - printf(", "); - - ast_node *ast = exec_node_data(ast_node, n, link); - ast->print(); - } - printf(") "); - break; - } - - default: - assert(0); - break; - } -} - -ast_expression::ast_expression(int oper, - ast_expression *ex0, - ast_expression *ex1, - ast_expression *ex2) -{ - this->oper = ast_operators(oper); - this->subexpressions[0] = ex0; - this->subexpressions[1] = ex1; - this->subexpressions[2] = ex2; -} - - -void -ast_expression_statement::print(void) const -{ - if (expression) - expression->print(); - - printf("; "); -} - - -ast_expression_statement::ast_expression_statement(ast_expression *ex) : - expression(ex) -{ - /* empty */ -} - - -void -ast_function::print(void) const -{ - return_type->print(); - printf(" %s (", identifier); - - foreach_list_const(n, & this->parameters) { - ast_node *ast = exec_node_data(ast_node, n, link); - ast->print(); - } - - printf(")"); -} - - -ast_function::ast_function(void) - : is_definition(false), signature(NULL) -{ - /* empty */ -} - - -void -ast_fully_specified_type::print(void) const -{ - _mesa_ast_type_qualifier_print(& qualifier); - specifier->print(); -} - - -void -ast_parameter_declarator::print(void) const -{ - type->print(); - if (identifier) - printf("%s ", identifier); - ast_opt_array_size_print(is_array, array_size); -} - - -void -ast_function_definition::print(void) const -{ - prototype->print(); - body->print(); -} - - -void -ast_declaration::print(void) const -{ - printf("%s ", identifier); - ast_opt_array_size_print(is_array, array_size); - - if (initializer) { - printf("= "); - initializer->print(); - } -} - - -ast_declaration::ast_declaration(char *identifier, int is_array, - ast_expression *array_size, - ast_expression *initializer) -{ - this->identifier = identifier; - this->is_array = is_array; - this->array_size = array_size; - this->initializer = initializer; -} - - -void -ast_declarator_list::print(void) const -{ - assert(type || invariant); - - if (type) - type->print(); - else - printf("invariant "); - - foreach_list_const (ptr, & this->declarations) { - if (ptr != this->declarations.get_head()) - printf(", "); - - ast_node *ast = exec_node_data(ast_node, ptr, link); - ast->print(); - } - - printf("; "); -} - - -ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) -{ - this->type = type; - this->invariant = false; -} - -void -ast_jump_statement::print(void) const -{ - switch (mode) { - case ast_continue: - printf("continue; "); - break; - case ast_break: - printf("break; "); - break; - case ast_return: - printf("return "); - if (opt_return_value) - opt_return_value->print(); - - printf("; "); - break; - case ast_discard: - printf("discard; "); - break; - } -} - - -ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value) -{ - this->mode = ast_jump_modes(mode); - - if (mode == ast_return) - opt_return_value = return_value; -} - - -void -ast_selection_statement::print(void) const -{ - printf("if ( "); - condition->print(); - printf(") "); - - then_statement->print(); - - if (else_statement) { - printf("else "); - else_statement->print(); - } - -} - - -ast_selection_statement::ast_selection_statement(ast_expression *condition, - ast_node *then_statement, - ast_node *else_statement) -{ - this->condition = condition; - this->then_statement = then_statement; - this->else_statement = else_statement; -} - - -void -ast_iteration_statement::print(void) const -{ - switch (mode) { - case ast_for: - printf("for( "); - if (init_statement) - init_statement->print(); - printf("; "); - - if (condition) - condition->print(); - printf("; "); - - if (rest_expression) - rest_expression->print(); - printf(") "); - - body->print(); - break; - - case ast_while: - printf("while ( "); - if (condition) - condition->print(); - printf(") "); - body->print(); - break; - - case ast_do_while: - printf("do "); - body->print(); - printf("while ( "); - if (condition) - condition->print(); - printf("); "); - break; - } -} - - -ast_iteration_statement::ast_iteration_statement(int mode, - ast_node *init, - ast_node *condition, - ast_expression *rest_expression, - ast_node *body) -{ - this->mode = ast_iteration_modes(mode); - this->init_statement = init; - this->condition = condition; - this->rest_expression = rest_expression; - this->body = body; -} - - -void -ast_struct_specifier::print(void) const -{ - printf("struct %s { ", name); - foreach_list_const(n, &this->declarations) { - ast_node *ast = exec_node_data(ast_node, n, link); - ast->print(); - } - printf("} "); -} - - -ast_struct_specifier::ast_struct_specifier(char *identifier, - ast_node *declarator_list) -{ - if (identifier == NULL) { - static unsigned anon_count = 1; - identifier = talloc_asprintf(this, "#anon_struct_%04x", anon_count); - anon_count++; - } - name = identifier; - this->declarations.push_degenerate_list_at_head(&declarator_list->link); -} - -bool -do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations) -{ - GLboolean progress = GL_FALSE; - - progress = do_sub_to_add_neg(ir) || progress; - - if (linked) { - progress = do_function_inlining(ir) || progress; - progress = do_dead_functions(ir) || progress; - } - progress = do_structure_splitting(ir) || progress; - progress = do_if_simplification(ir) || progress; - progress = do_copy_propagation(ir) || progress; - if (linked) - progress = do_dead_code(ir) || progress; - else - progress = do_dead_code_unlinked(ir) || progress; - progress = do_dead_code_local(ir) || progress; - progress = do_tree_grafting(ir) || progress; - progress = do_constant_propagation(ir) || progress; - if (linked) - progress = do_constant_variable(ir) || progress; - else - progress = do_constant_variable_unlinked(ir) || progress; - progress = do_constant_folding(ir) || progress; - progress = do_algebraic(ir) || progress; - progress = do_lower_jumps(ir) || progress; - progress = do_vec_index_to_swizzle(ir) || progress; - progress = do_swizzle_swizzle(ir) || progress; - progress = do_noop_swizzle(ir) || progress; - - progress = optimize_redundant_jumps(ir) || progress; - - loop_state *ls = analyze_loop_variables(ir); - progress = set_loop_controls(ir, ls) || progress; - progress = unroll_loops(ir, ls, max_unroll_iterations) || progress; - delete ls; - - return progress; -} - -extern "C" { - -/** - * To be called at GL teardown time, this frees compiler datastructures. - * - * After calling this, any previously compiled shaders and shader - * programs would be invalid. So this should happen at approximately - * program exit. - */ -void -_mesa_destroy_shader_compiler(void) -{ - _mesa_destroy_shader_compiler_caches(); - - _mesa_glsl_release_types(); -} - -/** - * Releases compiler caches to trade off performance for memory. - * - * Intended to be used with glReleaseShaderCompiler(). - */ -void -_mesa_destroy_shader_compiler_caches(void) -{ - _mesa_glsl_release_functions(); -} - -} +/*
+ * Copyright © 2008, 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+extern "C" {
+#include <talloc.h>
+#include "main/core.h" /* for struct gl_context */
+}
+
+#include "ast.h"
+#include "glsl_parser_extras.h"
+#include "glsl_parser.h"
+#include "ir_optimization.h"
+#include "loop_analysis.h"
+
+_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
+ GLenum target, void *mem_ctx)
+{
+ switch (target) {
+ case GL_VERTEX_SHADER: this->target = vertex_shader; break;
+ case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
+ case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
+ }
+
+ this->scanner = NULL;
+ this->translation_unit.make_empty();
+ this->symbols = new(mem_ctx) glsl_symbol_table;
+ this->info_log = talloc_strdup(mem_ctx, "");
+ this->error = false;
+ this->loop_or_switch_nesting = NULL;
+
+ /* Set default language version and extensions */
+ this->language_version = 110;
+ this->es_shader = false;
+ this->ARB_texture_rectangle_enable = true;
+
+ /* OpenGL ES 2.0 has different defaults from desktop GL. */
+ if (ctx->API == API_OPENGLES2) {
+ this->language_version = 100;
+ this->es_shader = true;
+ this->ARB_texture_rectangle_enable = false;
+ }
+
+ this->extensions = &ctx->Extensions;
+
+ this->Const.MaxLights = ctx->Const.MaxLights;
+ this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
+ this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
+ this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
+ this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs;
+ this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents;
+ this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4;
+ this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits;
+ this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
+ this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+ this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
+
+ this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
+}
+
+const char *
+_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
+{
+ switch (target) {
+ case vertex_shader: return "vertex";
+ case fragment_shader: return "fragment";
+ case geometry_shader: return "geometry";
+ }
+
+ assert(!"Should not get here.");
+ return "unknown";
+}
+
+
+void
+_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ state->error = true;
+
+ assert(state->info_log != NULL);
+ state->info_log = talloc_asprintf_append(state->info_log,
+ "%u:%u(%u): error: ",
+ locp->source,
+ locp->first_line,
+ locp->first_column);
+ va_start(ap, fmt);
+ state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
+ va_end(ap);
+ state->info_log = talloc_strdup_append(state->info_log, "\n");
+}
+
+
+void
+_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ assert(state->info_log != NULL);
+ state->info_log = talloc_asprintf_append(state->info_log,
+ "%u:%u(%u): warning: ",
+ locp->source,
+ locp->first_line,
+ locp->first_column);
+ va_start(ap, fmt);
+ state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
+ va_end(ap);
+ state->info_log = talloc_strdup_append(state->info_log, "\n");
+}
+
+
+bool
+_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
+ const char *behavior, YYLTYPE *behavior_locp,
+ _mesa_glsl_parse_state *state)
+{
+ enum {
+ extension_disable,
+ extension_enable,
+ extension_require,
+ extension_warn
+ } ext_mode;
+
+ if (strcmp(behavior, "warn") == 0) {
+ ext_mode = extension_warn;
+ } else if (strcmp(behavior, "require") == 0) {
+ ext_mode = extension_require;
+ } else if (strcmp(behavior, "enable") == 0) {
+ ext_mode = extension_enable;
+ } else if (strcmp(behavior, "disable") == 0) {
+ ext_mode = extension_disable;
+ } else {
+ _mesa_glsl_error(behavior_locp, state,
+ "Unknown extension behavior `%s'",
+ behavior);
+ return false;
+ }
+
+ bool unsupported = false;
+
+ if (strcmp(name, "all") == 0) {
+ if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
+ _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
+ (ext_mode == extension_enable)
+ ? "enable" : "require");
+ return false;
+ }
+ } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
+ /* This extension is only supported in fragment shaders.
+ */
+ if (state->target != fragment_shader) {
+ unsupported = true;
+ } else {
+ state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
+ state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
+ }
+ } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
+ state->ARB_explicit_attrib_location_enable =
+ (ext_mode != extension_disable);
+ state->ARB_explicit_attrib_location_warn =
+ (ext_mode == extension_warn);
+
+ unsupported = !state->extensions->ARB_explicit_attrib_location;
+ } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) {
+ state->ARB_fragment_coord_conventions_enable =
+ (ext_mode != extension_disable);
+ state->ARB_fragment_coord_conventions_warn =
+ (ext_mode == extension_warn);
+
+ unsupported = !state->extensions->ARB_fragment_coord_conventions;
+ } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
+ state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
+ state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
+ } else if (strcmp(name, "GL_EXT_texture_array") == 0) {
+ state->EXT_texture_array_enable = (ext_mode != extension_disable);
+ state->EXT_texture_array_warn = (ext_mode == extension_warn);
+
+ unsupported = !state->extensions->EXT_texture_array;
+ } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) {
+ if (state->target != fragment_shader) {
+ unsupported = true;
+ } else {
+ state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable);
+ state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn);
+ unsupported = !state->extensions->ARB_shader_stencil_export;
+ }
+ } else {
+ unsupported = true;
+ }
+
+ if (unsupported) {
+ static const char *const fmt = "extension `%s' unsupported in %s shader";
+
+ if (ext_mode == extension_require) {
+ _mesa_glsl_error(name_locp, state, fmt,
+ name, _mesa_glsl_shader_target_name(state->target));
+ return false;
+ } else {
+ _mesa_glsl_warning(name_locp, state, fmt,
+ name, _mesa_glsl_shader_target_name(state->target));
+ }
+ }
+
+ return true;
+}
+
+void
+_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
+{
+ if (q->flags.q.constant)
+ printf("const ");
+
+ if (q->flags.q.invariant)
+ printf("invariant ");
+
+ if (q->flags.q.attribute)
+ printf("attribute ");
+
+ if (q->flags.q.varying)
+ printf("varying ");
+
+ if (q->flags.q.in && q->flags.q.out)
+ printf("inout ");
+ else {
+ if (q->flags.q.in)
+ printf("in ");
+
+ if (q->flags.q.out)
+ printf("out ");
+ }
+
+ if (q->flags.q.centroid)
+ printf("centroid ");
+ if (q->flags.q.uniform)
+ printf("uniform ");
+ if (q->flags.q.smooth)
+ printf("smooth ");
+ if (q->flags.q.flat)
+ printf("flat ");
+ if (q->flags.q.noperspective)
+ printf("noperspective ");
+}
+
+
+void
+ast_node::print(void) const
+{
+ printf("unhandled node ");
+}
+
+
+ast_node::ast_node(void)
+{
+ this->location.source = 0;
+ this->location.line = 0;
+ this->location.column = 0;
+}
+
+
+static void
+ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
+{
+ if (is_array) {
+ printf("[ ");
+
+ if (array_size)
+ array_size->print();
+
+ printf("] ");
+ }
+}
+
+
+void
+ast_compound_statement::print(void) const
+{
+ printf("{\n");
+
+ foreach_list_const(n, &this->statements) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
+ }
+
+ printf("}\n");
+}
+
+
+ast_compound_statement::ast_compound_statement(int new_scope,
+ ast_node *statements)
+{
+ this->new_scope = new_scope;
+
+ if (statements != NULL) {
+ this->statements.push_degenerate_list_at_head(&statements->link);
+ }
+}
+
+
+void
+ast_expression::print(void) const
+{
+ switch (oper) {
+ case ast_assign:
+ case ast_mul_assign:
+ case ast_div_assign:
+ case ast_mod_assign:
+ case ast_add_assign:
+ case ast_sub_assign:
+ case ast_ls_assign:
+ case ast_rs_assign:
+ case ast_and_assign:
+ case ast_xor_assign:
+ case ast_or_assign:
+ subexpressions[0]->print();
+ printf("%s ", operator_string(oper));
+ subexpressions[1]->print();
+ break;
+
+ case ast_field_selection:
+ subexpressions[0]->print();
+ printf(". %s ", primary_expression.identifier);
+ break;
+
+ case ast_plus:
+ case ast_neg:
+ case ast_bit_not:
+ case ast_logic_not:
+ case ast_pre_inc:
+ case ast_pre_dec:
+ printf("%s ", operator_string(oper));
+ subexpressions[0]->print();
+ break;
+
+ case ast_post_inc:
+ case ast_post_dec:
+ subexpressions[0]->print();
+ printf("%s ", operator_string(oper));
+ break;
+
+ case ast_conditional:
+ subexpressions[0]->print();
+ printf("? ");
+ subexpressions[1]->print();
+ printf(": ");
+ subexpressions[1]->print();
+ break;
+
+ case ast_array_index:
+ subexpressions[0]->print();
+ printf("[ ");
+ subexpressions[1]->print();
+ printf("] ");
+ break;
+
+ case ast_function_call: {
+ subexpressions[0]->print();
+ printf("( ");
+
+ foreach_list_const (n, &this->expressions) {
+ if (n != this->expressions.get_head())
+ printf(", ");
+
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
+ }
+
+ printf(") ");
+ break;
+ }
+
+ case ast_identifier:
+ printf("%s ", primary_expression.identifier);
+ break;
+
+ case ast_int_constant:
+ printf("%d ", primary_expression.int_constant);
+ break;
+
+ case ast_uint_constant:
+ printf("%u ", primary_expression.uint_constant);
+ break;
+
+ case ast_float_constant:
+ printf("%f ", primary_expression.float_constant);
+ break;
+
+ case ast_bool_constant:
+ printf("%s ",
+ primary_expression.bool_constant
+ ? "true" : "false");
+ break;
+
+ case ast_sequence: {
+ printf("( ");
+ foreach_list_const(n, & this->expressions) {
+ if (n != this->expressions.get_head())
+ printf(", ");
+
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
+ }
+ printf(") ");
+ break;
+ }
+
+ default:
+ assert(0);
+ break;
+ }
+}
+
+ast_expression::ast_expression(int oper,
+ ast_expression *ex0,
+ ast_expression *ex1,
+ ast_expression *ex2)
+{
+ this->oper = ast_operators(oper);
+ this->subexpressions[0] = ex0;
+ this->subexpressions[1] = ex1;
+ this->subexpressions[2] = ex2;
+}
+
+
+void
+ast_expression_statement::print(void) const
+{
+ if (expression)
+ expression->print();
+
+ printf("; ");
+}
+
+
+ast_expression_statement::ast_expression_statement(ast_expression *ex) :
+ expression(ex)
+{
+ /* empty */
+}
+
+
+void
+ast_function::print(void) const
+{
+ return_type->print();
+ printf(" %s (", identifier);
+
+ foreach_list_const(n, & this->parameters) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
+ }
+
+ printf(")");
+}
+
+
+ast_function::ast_function(void)
+ : is_definition(false), signature(NULL)
+{
+ /* empty */
+}
+
+
+void
+ast_fully_specified_type::print(void) const
+{
+ _mesa_ast_type_qualifier_print(& qualifier);
+ specifier->print();
+}
+
+
+void
+ast_parameter_declarator::print(void) const
+{
+ type->print();
+ if (identifier)
+ printf("%s ", identifier);
+ ast_opt_array_size_print(is_array, array_size);
+}
+
+
+void
+ast_function_definition::print(void) const
+{
+ prototype->print();
+ body->print();
+}
+
+
+void
+ast_declaration::print(void) const
+{
+ printf("%s ", identifier);
+ ast_opt_array_size_print(is_array, array_size);
+
+ if (initializer) {
+ printf("= ");
+ initializer->print();
+ }
+}
+
+
+ast_declaration::ast_declaration(char *identifier, int is_array,
+ ast_expression *array_size,
+ ast_expression *initializer)
+{
+ this->identifier = identifier;
+ this->is_array = is_array;
+ this->array_size = array_size;
+ this->initializer = initializer;
+}
+
+
+void
+ast_declarator_list::print(void) const
+{
+ assert(type || invariant);
+
+ if (type)
+ type->print();
+ else
+ printf("invariant ");
+
+ foreach_list_const (ptr, & this->declarations) {
+ if (ptr != this->declarations.get_head())
+ printf(", ");
+
+ ast_node *ast = exec_node_data(ast_node, ptr, link);
+ ast->print();
+ }
+
+ printf("; ");
+}
+
+
+ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
+{
+ this->type = type;
+ this->invariant = false;
+}
+
+void
+ast_jump_statement::print(void) const
+{
+ switch (mode) {
+ case ast_continue:
+ printf("continue; ");
+ break;
+ case ast_break:
+ printf("break; ");
+ break;
+ case ast_return:
+ printf("return ");
+ if (opt_return_value)
+ opt_return_value->print();
+
+ printf("; ");
+ break;
+ case ast_discard:
+ printf("discard; ");
+ break;
+ }
+}
+
+
+ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
+{
+ this->mode = ast_jump_modes(mode);
+
+ if (mode == ast_return)
+ opt_return_value = return_value;
+}
+
+
+void
+ast_selection_statement::print(void) const
+{
+ printf("if ( ");
+ condition->print();
+ printf(") ");
+
+ then_statement->print();
+
+ if (else_statement) {
+ printf("else ");
+ else_statement->print();
+ }
+
+}
+
+
+ast_selection_statement::ast_selection_statement(ast_expression *condition,
+ ast_node *then_statement,
+ ast_node *else_statement)
+{
+ this->condition = condition;
+ this->then_statement = then_statement;
+ this->else_statement = else_statement;
+}
+
+
+void
+ast_iteration_statement::print(void) const
+{
+ switch (mode) {
+ case ast_for:
+ printf("for( ");
+ if (init_statement)
+ init_statement->print();
+ printf("; ");
+
+ if (condition)
+ condition->print();
+ printf("; ");
+
+ if (rest_expression)
+ rest_expression->print();
+ printf(") ");
+
+ body->print();
+ break;
+
+ case ast_while:
+ printf("while ( ");
+ if (condition)
+ condition->print();
+ printf(") ");
+ body->print();
+ break;
+
+ case ast_do_while:
+ printf("do ");
+ body->print();
+ printf("while ( ");
+ if (condition)
+ condition->print();
+ printf("); ");
+ break;
+ }
+}
+
+
+ast_iteration_statement::ast_iteration_statement(int mode,
+ ast_node *init,
+ ast_node *condition,
+ ast_expression *rest_expression,
+ ast_node *body)
+{
+ this->mode = ast_iteration_modes(mode);
+ this->init_statement = init;
+ this->condition = condition;
+ this->rest_expression = rest_expression;
+ this->body = body;
+}
+
+
+void
+ast_struct_specifier::print(void) const
+{
+ printf("struct %s { ", name);
+ foreach_list_const(n, &this->declarations) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
+ }
+ printf("} ");
+}
+
+
+ast_struct_specifier::ast_struct_specifier(char *identifier,
+ ast_node *declarator_list)
+{
+ if (identifier == NULL) {
+ static unsigned anon_count = 1;
+ identifier = talloc_asprintf(this, "#anon_struct_%04x", anon_count);
+ anon_count++;
+ }
+ name = identifier;
+ this->declarations.push_degenerate_list_at_head(&declarator_list->link);
+}
+
+bool
+do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
+{
+ GLboolean progress = GL_FALSE;
+
+ progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
+
+ if (linked) {
+ progress = do_function_inlining(ir) || progress;
+ progress = do_dead_functions(ir) || progress;
+ }
+ progress = do_structure_splitting(ir) || progress;
+ progress = do_if_simplification(ir) || progress;
+ progress = do_discard_simplification(ir) || progress;
+ progress = do_copy_propagation(ir) || progress;
+ if (linked)
+ progress = do_dead_code(ir) || progress;
+ else
+ progress = do_dead_code_unlinked(ir) || progress;
+ progress = do_dead_code_local(ir) || progress;
+ progress = do_tree_grafting(ir) || progress;
+ progress = do_constant_propagation(ir) || progress;
+ if (linked)
+ progress = do_constant_variable(ir) || progress;
+ else
+ progress = do_constant_variable_unlinked(ir) || progress;
+ progress = do_constant_folding(ir) || progress;
+ progress = do_algebraic(ir) || progress;
+ progress = do_lower_jumps(ir) || progress;
+ progress = do_vec_index_to_swizzle(ir) || progress;
+ progress = do_swizzle_swizzle(ir) || progress;
+ progress = do_noop_swizzle(ir) || progress;
+
+ progress = optimize_redundant_jumps(ir) || progress;
+
+ loop_state *ls = analyze_loop_variables(ir);
+ progress = set_loop_controls(ir, ls) || progress;
+ progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
+ delete ls;
+
+ return progress;
+}
+
+extern "C" {
+
+/**
+ * To be called at GL teardown time, this frees compiler datastructures.
+ *
+ * After calling this, any previously compiled shaders and shader
+ * programs would be invalid. So this should happen at approximately
+ * program exit.
+ */
+void
+_mesa_destroy_shader_compiler(void)
+{
+ _mesa_destroy_shader_compiler_caches();
+
+ _mesa_glsl_release_types();
+}
+
+/**
+ * Releases compiler caches to trade off performance for memory.
+ *
+ * Intended to be used with glReleaseShaderCompiler().
+ */
+void
+_mesa_destroy_shader_compiler_caches(void)
+{
+ _mesa_glsl_release_functions();
+}
+
+}
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index f300ece4b..df629cfcf 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -1,240 +1,243 @@ -/* - * 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 - -/* - * Most of the definitions here only apply to C++ - */ -#ifdef __cplusplus - - -#include <cstdlib> -#include "glsl_symbol_table.h" - -enum _mesa_glsl_parser_targets { - vertex_shader, - geometry_shader, - fragment_shader, - ir_shader -}; - -struct __GLcontextRec; - -struct _mesa_glsl_parse_state { - _mesa_glsl_parse_state(struct __GLcontextRec *ctx, GLenum target, - void *mem_ctx); - - /* 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 *mem = talloc_zero_size(ctx, size); - assert(mem != NULL); - - return mem; - } - - /* If the user *does* call delete, that's OK, we will just - * talloc_free in that case. */ - static void operator delete(void *mem, void *ctx) - { - talloc_free(mem); - } - static void operator delete(void *mem) - { - talloc_free(mem); - } - - void *scanner; - exec_list translation_unit; - glsl_symbol_table *symbols; - - bool es_shader; - unsigned language_version; - enum _mesa_glsl_parser_targets target; - - /** - * Implementation defined limits that affect built-in variables, etc. - * - * \sa struct gl_constants (in mtypes.h) - */ - struct { - /* 1.10 */ - unsigned MaxLights; - unsigned MaxClipPlanes; - unsigned MaxTextureUnits; - unsigned MaxTextureCoords; - unsigned MaxVertexAttribs; - unsigned MaxVertexUniformComponents; - unsigned MaxVaryingFloats; - unsigned MaxVertexTextureImageUnits; - unsigned MaxCombinedTextureImageUnits; - unsigned MaxTextureImageUnits; - unsigned MaxFragmentUniformComponents; - - /* ARB_draw_buffers */ - unsigned MaxDrawBuffers; - } Const; - - /** - * 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; - - /** Have we found a return statement in this function? */ - bool found_return; - - /** Was there an error during compilation? */ - bool error; - - /** Loop or switch statement containing the current instructions. */ - class ir_instruction *loop_or_switch_nesting; - class ast_iteration_statement *loop_or_switch_nesting_ast; - - /** 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_fragment_coord_conventions_enable:1; - unsigned ARB_fragment_coord_conventions_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; - /*@}*/ - - /** Extensions supported by the OpenGL implementation. */ - const struct gl_extensions *extensions; - - /** Shaders containing built-in functions that are used for linking. */ - struct gl_shader *builtins_to_link[16]; - unsigned num_builtins_to_link; -}; - -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 - -# define YYLLOC_DEFAULT(Current, Rhs, N) \ -do { \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC(Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC(Rhs, 0).last_column; \ - } \ - (Current).source = 0; \ -} while (0) - -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 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); - - -#endif /* __cplusplus */ - - -/* - * These definitions apply to C and C++ - */ -#ifdef __cplusplus -extern "C" { -#endif - -extern int preprocess(void *ctx, const char **shader, char **info_log, - const struct gl_extensions *extensions, int api); - -extern void _mesa_destroy_shader_compiler(); -extern void _mesa_destroy_shader_compiler_caches(); - -#ifdef __cplusplus -} -#endif - - -#endif /* GLSL_PARSER_EXTRAS_H */ +/*
+ * 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
+
+/*
+ * Most of the definitions here only apply to C++
+ */
+#ifdef __cplusplus
+
+
+#include <cstdlib>
+#include "glsl_symbol_table.h"
+
+enum _mesa_glsl_parser_targets {
+ vertex_shader,
+ geometry_shader,
+ fragment_shader
+};
+
+struct gl_context;
+
+struct _mesa_glsl_parse_state {
+ _mesa_glsl_parse_state(struct gl_context *ctx, GLenum target,
+ void *mem_ctx);
+
+ /* 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 *mem = talloc_zero_size(ctx, size);
+ assert(mem != NULL);
+
+ return mem;
+ }
+
+ /* If the user *does* call delete, that's OK, we will just
+ * talloc_free in that case. */
+ static void operator delete(void *mem, void *ctx)
+ {
+ talloc_free(mem);
+ }
+ static void operator delete(void *mem)
+ {
+ talloc_free(mem);
+ }
+
+ void *scanner;
+ exec_list translation_unit;
+ glsl_symbol_table *symbols;
+
+ bool es_shader;
+ unsigned language_version;
+ enum _mesa_glsl_parser_targets target;
+
+ /**
+ * Implementation defined limits that affect built-in variables, etc.
+ *
+ * \sa struct gl_constants (in mtypes.h)
+ */
+ struct {
+ /* 1.10 */
+ unsigned MaxLights;
+ unsigned MaxClipPlanes;
+ unsigned MaxTextureUnits;
+ unsigned MaxTextureCoords;
+ unsigned MaxVertexAttribs;
+ unsigned MaxVertexUniformComponents;
+ unsigned MaxVaryingFloats;
+ unsigned MaxVertexTextureImageUnits;
+ unsigned MaxCombinedTextureImageUnits;
+ unsigned MaxTextureImageUnits;
+ unsigned MaxFragmentUniformComponents;
+
+ /* ARB_draw_buffers */
+ unsigned MaxDrawBuffers;
+ } Const;
+
+ /**
+ * 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;
+
+ /** Have we found a return statement in this function? */
+ bool found_return;
+
+ /** Was there an error during compilation? */
+ bool error;
+
+ /** Loop or switch statement containing the current instructions. */
+ class ir_instruction *loop_or_switch_nesting;
+ class ast_iteration_statement *loop_or_switch_nesting_ast;
+
+ /** 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_explicit_attrib_location_enable:1;
+ unsigned ARB_explicit_attrib_location_warn:1;
+ unsigned ARB_fragment_coord_conventions_enable:1;
+ unsigned ARB_fragment_coord_conventions_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;
+ unsigned ARB_shader_stencil_export_enable:1;
+ unsigned ARB_shader_stencil_export_warn:1;
+ /*@}*/
+
+ /** Extensions supported by the OpenGL implementation. */
+ const struct gl_extensions *extensions;
+
+ /** Shaders containing built-in functions that are used for linking. */
+ struct gl_shader *builtins_to_link[16];
+ unsigned num_builtins_to_link;
+};
+
+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
+
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+do { \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC(Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC(Rhs, 0).last_column; \
+ } \
+ (Current).source = 0; \
+} while (0)
+
+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 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);
+
+
+#endif /* __cplusplus */
+
+
+/*
+ * These definitions apply to C and C++
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int preprocess(void *ctx, const char **shader, char **info_log,
+ const struct gl_extensions *extensions, int api);
+
+extern void _mesa_destroy_shader_compiler();
+extern void _mesa_destroy_shader_compiler_caches();
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* GLSL_PARSER_EXTRAS_H */
diff --git a/mesalib/src/glsl/glsl_symbol_table.cpp b/mesalib/src/glsl/glsl_symbol_table.cpp index 9537d86c9..b64b9179d 100644 --- a/mesalib/src/glsl/glsl_symbol_table.cpp +++ b/mesalib/src/glsl/glsl_symbol_table.cpp @@ -1,165 +1,172 @@ -/* -*- 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 "glsl_symbol_table.h" - -class symbol_table_entry { -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 *entry = talloc_size(ctx, size); - assert(entry != NULL); - return entry; - } - - /* 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, void *ctx) - { - talloc_set_destructor(table, NULL); - talloc_free(table); - } - static void operator delete(void *table) - { - talloc_set_destructor(table, NULL); - talloc_free(table); - } - - symbol_table_entry(ir_variable *v) : v(v), f(0), t(0) {} - symbol_table_entry(ir_function *f) : v(0), f(f), t(0) {} - symbol_table_entry(const glsl_type *t) : v(0), f(0), t(t) {} - - ir_variable *v; - ir_function *f; - const glsl_type *t; -}; - -glsl_symbol_table::glsl_symbol_table() -{ - this->language_version = 120; - this->table = _mesa_symbol_table_ctor(); - this->mem_ctx = talloc_init("symbol table entries"); -} - -glsl_symbol_table::~glsl_symbol_table() -{ - _mesa_symbol_table_dtor(table); - talloc_free(mem_ctx); -} - -void glsl_symbol_table::push_scope() -{ - _mesa_symbol_table_push_scope(table); -} - -void glsl_symbol_table::pop_scope() -{ - _mesa_symbol_table_pop_scope(table); -} - -bool glsl_symbol_table::name_declared_this_scope(const char *name) -{ - return _mesa_symbol_table_symbol_scope(table, -1, name) == 0; -} - -bool glsl_symbol_table::add_variable(const char *name, ir_variable *v) -{ - if (this->language_version == 110) { - /* In 1.10, functions and variables have separate namespaces. */ - symbol_table_entry *existing = get_entry(name); - if (name_declared_this_scope(name)) { - /* If there's already an existing function (not a constructor!) in - * the current scope, just update the existing entry to include 'v'. - */ - if (existing->v == NULL && existing->t == NULL) { - existing->v = v; - return true; - } - } else { - /* If not declared at this scope, add a new entry. But if an existing - * entry includes a function, propagate that to this block - otherwise - * the new variable declaration would shadow the function. - */ - symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); - if (existing != NULL) - entry->f = existing->f; - int added = _mesa_symbol_table_add_symbol(table, -1, name, entry); - assert(added == 0); - (void)added; - return true; - } - return false; - } - - /* 1.20+ rules: */ - symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); - return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; -} - -bool glsl_symbol_table::add_type(const char *name, const glsl_type *t) -{ - symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t); - return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; -} - -bool glsl_symbol_table::add_function(const char *name, ir_function *f) -{ - if (this->language_version == 110 && name_declared_this_scope(name)) { - /* In 1.10, functions and variables have separate namespaces. */ - symbol_table_entry *existing = get_entry(name); - if ((existing->f == NULL) && (existing->t == NULL)) { - existing->f = f; - return true; - } - } - symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); - return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; -} - -ir_variable *glsl_symbol_table::get_variable(const char *name) -{ - symbol_table_entry *entry = get_entry(name); - return entry != NULL ? entry->v : NULL; -} - -const glsl_type *glsl_symbol_table::get_type(const char *name) -{ - symbol_table_entry *entry = get_entry(name); - return entry != NULL ? entry->t : NULL; -} - -ir_function *glsl_symbol_table::get_function(const char *name) -{ - symbol_table_entry *entry = get_entry(name); - return entry != NULL ? entry->f : NULL; -} - -symbol_table_entry *glsl_symbol_table::get_entry(const char *name) -{ - return (symbol_table_entry *) - _mesa_symbol_table_find_symbol(table, -1, name); -} +/* -*- 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 "glsl_symbol_table.h"
+
+class symbol_table_entry {
+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 *entry = talloc_size(ctx, size);
+ assert(entry != NULL);
+ return entry;
+ }
+
+ /* 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, void *ctx)
+ {
+ talloc_set_destructor(table, NULL);
+ talloc_free(table);
+ }
+ static void operator delete(void *table)
+ {
+ talloc_set_destructor(table, NULL);
+ talloc_free(table);
+ }
+
+ symbol_table_entry(ir_variable *v) : v(v), f(0), t(0) {}
+ symbol_table_entry(ir_function *f) : v(0), f(f), t(0) {}
+ symbol_table_entry(const glsl_type *t) : v(0), f(0), t(t) {}
+
+ ir_variable *v;
+ ir_function *f;
+ const glsl_type *t;
+};
+
+glsl_symbol_table::glsl_symbol_table()
+{
+ this->language_version = 120;
+ this->table = _mesa_symbol_table_ctor();
+ this->mem_ctx = talloc_init("symbol table entries");
+}
+
+glsl_symbol_table::~glsl_symbol_table()
+{
+ _mesa_symbol_table_dtor(table);
+ talloc_free(mem_ctx);
+}
+
+void glsl_symbol_table::push_scope()
+{
+ _mesa_symbol_table_push_scope(table);
+}
+
+void glsl_symbol_table::pop_scope()
+{
+ _mesa_symbol_table_pop_scope(table);
+}
+
+bool glsl_symbol_table::name_declared_this_scope(const char *name)
+{
+ return _mesa_symbol_table_symbol_scope(table, -1, name) == 0;
+}
+
+bool glsl_symbol_table::add_variable(ir_variable *v)
+{
+ if (this->language_version == 110) {
+ /* In 1.10, functions and variables have separate namespaces. */
+ symbol_table_entry *existing = get_entry(v->name);
+ if (name_declared_this_scope(v->name)) {
+ /* If there's already an existing function (not a constructor!) in
+ * the current scope, just update the existing entry to include 'v'.
+ */
+ if (existing->v == NULL && existing->t == NULL) {
+ existing->v = v;
+ return true;
+ }
+ } else {
+ /* If not declared at this scope, add a new entry. But if an existing
+ * entry includes a function, propagate that to this block - otherwise
+ * the new variable declaration would shadow the function.
+ */
+ symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v);
+ if (existing != NULL)
+ entry->f = existing->f;
+ int added = _mesa_symbol_table_add_symbol(table, -1, v->name, entry);
+ assert(added == 0);
+ (void)added;
+ return true;
+ }
+ return false;
+ }
+
+ /* 1.20+ rules: */
+ symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v);
+ return _mesa_symbol_table_add_symbol(table, -1, v->name, entry) == 0;
+}
+
+bool glsl_symbol_table::add_type(const char *name, const glsl_type *t)
+{
+ symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t);
+ return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0;
+}
+
+bool glsl_symbol_table::add_function(ir_function *f)
+{
+ if (this->language_version == 110 && name_declared_this_scope(f->name)) {
+ /* In 1.10, functions and variables have separate namespaces. */
+ symbol_table_entry *existing = get_entry(f->name);
+ if ((existing->f == NULL) && (existing->t == NULL)) {
+ existing->f = f;
+ return true;
+ }
+ }
+ symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f);
+ return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0;
+}
+
+void glsl_symbol_table::add_global_function(ir_function *f)
+{
+ symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f);
+ int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry);
+ assert(added == 0);
+}
+
+ir_variable *glsl_symbol_table::get_variable(const char *name)
+{
+ symbol_table_entry *entry = get_entry(name);
+ return entry != NULL ? entry->v : NULL;
+}
+
+const glsl_type *glsl_symbol_table::get_type(const char *name)
+{
+ symbol_table_entry *entry = get_entry(name);
+ return entry != NULL ? entry->t : NULL;
+}
+
+ir_function *glsl_symbol_table::get_function(const char *name)
+{
+ symbol_table_entry *entry = get_entry(name);
+ return entry != NULL ? entry->f : NULL;
+}
+
+symbol_table_entry *glsl_symbol_table::get_entry(const char *name)
+{
+ return (symbol_table_entry *)
+ _mesa_symbol_table_find_symbol(table, -1, name);
+}
diff --git a/mesalib/src/glsl/glsl_symbol_table.h b/mesalib/src/glsl/glsl_symbol_table.h index 02c45b2e0..3890efd87 100644 --- a/mesalib/src/glsl/glsl_symbol_table.h +++ b/mesalib/src/glsl/glsl_symbol_table.h @@ -1,126 +1,131 @@ -/* -*- 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> - -extern "C" { -#include "program/symbol_table.h" -} -#include "ir.h" -#include "glsl_types.h" - -class symbol_table_entry; - -/** - * 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. - */ -struct glsl_symbol_table { -private: - 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, void *ctx) - { - talloc_set_destructor(table, NULL); - talloc_free(table); - } - static void operator delete(void *table) - { - talloc_set_destructor(table, NULL); - talloc_free(table); - } - - glsl_symbol_table(); - ~glsl_symbol_table(); - - unsigned int language_version; - - void push_scope(); - void pop_scope(); - - /** - * Determine whether a name was declared at the current scope - */ - bool name_declared_this_scope(const char *name); - - /** - * \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); - bool add_type(const char *name, const glsl_type *t); - bool add_function(const char *name, ir_function *f); - /*@}*/ - - /** - * \name Methods to get symbols from the table - */ - /*@{*/ - ir_variable *get_variable(const char *name); - const glsl_type *get_type(const char *name); - ir_function *get_function(const char *name); - /*@}*/ - -private: - symbol_table_entry *get_entry(const char *name); - - struct _mesa_symbol_table *table; - void *mem_ctx; -}; - -#endif /* GLSL_SYMBOL_TABLE */ +/* -*- 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>
+
+extern "C" {
+#include "program/symbol_table.h"
+}
+#include "ir.h"
+#include "glsl_types.h"
+
+class symbol_table_entry;
+
+/**
+ * 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.
+ */
+struct glsl_symbol_table {
+private:
+ 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, void *ctx)
+ {
+ talloc_set_destructor(table, NULL);
+ talloc_free(table);
+ }
+ static void operator delete(void *table)
+ {
+ talloc_set_destructor(table, NULL);
+ talloc_free(table);
+ }
+
+ glsl_symbol_table();
+ ~glsl_symbol_table();
+
+ unsigned int language_version;
+
+ void push_scope();
+ void pop_scope();
+
+ /**
+ * Determine whether a name was declared at the current scope
+ */
+ bool name_declared_this_scope(const char *name);
+
+ /**
+ * \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(ir_variable *v);
+ bool add_type(const char *name, const glsl_type *t);
+ bool add_function(ir_function *f);
+ /*@}*/
+
+ /**
+ * Add an function at global scope without checking for scoping conflicts.
+ */
+ void add_global_function(ir_function *f);
+
+ /**
+ * \name Methods to get symbols from the table
+ */
+ /*@{*/
+ ir_variable *get_variable(const char *name);
+ const glsl_type *get_type(const char *name);
+ ir_function *get_function(const char *name);
+ /*@}*/
+
+private:
+ symbol_table_entry *get_entry(const char *name);
+
+ struct _mesa_symbol_table *table;
+ void *mem_ctx;
+};
+
+#endif /* GLSL_SYMBOL_TABLE */
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 82eb47060..899e9c302 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -1,497 +1,497 @@ -/* - * 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 "main/core.h" /* for Elements */ -#include "glsl_symbol_table.h" -#include "glsl_parser_extras.h" -#include "glsl_types.h" -#include "builtin_types.h" -extern "C" { -#include "program/hash_table.h" -} - -hash_table *glsl_type::array_types = NULL; -hash_table *glsl_type::record_types = NULL; -void *glsl_type::mem_ctx = NULL; - -void -glsl_type::init_talloc_type_ctx(void) -{ - if (glsl_type::mem_ctx == NULL) { - glsl_type::mem_ctx = talloc_autofree_context(); - assert(glsl_type::mem_ctx != NULL); - } -} - -glsl_type::glsl_type(GLenum gl_type, - unsigned base_type, unsigned vector_elements, - unsigned matrix_columns, const char *name) : - gl_type(gl_type), - base_type(base_type), - sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - sampler_type(0), - vector_elements(vector_elements), matrix_columns(matrix_columns), - length(0) -{ - init_talloc_type_ctx(); - this->name = talloc_strdup(this->mem_ctx, name); - /* Neither dimension is zero or both dimensions are zero. - */ - assert((vector_elements == 0) == (matrix_columns == 0)); - memset(& fields, 0, sizeof(fields)); -} - -glsl_type::glsl_type(GLenum gl_type, - enum glsl_sampler_dim dim, bool shadow, bool array, - unsigned type, const char *name) : - gl_type(gl_type), - base_type(GLSL_TYPE_SAMPLER), - sampler_dimensionality(dim), sampler_shadow(shadow), - sampler_array(array), sampler_type(type), - vector_elements(0), matrix_columns(0), - length(0) -{ - init_talloc_type_ctx(); - this->name = talloc_strdup(this->mem_ctx, name); - memset(& fields, 0, sizeof(fields)); -} - -glsl_type::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), - length(num_fields) -{ - unsigned int i; - - init_talloc_type_ctx(); - this->name = talloc_strdup(this->mem_ctx, name); - this->fields.structure = talloc_array(this->mem_ctx, - glsl_struct_field, length); - for (i = 0; i < length; i++) { - this->fields.structure[i].type = fields[i].type; - this->fields.structure[i].name = talloc_strdup(this->fields.structure, - fields[i].name); - } -} - -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]); - } -} - -void -glsl_type::generate_100ES_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, &void_type, 1, false); -} - -void -glsl_type::generate_110_types(glsl_symbol_table *symtab) -{ - generate_100ES_types(symtab); - - add_types_to_symbol_table(symtab, builtin_110_types, - Elements(builtin_110_types), - false); - add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types, - Elements(builtin_110_deprecated_structure_types), - false); -} - - -void -glsl_type::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); -} - - -void -glsl_type::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); - generate_EXT_texture_array_types(symtab, false); -} - - -void -glsl_type::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); -} - - -void -glsl_type::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 100: - assert(state->es_shader); - glsl_type::generate_100ES_types(state->symbols); - break; - case 110: - glsl_type::generate_110_types(state->symbols); - break; - case 120: - glsl_type::generate_120_types(state->symbols); - break; - case 130: - glsl_type::generate_130_types(state->symbols); - break; - default: - /* error */ - break; - } - - if (state->ARB_texture_rectangle_enable) { - glsl_type::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. - glsl_type::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; - } -} - - -void -_mesa_glsl_release_types(void) -{ - if (glsl_type::array_types != NULL) { - hash_table_dtor(glsl_type::array_types); - glsl_type::array_types = NULL; - } - - if (glsl_type::record_types != NULL) { - hash_table_dtor(glsl_type::record_types); - glsl_type::record_types = NULL; - } -} - - -glsl_type::glsl_type(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; - /* Inherit the gl type of the base. The GL type is used for - * uniform/statevar handling in Mesa and the arrayness of the type - * is represented by the size rather than the type. - */ - this->gl_type = array->gl_type; - - /* 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(this->mem_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; -} - - -const glsl_type * -glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) -{ - - if (array_types == NULL) { - array_types = hash_table_ctor(64, hash_table_string_hash, - hash_table_string_compare); - } - - /* Generate a name using the base type pointer in the key. This is - * done because the name of the base type may not be unique across - * shaders. For example, two shaders may have different record types - * named 'foo'. - */ - char key[128]; - snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size); - - const glsl_type *t = (glsl_type *) hash_table_find(array_types, key); - if (t == NULL) { - t = new glsl_type(base, array_size); - - hash_table_insert(array_types, (void *) t, talloc_strdup(mem_ctx, key)); - } - - assert(t->base_type == GLSL_TYPE_ARRAY); - assert(t->length == array_size); - assert(t->fields.array == base); - - return t; -} - - -int -glsl_type::record_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. - */ - if (strcmp(key1->name, key2->name) != 0) - return 1; - - if (key1->length != key2->length) - return 1; - - for (unsigned i = 0; i < key1->length; i++) { - if (key1->fields.structure[i].type != key2->fields.structure[i].type) - return 1; - if (strcmp(key1->fields.structure[i].name, - key2->fields.structure[i].name) != 0) - return 1; - } - - return 0; -} - - -unsigned -glsl_type::record_key_hash(const void *a) -{ - const glsl_type *const key = (glsl_type *) a; - char hash_key[128]; - unsigned size = 0; - - size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length); - - for (unsigned i = 0; i < key->length; i++) { - if (size >= sizeof(hash_key)) - break; - - size += snprintf(& hash_key[size], sizeof(hash_key) - size, - "%p", (void *) key->fields.structure[i].type); - } - - return hash_table_string_hash(& hash_key); -} - - -const glsl_type * -glsl_type::get_record_instance(const glsl_struct_field *fields, - unsigned num_fields, - const char *name) -{ - const glsl_type key(fields, num_fields, name); - - if (record_types == NULL) { - record_types = hash_table_ctor(64, record_key_hash, record_key_compare); - } - - const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key); - if (t == NULL) { - t = new glsl_type(fields, num_fields, name); - - hash_table_insert(record_types, (void *) t, t); - } - - assert(t->base_type == GLSL_TYPE_STRUCT); - assert(t->length == num_fields); - assert(strcmp(t->name, name) == 0); - - 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; - } -} +/*
+ * 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 "main/core.h" /* for Elements */
+#include "glsl_symbol_table.h"
+#include "glsl_parser_extras.h"
+#include "glsl_types.h"
+#include "builtin_types.h"
+extern "C" {
+#include "program/hash_table.h"
+}
+
+hash_table *glsl_type::array_types = NULL;
+hash_table *glsl_type::record_types = NULL;
+void *glsl_type::mem_ctx = NULL;
+
+void
+glsl_type::init_talloc_type_ctx(void)
+{
+ if (glsl_type::mem_ctx == NULL) {
+ glsl_type::mem_ctx = talloc_autofree_context();
+ assert(glsl_type::mem_ctx != NULL);
+ }
+}
+
+glsl_type::glsl_type(GLenum gl_type,
+ glsl_base_type base_type, unsigned vector_elements,
+ unsigned matrix_columns, const char *name) :
+ gl_type(gl_type),
+ base_type(base_type),
+ sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+ sampler_type(0),
+ vector_elements(vector_elements), matrix_columns(matrix_columns),
+ length(0)
+{
+ init_talloc_type_ctx();
+ this->name = talloc_strdup(this->mem_ctx, name);
+ /* Neither dimension is zero or both dimensions are zero.
+ */
+ assert((vector_elements == 0) == (matrix_columns == 0));
+ memset(& fields, 0, sizeof(fields));
+}
+
+glsl_type::glsl_type(GLenum gl_type,
+ enum glsl_sampler_dim dim, bool shadow, bool array,
+ unsigned type, const char *name) :
+ gl_type(gl_type),
+ base_type(GLSL_TYPE_SAMPLER),
+ sampler_dimensionality(dim), sampler_shadow(shadow),
+ sampler_array(array), sampler_type(type),
+ vector_elements(0), matrix_columns(0),
+ length(0)
+{
+ init_talloc_type_ctx();
+ this->name = talloc_strdup(this->mem_ctx, name);
+ memset(& fields, 0, sizeof(fields));
+}
+
+glsl_type::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),
+ length(num_fields)
+{
+ unsigned int i;
+
+ init_talloc_type_ctx();
+ this->name = talloc_strdup(this->mem_ctx, name);
+ this->fields.structure = talloc_array(this->mem_ctx,
+ glsl_struct_field, length);
+ for (i = 0; i < length; i++) {
+ this->fields.structure[i].type = fields[i].type;
+ this->fields.structure[i].name = talloc_strdup(this->fields.structure,
+ fields[i].name);
+ }
+}
+
+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]);
+ }
+}
+
+void
+glsl_type::generate_100ES_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, void_type, 1, false);
+}
+
+void
+glsl_type::generate_110_types(glsl_symbol_table *symtab)
+{
+ generate_100ES_types(symtab);
+
+ add_types_to_symbol_table(symtab, builtin_110_types,
+ Elements(builtin_110_types),
+ false);
+ add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
+ Elements(builtin_110_deprecated_structure_types),
+ false);
+}
+
+
+void
+glsl_type::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);
+}
+
+
+void
+glsl_type::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);
+ generate_EXT_texture_array_types(symtab, false);
+}
+
+
+void
+glsl_type::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);
+}
+
+
+void
+glsl_type::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 100:
+ assert(state->es_shader);
+ glsl_type::generate_100ES_types(state->symbols);
+ break;
+ case 110:
+ glsl_type::generate_110_types(state->symbols);
+ break;
+ case 120:
+ glsl_type::generate_120_types(state->symbols);
+ break;
+ case 130:
+ glsl_type::generate_130_types(state->symbols);
+ break;
+ default:
+ /* error */
+ break;
+ }
+
+ if (state->ARB_texture_rectangle_enable) {
+ glsl_type::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.
+ glsl_type::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;
+ }
+}
+
+
+void
+_mesa_glsl_release_types(void)
+{
+ if (glsl_type::array_types != NULL) {
+ hash_table_dtor(glsl_type::array_types);
+ glsl_type::array_types = NULL;
+ }
+
+ if (glsl_type::record_types != NULL) {
+ hash_table_dtor(glsl_type::record_types);
+ glsl_type::record_types = NULL;
+ }
+}
+
+
+glsl_type::glsl_type(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;
+ /* Inherit the gl type of the base. The GL type is used for
+ * uniform/statevar handling in Mesa and the arrayness of the type
+ * is represented by the size rather than the type.
+ */
+ this->gl_type = array->gl_type;
+
+ /* 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(this->mem_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;
+}
+
+
+const glsl_type *
+glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
+{
+
+ if (array_types == NULL) {
+ array_types = hash_table_ctor(64, hash_table_string_hash,
+ hash_table_string_compare);
+ }
+
+ /* Generate a name using the base type pointer in the key. This is
+ * done because the name of the base type may not be unique across
+ * shaders. For example, two shaders may have different record types
+ * named 'foo'.
+ */
+ char key[128];
+ snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
+
+ const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
+ if (t == NULL) {
+ t = new glsl_type(base, array_size);
+
+ hash_table_insert(array_types, (void *) t, talloc_strdup(mem_ctx, key));
+ }
+
+ assert(t->base_type == GLSL_TYPE_ARRAY);
+ assert(t->length == array_size);
+ assert(t->fields.array == base);
+
+ return t;
+}
+
+
+int
+glsl_type::record_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.
+ */
+ if (strcmp(key1->name, key2->name) != 0)
+ return 1;
+
+ if (key1->length != key2->length)
+ return 1;
+
+ for (unsigned i = 0; i < key1->length; i++) {
+ if (key1->fields.structure[i].type != key2->fields.structure[i].type)
+ return 1;
+ if (strcmp(key1->fields.structure[i].name,
+ key2->fields.structure[i].name) != 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+unsigned
+glsl_type::record_key_hash(const void *a)
+{
+ const glsl_type *const key = (glsl_type *) a;
+ char hash_key[128];
+ unsigned size = 0;
+
+ size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
+
+ for (unsigned i = 0; i < key->length; i++) {
+ if (size >= sizeof(hash_key))
+ break;
+
+ size += snprintf(& hash_key[size], sizeof(hash_key) - size,
+ "%p", (void *) key->fields.structure[i].type);
+ }
+
+ return hash_table_string_hash(& hash_key);
+}
+
+
+const glsl_type *
+glsl_type::get_record_instance(const glsl_struct_field *fields,
+ unsigned num_fields,
+ const char *name)
+{
+ const glsl_type key(fields, num_fields, name);
+
+ if (record_types == NULL) {
+ record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
+ }
+
+ const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
+ if (t == NULL) {
+ t = new glsl_type(fields, num_fields, name);
+
+ hash_table_insert(record_types, (void *) t, t);
+ }
+
+ assert(t->base_type == GLSL_TYPE_STRUCT);
+ assert(t->length == num_fields);
+ assert(strcmp(t->name, name) == 0);
+
+ 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;
+ }
+}
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index 4f7d2f74a..310747f57 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -1,476 +1,475 @@ -/* -*- 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 "GL/gl.h" -#include <talloc.h> -} - -struct _mesa_glsl_parse_state; -struct glsl_symbol_table; - -extern "C" void -_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); - -extern "C" void -_mesa_glsl_release_types(void); - -#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 { - GLenum gl_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 'mem_ctx' (or any of its ancestors). */ - static void* operator new(size_t size) - { - if (glsl_type::mem_ctx == NULL) { - glsl_type::mem_ctx = talloc_init("glsl_type"); - assert(glsl_type::mem_ctx != NULL); - } - - void *type; - - type = talloc_size(glsl_type::mem_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. */ - 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; - /*@}*/ - - - /** - * 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(const glsl_type *base, - unsigned elements); - - /** - * Get the instance of a record type - */ - static const glsl_type *get_record_instance(const glsl_struct_field *fields, - unsigned num_fields, - const char *name); - - /** - * 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: - /** - * talloc context for all glsl_type allocations - * - * Set on the first call to \c glsl_type::new. - */ - static void *mem_ctx; - - void init_talloc_type_ctx(void); - - /** Constructor for vector and matrix types */ - glsl_type(GLenum gl_type, - unsigned base_type, unsigned vector_elements, - unsigned matrix_columns, const char *name); - - /** Constructor for sampler types */ - glsl_type(GLenum gl_type, - enum glsl_sampler_dim dim, bool shadow, bool array, - unsigned type, const char *name); - - /** Constructor for record types */ - glsl_type(const glsl_struct_field *fields, unsigned num_fields, - const char *name); - - /** Constructor for array types */ - glsl_type(const glsl_type *array, unsigned length); - - /** Hash table containing the known array types. */ - static struct hash_table *array_types; - - /** Hash table containing the known record types. */ - static struct hash_table *record_types; - - static int record_key_compare(const void *a, const void *b); - static unsigned record_key_hash(const void *key); - - /** - * \name Pointers to various type singletons - */ - /*@{*/ - static const glsl_type _error_type; - static const glsl_type void_type; - static const glsl_type builtin_core_types[]; - static const glsl_type builtin_structure_types[]; - static const glsl_type builtin_110_deprecated_structure_types[]; - static const glsl_type builtin_110_types[]; - static const glsl_type builtin_120_types[]; - static const glsl_type builtin_130_types[]; - static const glsl_type builtin_ARB_texture_rectangle_types[]; - static const glsl_type builtin_EXT_texture_array_types[]; - static const glsl_type builtin_EXT_texture_buffer_object_types[]; - /*@}*/ - - /** - * \name Methods to populate a symbol table with built-in types. - * - * \internal - * This is one of the truely annoying things about C++. Methods that are - * completely internal and private to a type still have to be advertised to - * the world in a public header file. - */ - /*@{*/ - static void generate_100ES_types(glsl_symbol_table *); - static void generate_110_types(glsl_symbol_table *); - static void generate_120_types(glsl_symbol_table *); - static void generate_130_types(glsl_symbol_table *); - static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool); - static void generate_EXT_texture_array_types(glsl_symbol_table *, bool); - /*@}*/ - - /** - * \name Friend functions. - * - * These functions are friends because they must have C linkage and the - * need to call various private methods or access various private static - * data. - */ - /*@{*/ - friend void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *); - friend void _mesa_glsl_release_types(void); - /*@}*/ -}; - -struct glsl_struct_field { - const struct glsl_type *type; - const char *name; -}; - -#endif /* GLSL_TYPES_H */ +/* -*- c++ -*- */
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+#ifndef GLSL_TYPES_H
+#define GLSL_TYPES_H
+
+#include <cstring>
+#include <cassert>
+
+extern "C" {
+#include "GL/gl.h"
+#include <talloc.h>
+}
+
+struct _mesa_glsl_parse_state;
+struct glsl_symbol_table;
+
+extern "C" void
+_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
+
+extern "C" void
+_mesa_glsl_release_types(void);
+
+enum glsl_base_type {
+ GLSL_TYPE_UINT = 0,
+ GLSL_TYPE_INT,
+ GLSL_TYPE_FLOAT,
+ GLSL_TYPE_BOOL,
+ GLSL_TYPE_SAMPLER,
+ GLSL_TYPE_STRUCT,
+ GLSL_TYPE_ARRAY,
+ GLSL_TYPE_VOID,
+ GLSL_TYPE_ERROR
+};
+
+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 {
+ GLenum gl_type;
+ glsl_base_type base_type;
+
+ 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 'mem_ctx' (or any of its ancestors). */
+ static void* operator new(size_t size)
+ {
+ if (glsl_type::mem_ctx == NULL) {
+ glsl_type::mem_ctx = talloc_init("glsl_type");
+ assert(glsl_type::mem_ctx != NULL);
+ }
+
+ void *type;
+
+ type = talloc_size(glsl_type::mem_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).
+ */
+ 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. */
+ 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 void_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 uvec2_type;
+ static const glsl_type *const uvec3_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;
+ /*@}*/
+
+
+ /**
+ * 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(const glsl_type *base,
+ unsigned elements);
+
+ /**
+ * Get the instance of a record type
+ */
+ static const glsl_type *get_record_instance(const glsl_struct_field *fields,
+ unsigned num_fields,
+ const char *name);
+
+ /**
+ * 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:
+ /**
+ * talloc context for all glsl_type allocations
+ *
+ * Set on the first call to \c glsl_type::new.
+ */
+ static void *mem_ctx;
+
+ void init_talloc_type_ctx(void);
+
+ /** Constructor for vector and matrix types */
+ glsl_type(GLenum gl_type,
+ glsl_base_type base_type, unsigned vector_elements,
+ unsigned matrix_columns, const char *name);
+
+ /** Constructor for sampler types */
+ glsl_type(GLenum gl_type,
+ enum glsl_sampler_dim dim, bool shadow, bool array,
+ unsigned type, const char *name);
+
+ /** Constructor for record types */
+ glsl_type(const glsl_struct_field *fields, unsigned num_fields,
+ const char *name);
+
+ /** Constructor for array types */
+ glsl_type(const glsl_type *array, unsigned length);
+
+ /** Hash table containing the known array types. */
+ static struct hash_table *array_types;
+
+ /** Hash table containing the known record types. */
+ static struct hash_table *record_types;
+
+ static int record_key_compare(const void *a, const void *b);
+ static unsigned record_key_hash(const void *key);
+
+ /**
+ * \name Pointers to various type singletons
+ */
+ /*@{*/
+ static const glsl_type _error_type;
+ static const glsl_type _void_type;
+ static const glsl_type builtin_core_types[];
+ static const glsl_type builtin_structure_types[];
+ static const glsl_type builtin_110_deprecated_structure_types[];
+ static const glsl_type builtin_110_types[];
+ static const glsl_type builtin_120_types[];
+ static const glsl_type builtin_130_types[];
+ static const glsl_type builtin_ARB_texture_rectangle_types[];
+ static const glsl_type builtin_EXT_texture_array_types[];
+ static const glsl_type builtin_EXT_texture_buffer_object_types[];
+ /*@}*/
+
+ /**
+ * \name Methods to populate a symbol table with built-in types.
+ *
+ * \internal
+ * This is one of the truely annoying things about C++. Methods that are
+ * completely internal and private to a type still have to be advertised to
+ * the world in a public header file.
+ */
+ /*@{*/
+ static void generate_100ES_types(glsl_symbol_table *);
+ static void generate_110_types(glsl_symbol_table *);
+ static void generate_120_types(glsl_symbol_table *);
+ static void generate_130_types(glsl_symbol_table *);
+ static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool);
+ static void generate_EXT_texture_array_types(glsl_symbol_table *, bool);
+ /*@}*/
+
+ /**
+ * \name Friend functions.
+ *
+ * These functions are friends because they must have C linkage and the
+ * need to call various private methods or access various private static
+ * data.
+ */
+ /*@{*/
+ friend void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *);
+ friend void _mesa_glsl_release_types(void);
+ /*@}*/
+};
+
+struct glsl_struct_field {
+ const struct glsl_type *type;
+ const char *name;
+};
+
+#endif /* GLSL_TYPES_H */
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 5e2109ecc..b47f4bd9d 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1,1238 +1,1495 @@ -/* - * 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/core.h" /* for MAX2 */ -#include "ir.h" -#include "ir_visitor.h" -#include "glsl_types.h" - -ir_rvalue::ir_rvalue() -{ - this->type = glsl_type::error_type; -} - -/** - * Modify the swizzle make to move one component to another - * - * \param m IR swizzle to be modified - * \param from Component in the RHS that is to be swizzled - * \param to Desired swizzle location of \c from - */ -static void -update_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to) -{ - switch (to) { - case 0: m.x = from; break; - case 1: m.y = from; break; - case 2: m.z = from; break; - case 3: m.w = from; break; - default: assert(!"Should not get here."); - } - - m.num_components = MAX2(m.num_components, (to + 1)); -} - -void -ir_assignment::set_lhs(ir_rvalue *lhs) -{ - void *mem_ctx = this; - bool swizzled = false; - - while (lhs != NULL) { - ir_swizzle *swiz = lhs->as_swizzle(); - - if (swiz == NULL) - break; - - unsigned write_mask = 0; - ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 }; - - for (unsigned i = 0; i < swiz->mask.num_components; i++) { - unsigned c = 0; - - switch (i) { - case 0: c = swiz->mask.x; break; - case 1: c = swiz->mask.y; break; - case 2: c = swiz->mask.z; break; - case 3: c = swiz->mask.w; break; - default: assert(!"Should not get here."); - } - - write_mask |= (((this->write_mask >> i) & 1) << c); - update_rhs_swizzle(rhs_swiz, i, c); - } - - this->write_mask = write_mask; - lhs = swiz->val; - - this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz); - swizzled = true; - } - - if (swizzled) { - /* Now, RHS channels line up with the LHS writemask. Collapse it - * to just the channels that will be written. - */ - ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 }; - int rhs_chan = 0; - for (int i = 0; i < 4; i++) { - if (write_mask & (1 << i)) - update_rhs_swizzle(rhs_swiz, i, rhs_chan++); - } - this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz); - } - - assert((lhs == NULL) || lhs->as_dereference()); - - this->lhs = (ir_dereference *) lhs; -} - -ir_variable * -ir_assignment::whole_variable_written() -{ - ir_variable *v = this->lhs->whole_variable_referenced(); - - if (v == NULL) - return NULL; - - if (v->type->is_scalar()) - return v; - - if (v->type->is_vector()) { - const unsigned mask = (1U << v->type->vector_elements) - 1; - - if (mask != this->write_mask) - return NULL; - } - - /* Either all the vector components are assigned or the variable is some - * composite type (and the whole thing is assigned. - */ - return v; -} - -ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, - ir_rvalue *condition, unsigned write_mask) -{ - this->ir_type = ir_type_assignment; - this->condition = condition; - this->rhs = rhs; - this->lhs = lhs; - this->write_mask = write_mask; - - if (lhs->type->is_scalar() || lhs->type->is_vector()) { - int lhs_components = 0; - for (int i = 0; i < 4; i++) { - if (write_mask & (1 << i)) - lhs_components++; - } - - assert(lhs_components == this->rhs->type->vector_elements); - } -} - -ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, - ir_rvalue *condition) -{ - this->ir_type = ir_type_assignment; - this->condition = condition; - this->rhs = rhs; - - /* If the RHS is a vector type, assume that all components of the vector - * type are being written to the LHS. The write mask comes from the RHS - * because we can have a case where the LHS is a vec4 and the RHS is a - * vec3. In that case, the assignment is: - * - * (assign (...) (xyz) (var_ref lhs) (var_ref rhs)) - */ - if (rhs->type->is_vector()) - this->write_mask = (1U << rhs->type->vector_elements) - 1; - else if (rhs->type->is_scalar()) - this->write_mask = 1; - else - this->write_mask = 0; - - this->set_lhs(lhs); -} - - -ir_expression::ir_expression(int op, const struct glsl_type *type, - ir_rvalue *op0, ir_rvalue *op1) -{ - this->ir_type = ir_type_expression; - 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_any */ - - 1, /* ir_unop_trunc */ - 1, /* ir_unop_ceil */ - 1, /* ir_unop_floor */ - 1, /* ir_unop_fract */ - - 1, /* ir_unop_sin */ - 1, /* ir_unop_cos */ - - 1, /* ir_unop_dFdx */ - 1, /* ir_unop_dFdy */ - - 1, /* ir_unop_noise */ - - 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_all_equal */ - 2, /* ir_binop_any_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_cross */ - 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", - "any", - "trunc", - "ceil", - "floor", - "fract", - "sin", - "cos", - "dFdx", - "dFdy", - "noise", - "+", - "-", - "*", - "/", - "%", - "<", - ">", - "<=", - ">=", - "==", - "!=", - "all_equal", - "any_nequal", - "<<", - ">>", - "&", - "^", - "|", - "&&", - "^^", - "||", - "dot", - "cross", - "min", - "max", - "pow", -}; - -const char *ir_expression::operator_string(ir_expression_operation op) -{ - assert((unsigned int) op < Elements(operator_strs)); - assert(Elements(operator_strs) == (ir_binop_pow + 1)); - return operator_strs[op]; -} - -const char *ir_expression::operator_string() -{ - return operator_string(this->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() -{ - this->ir_type = ir_type_constant; -} - -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->ir_type = ir_type_constant; - this->type = type; - memcpy(& this->value, data, sizeof(this->value)); -} - -ir_constant::ir_constant(float f) -{ - this->ir_type = ir_type_constant; - this->type = glsl_type::float_type; - this->value.f[0] = f; - for (int i = 1; i < 16; i++) { - this->value.f[i] = 0; - } -} - -ir_constant::ir_constant(unsigned int u) -{ - this->ir_type = ir_type_constant; - this->type = glsl_type::uint_type; - this->value.u[0] = u; - for (int i = 1; i < 16; i++) { - this->value.u[i] = 0; - } -} - -ir_constant::ir_constant(int i) -{ - this->ir_type = ir_type_constant; - this->type = glsl_type::int_type; - this->value.i[0] = i; - for (int i = 1; i < 16; i++) { - this->value.i[i] = 0; - } -} - -ir_constant::ir_constant(bool b) -{ - this->ir_type = ir_type_constant; - this->type = glsl_type::bool_type; - this->value.b[0] = b; - for (int i = 1; i < 16; i++) { - this->value.b[i] = false; - } -} - -ir_constant::ir_constant(const ir_constant *c, unsigned i) -{ - this->ir_type = ir_type_constant; - 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->ir_type = ir_type_constant; - this->type = type; - - assert(type->is_scalar() || type->is_vector() || type->is_matrix() - || type->is_record() || type->is_array()); - - if (type->is_array()) { - this->array_elements = talloc_array(this, ir_constant *, type->length); - unsigned i = 0; - foreach_list(node, value_list) { - ir_constant *value = (ir_constant *) node; - assert(value->as_constant() != NULL); - - this->array_elements[i++] = value; - } - return; - } - - /* 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; - } - - for (unsigned i = 0; i < 16; i++) { - this->value.u[i] = 0; - } - - ir_constant *value = (ir_constant *) (value_list->head); - - /* Constructors with exactly one scalar argument are special for vectors - * and matrices. For vectors, the scalar value is replicated to fill all - * the components. For matrices, the scalar fills the components of the - * diagonal while the rest is filled with 0. - */ - if (value->type->is_scalar() && value->next->is_tail_sentinel()) { - if (type->is_matrix()) { - /* Matrix - fill diagonal (rest is already set to 0) */ - assert(type->base_type == GLSL_TYPE_FLOAT); - for (unsigned i = 0; i < type->matrix_columns; i++) - this->value.f[i * type->vector_elements + i] = value->value.f[0]; - } else { - /* Vector or scalar - fill all components */ - switch (type->base_type) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: - for (unsigned i = 0; i < type->components(); i++) - this->value.u[i] = value->value.u[0]; - break; - case GLSL_TYPE_FLOAT: - for (unsigned i = 0; i < type->components(); i++) - this->value.f[i] = value->value.f[0]; - break; - case GLSL_TYPE_BOOL: - for (unsigned i = 0; i < type->components(); i++) - this->value.b[i] = value->value.b[0]; - break; - default: - assert(!"Should not get here."); - break; - } - } - return; - } - - if (type->is_matrix() && value->type->is_matrix()) { - assert(value->next->is_tail_sentinel()); - - /* From section 5.4.2 of the GLSL 1.20 spec: - * "If a matrix is constructed from a matrix, then each component - * (column i, row j) in the result that has a corresponding component - * (column i, row j) in the argument will be initialized from there." - */ - unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns); - unsigned rows = MIN2(type->vector_elements, value->type->vector_elements); - for (unsigned i = 0; i < cols; i++) { - for (unsigned j = 0; j < rows; j++) { - const unsigned src = i * value->type->vector_elements + j; - const unsigned dst = i * type->vector_elements + j; - this->value.f[dst] = value->value.f[src]; - } - } - - /* "All other components will be initialized to the identity matrix." */ - for (unsigned i = cols; i < type->matrix_columns; i++) - this->value.f[i * type->vector_elements + i] = 1.0; - - return; - } - - /* 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_sentinel()); - - 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; - } -} - -ir_constant * -ir_constant::zero(void *mem_ctx, const glsl_type *type) -{ - assert(type->is_numeric() || type->is_boolean()); - - ir_constant *c = new(mem_ctx) ir_constant; - c->type = type; - memset(&c->value, 0, sizeof(c->value)); - - return c; -} - -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_array_element(unsigned i) const -{ - assert(this->type->is_array()); - - /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec: - * - * "Behavior is undefined if a shader subscripts an array with an index - * less than 0 or greater than or equal to the size the array was - * declared with." - * - * Most out-of-bounds accesses are removed before things could get this far. - * There are cases where non-constant array index values can get constant - * folded. - */ - if (int(i) < 0) - i = 0; - else if (i >= this->type->length) - i = this->type->length - 1; - - return array_elements[i]; -} - -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_sentinel()) - return NULL; - } - - return (ir_constant *) node; -} - - -bool -ir_constant::has_value(const ir_constant *c) const -{ - if (this->type != c->type) - return false; - - if (this->type->is_array()) { - for (unsigned i = 0; i < this->type->length; i++) { - if (this->array_elements[i]->has_value(c->array_elements[i])) - return false; - } - return true; - } - - 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_sentinel()) { - assert(!b_node->is_tail_sentinel()); - - 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_loop::ir_loop() -{ - this->ir_type = ir_type_loop; - this->cmp = ir_unop_neg; - this->from = NULL; - this->to = NULL; - this->increment = NULL; - this->counter = NULL; -} - - -ir_dereference_variable::ir_dereference_variable(ir_variable *var) -{ - this->ir_type = ir_type_dereference_variable; - 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->ir_type = ir_type_dereference_array; - 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->ir_type = ir_type_dereference_array; - 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->ir_type = ir_type_dereference_record; - this->record = value; - this->field = talloc_strdup(this, 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->ir_type = ir_type_dereference_record; - this->record = new(ctx) ir_dereference_variable(var); - this->field = talloc_strdup(this, field); - this->type = (this->record != NULL) - ? this->record->type->field_type(field) : glsl_type::error_type; -} - -bool type_contains_sampler(const glsl_type *type) -{ - if (type->is_array()) { - return type_contains_sampler(type->fields.array); - } else if (type->is_record()) { - for (unsigned int i = 0; i < type->length; i++) { - if (type_contains_sampler(type->fields.structure[i].type)) - return true; - } - return false; - } else { - return type->is_sampler(); - } -} - -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; - - /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: - * - * "Samplers cannot be treated as l-values; hence cannot be used - * as out or inout function parameters, nor can they be - * assigned into." - */ - if (type_contains_sampler(this->type)) - 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; - } -} - - -void -ir_swizzle::init_mask(const unsigned *comp, unsigned count) -{ - assert((count >= 1) && (count <= 4)); - - memset(&this->mask, 0, sizeof(this->mask)); - this->mask.num_components = count; - - unsigned dup_mask = 0; - switch (count) { - case 4: - assert(comp[3] <= 3); - dup_mask |= (1U << comp[3]) - & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2])); - this->mask.w = comp[3]; - - case 3: - assert(comp[2] <= 3); - dup_mask |= (1U << comp[2]) - & ((1U << comp[0]) | (1U << comp[1])); - this->mask.z = comp[2]; - - case 2: - assert(comp[1] <= 3); - dup_mask |= (1U << comp[1]) - & ((1U << comp[0])); - this->mask.y = comp[1]; - - case 1: - assert(comp[0] <= 3); - this->mask.x = comp[0]; - } - - this->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, unsigned x, unsigned y, unsigned z, - unsigned w, unsigned count) - : val(val) -{ - const unsigned components[4] = { x, y, z, w }; - this->ir_type = ir_type_swizzle; - this->init_mask(components, count); -} - -ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp, - unsigned count) - : val(val) -{ - this->ir_type = ir_type_swizzle; - this->init_mask(comp, count); -} - -ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) -{ - this->ir_type = ir_type_swizzle; - 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, - ir_variable_mode mode) - : max_array_access(0), read_only(false), centroid(false), invariant(false), - mode(mode), interpolation(ir_var_smooth), array_lvalue(false) -{ - this->ir_type = ir_type_variable; - this->type = type; - this->name = talloc_strdup(this, name); - this->location = -1; - this->warn_extension = NULL; - this->constant_value = NULL; - this->origin_upper_left = false; - this->pixel_center_integer = false; - - if (type && type->base_type == GLSL_TYPE_SAMPLER) - this->read_only = true; -} - - -const char * -ir_variable::interpolation_string() const -{ - 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), _function(NULL) -{ - this->ir_type = ir_type_function_signature; - this->is_builtin = false; -} - - -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) -{ - this->ir_type = ir_type_function; - this->name = talloc_strdup(this, name); -} - - -bool -ir_function::has_user_signature() -{ - foreach_list(n, &this->signatures) { - ir_function_signature *const sig = (ir_function_signature *) n; - if (!sig->is_builtin) - return true; - } - return false; -} - - -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 -ir_call::set_callee(ir_function_signature *sig) -{ - assert((this->type == NULL) || (this->type == sig->return_type)); - - this->callee = sig; -} - -void -visit_exec_list(exec_list *list, ir_visitor *visitor) -{ - foreach_iter(exec_list_iterator, iter, *list) { - ((ir_instruction *)iter.get())->accept(visitor); - } -} - - -static void -steal_memory(ir_instruction *ir, void *new_ctx) -{ - ir_variable *var = ir->as_variable(); - ir_constant *constant = ir->as_constant(); - if (var != NULL && var->constant_value != NULL) - steal_memory(var->constant_value, ir); - - /* The components of aggregate constants are not visited by the normal - * visitor, so steal their values by hand. - */ - if (constant != NULL) { - if (constant->type->is_record()) { - foreach_iter(exec_list_iterator, iter, constant->components) { - ir_constant *field = (ir_constant *)iter.get(); - steal_memory(field, ir); - } - } else if (constant->type->is_array()) { - for (unsigned int i = 0; i < constant->type->length; i++) { - steal_memory(constant->array_elements[i], ir); - } - } - } - - talloc_steal(new_ctx, ir); -} - - -void -reparent_ir(exec_list *list, void *mem_ctx) -{ - foreach_list(node, list) { - visit_tree((ir_instruction *) node, steal_memory, mem_ctx); - } -} +/*
+ * 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/core.h" /* for MAX2 */
+#include "ir.h"
+#include "ir_visitor.h"
+#include "glsl_types.h"
+
+ir_rvalue::ir_rvalue()
+{
+ this->type = glsl_type::error_type;
+}
+
+bool ir_rvalue::is_zero() const
+{
+ return false;
+}
+
+bool ir_rvalue::is_one() const
+{
+ return false;
+}
+
+bool ir_rvalue::is_negative_one() const
+{
+ return false;
+}
+
+/**
+ * Modify the swizzle make to move one component to another
+ *
+ * \param m IR swizzle to be modified
+ * \param from Component in the RHS that is to be swizzled
+ * \param to Desired swizzle location of \c from
+ */
+static void
+update_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
+{
+ switch (to) {
+ case 0: m.x = from; break;
+ case 1: m.y = from; break;
+ case 2: m.z = from; break;
+ case 3: m.w = from; break;
+ default: assert(!"Should not get here.");
+ }
+
+ m.num_components = MAX2(m.num_components, (to + 1));
+}
+
+void
+ir_assignment::set_lhs(ir_rvalue *lhs)
+{
+ void *mem_ctx = this;
+ bool swizzled = false;
+
+ while (lhs != NULL) {
+ ir_swizzle *swiz = lhs->as_swizzle();
+
+ if (swiz == NULL)
+ break;
+
+ unsigned write_mask = 0;
+ ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
+
+ for (unsigned i = 0; i < swiz->mask.num_components; i++) {
+ unsigned c = 0;
+
+ switch (i) {
+ case 0: c = swiz->mask.x; break;
+ case 1: c = swiz->mask.y; break;
+ case 2: c = swiz->mask.z; break;
+ case 3: c = swiz->mask.w; break;
+ default: assert(!"Should not get here.");
+ }
+
+ write_mask |= (((this->write_mask >> i) & 1) << c);
+ update_rhs_swizzle(rhs_swiz, i, c);
+ }
+
+ this->write_mask = write_mask;
+ lhs = swiz->val;
+
+ this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
+ swizzled = true;
+ }
+
+ if (swizzled) {
+ /* Now, RHS channels line up with the LHS writemask. Collapse it
+ * to just the channels that will be written.
+ */
+ ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
+ int rhs_chan = 0;
+ for (int i = 0; i < 4; i++) {
+ if (write_mask & (1 << i))
+ update_rhs_swizzle(rhs_swiz, i, rhs_chan++);
+ }
+ this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
+ }
+
+ assert((lhs == NULL) || lhs->as_dereference());
+
+ this->lhs = (ir_dereference *) lhs;
+}
+
+ir_variable *
+ir_assignment::whole_variable_written()
+{
+ ir_variable *v = this->lhs->whole_variable_referenced();
+
+ if (v == NULL)
+ return NULL;
+
+ if (v->type->is_scalar())
+ return v;
+
+ if (v->type->is_vector()) {
+ const unsigned mask = (1U << v->type->vector_elements) - 1;
+
+ if (mask != this->write_mask)
+ return NULL;
+ }
+
+ /* Either all the vector components are assigned or the variable is some
+ * composite type (and the whole thing is assigned.
+ */
+ return v;
+}
+
+ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
+ ir_rvalue *condition, unsigned write_mask)
+{
+ this->ir_type = ir_type_assignment;
+ this->condition = condition;
+ this->rhs = rhs;
+ this->lhs = lhs;
+ this->write_mask = write_mask;
+
+ if (lhs->type->is_scalar() || lhs->type->is_vector()) {
+ int lhs_components = 0;
+ for (int i = 0; i < 4; i++) {
+ if (write_mask & (1 << i))
+ lhs_components++;
+ }
+
+ assert(lhs_components == this->rhs->type->vector_elements);
+ }
+}
+
+ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
+ ir_rvalue *condition)
+{
+ this->ir_type = ir_type_assignment;
+ this->condition = condition;
+ this->rhs = rhs;
+
+ /* If the RHS is a vector type, assume that all components of the vector
+ * type are being written to the LHS. The write mask comes from the RHS
+ * because we can have a case where the LHS is a vec4 and the RHS is a
+ * vec3. In that case, the assignment is:
+ *
+ * (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
+ */
+ if (rhs->type->is_vector())
+ this->write_mask = (1U << rhs->type->vector_elements) - 1;
+ else if (rhs->type->is_scalar())
+ this->write_mask = 1;
+ else
+ this->write_mask = 0;
+
+ this->set_lhs(lhs);
+}
+
+
+ir_expression::ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *op0)
+{
+ assert(get_num_operands(ir_expression_operation(op)) == 1);
+ this->ir_type = ir_type_expression;
+ this->type = type;
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = NULL;
+ this->operands[2] = NULL;
+ this->operands[3] = NULL;
+}
+
+ir_expression::ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *op0, ir_rvalue *op1)
+{
+ assert(((op1 == NULL) && (get_num_operands(ir_expression_operation(op)) == 1))
+ || (get_num_operands(ir_expression_operation(op)) == 2));
+ this->ir_type = ir_type_expression;
+ this->type = type;
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = op1;
+ this->operands[2] = NULL;
+ this->operands[3] = NULL;
+}
+
+ir_expression::ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *op0, ir_rvalue *op1,
+ ir_rvalue *op2, ir_rvalue *op3)
+{
+ this->ir_type = ir_type_expression;
+ this->type = type;
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = op1;
+ this->operands[2] = op2;
+ this->operands[3] = op3;
+}
+
+ir_expression::ir_expression(int op, ir_rvalue *op0)
+{
+ this->ir_type = ir_type_expression;
+
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = NULL;
+ this->operands[2] = NULL;
+ this->operands[3] = NULL;
+
+ assert(op <= ir_last_unop);
+
+ switch (this->operation) {
+ case ir_unop_bit_not:
+ case ir_unop_logic_not:
+ case ir_unop_neg:
+ case ir_unop_abs:
+ case ir_unop_sign:
+ case ir_unop_rcp:
+ case ir_unop_rsq:
+ case ir_unop_sqrt:
+ case ir_unop_exp:
+ case ir_unop_log:
+ case ir_unop_exp2:
+ case ir_unop_log2:
+ case ir_unop_trunc:
+ case ir_unop_ceil:
+ case ir_unop_floor:
+ case ir_unop_fract:
+ case ir_unop_round_even:
+ case ir_unop_cos:
+ case ir_unop_dFdx:
+ case ir_unop_dFdy:
+ this->type = op0->type;
+ break;
+
+ case ir_unop_any:
+ this->type = glsl_type::bool_type;
+ break;
+
+ default:
+ assert(!"not reached: missing automatic type setup for ir_expression");
+ this->type = op0->type;
+ break;
+ }
+}
+
+ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
+{
+ this->ir_type = ir_type_expression;
+
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = op1;
+ this->operands[2] = NULL;
+ this->operands[3] = NULL;
+
+ assert(op > ir_last_unop);
+
+ switch (this->operation) {
+ case ir_binop_all_equal:
+ case ir_binop_any_nequal:
+ this->type = glsl_type::bool_type;
+ break;
+
+ case ir_binop_add:
+ case ir_binop_sub:
+ case ir_binop_min:
+ case ir_binop_max:
+ case ir_binop_pow:
+ case ir_binop_mul:
+ if (op0->type->is_scalar()) {
+ this->type = op1->type;
+ } else if (op1->type->is_scalar()) {
+ this->type = op0->type;
+ } else {
+ /* FINISHME: matrix types */
+ assert(!op0->type->is_matrix() && !op1->type->is_matrix());
+ assert(op0->type == op1->type);
+ this->type = op0->type;
+ }
+ break;
+
+ case ir_binop_logic_and:
+ case ir_binop_logic_or:
+ if (op0->type->is_scalar()) {
+ this->type = op1->type;
+ } else if (op1->type->is_scalar()) {
+ this->type = op0->type;
+ }
+ break;
+
+ case ir_binop_dot:
+ this->type = glsl_type::float_type;
+ break;
+
+ default:
+ assert(!"not reached: missing automatic type setup for ir_expression");
+ this->type = glsl_type::float_type;
+ }
+}
+
+unsigned int
+ir_expression::get_num_operands(ir_expression_operation op)
+{
+ assert(op <= ir_last_opcode);
+
+ if (op <= ir_last_unop)
+ return 1;
+
+ if (op <= ir_last_binop)
+ return 2;
+
+ if (op == ir_quadop_vector)
+ return 4;
+
+ assert(false);
+ return 0;
+}
+
+static const char *const operator_strs[] = {
+ "~",
+ "!",
+ "neg",
+ "abs",
+ "sign",
+ "rcp",
+ "rsq",
+ "sqrt",
+ "exp",
+ "log",
+ "exp2",
+ "log2",
+ "f2i",
+ "i2f",
+ "f2b",
+ "b2f",
+ "i2b",
+ "b2i",
+ "u2f",
+ "any",
+ "trunc",
+ "ceil",
+ "floor",
+ "fract",
+ "round_even",
+ "sin",
+ "cos",
+ "sin_reduced",
+ "cos_reduced",
+ "dFdx",
+ "dFdy",
+ "noise",
+ "+",
+ "-",
+ "*",
+ "/",
+ "%",
+ "<",
+ ">",
+ "<=",
+ ">=",
+ "==",
+ "!=",
+ "all_equal",
+ "any_nequal",
+ "<<",
+ ">>",
+ "&",
+ "^",
+ "|",
+ "&&",
+ "^^",
+ "||",
+ "dot",
+ "min",
+ "max",
+ "pow",
+ "vector",
+};
+
+const char *ir_expression::operator_string(ir_expression_operation op)
+{
+ assert((unsigned int) op < Elements(operator_strs));
+ assert(Elements(operator_strs) == (ir_quadop_vector + 1));
+ return operator_strs[op];
+}
+
+const char *ir_expression::operator_string()
+{
+ return operator_string(this->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()
+{
+ this->ir_type = ir_type_constant;
+}
+
+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->ir_type = ir_type_constant;
+ this->type = type;
+ memcpy(& this->value, data, sizeof(this->value));
+}
+
+ir_constant::ir_constant(float f)
+{
+ this->ir_type = ir_type_constant;
+ this->type = glsl_type::float_type;
+ this->value.f[0] = f;
+ for (int i = 1; i < 16; i++) {
+ this->value.f[i] = 0;
+ }
+}
+
+ir_constant::ir_constant(unsigned int u)
+{
+ this->ir_type = ir_type_constant;
+ this->type = glsl_type::uint_type;
+ this->value.u[0] = u;
+ for (int i = 1; i < 16; i++) {
+ this->value.u[i] = 0;
+ }
+}
+
+ir_constant::ir_constant(int i)
+{
+ this->ir_type = ir_type_constant;
+ this->type = glsl_type::int_type;
+ this->value.i[0] = i;
+ for (int i = 1; i < 16; i++) {
+ this->value.i[i] = 0;
+ }
+}
+
+ir_constant::ir_constant(bool b)
+{
+ this->ir_type = ir_type_constant;
+ this->type = glsl_type::bool_type;
+ this->value.b[0] = b;
+ for (int i = 1; i < 16; i++) {
+ this->value.b[i] = false;
+ }
+}
+
+ir_constant::ir_constant(const ir_constant *c, unsigned i)
+{
+ this->ir_type = ir_type_constant;
+ 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->ir_type = ir_type_constant;
+ this->type = type;
+
+ assert(type->is_scalar() || type->is_vector() || type->is_matrix()
+ || type->is_record() || type->is_array());
+
+ if (type->is_array()) {
+ this->array_elements = talloc_array(this, ir_constant *, type->length);
+ unsigned i = 0;
+ foreach_list(node, value_list) {
+ ir_constant *value = (ir_constant *) node;
+ assert(value->as_constant() != NULL);
+
+ this->array_elements[i++] = value;
+ }
+ return;
+ }
+
+ /* 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;
+ }
+
+ for (unsigned i = 0; i < 16; i++) {
+ this->value.u[i] = 0;
+ }
+
+ ir_constant *value = (ir_constant *) (value_list->head);
+
+ /* Constructors with exactly one scalar argument are special for vectors
+ * and matrices. For vectors, the scalar value is replicated to fill all
+ * the components. For matrices, the scalar fills the components of the
+ * diagonal while the rest is filled with 0.
+ */
+ if (value->type->is_scalar() && value->next->is_tail_sentinel()) {
+ if (type->is_matrix()) {
+ /* Matrix - fill diagonal (rest is already set to 0) */
+ assert(type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned i = 0; i < type->matrix_columns; i++)
+ this->value.f[i * type->vector_elements + i] = value->value.f[0];
+ } else {
+ /* Vector or scalar - fill all components */
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ for (unsigned i = 0; i < type->components(); i++)
+ this->value.u[i] = value->value.u[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ for (unsigned i = 0; i < type->components(); i++)
+ this->value.f[i] = value->value.f[0];
+ break;
+ case GLSL_TYPE_BOOL:
+ for (unsigned i = 0; i < type->components(); i++)
+ this->value.b[i] = value->value.b[0];
+ break;
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ }
+ return;
+ }
+
+ if (type->is_matrix() && value->type->is_matrix()) {
+ assert(value->next->is_tail_sentinel());
+
+ /* From section 5.4.2 of the GLSL 1.20 spec:
+ * "If a matrix is constructed from a matrix, then each component
+ * (column i, row j) in the result that has a corresponding component
+ * (column i, row j) in the argument will be initialized from there."
+ */
+ unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
+ unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
+ for (unsigned i = 0; i < cols; i++) {
+ for (unsigned j = 0; j < rows; j++) {
+ const unsigned src = i * value->type->vector_elements + j;
+ const unsigned dst = i * type->vector_elements + j;
+ this->value.f[dst] = value->value.f[src];
+ }
+ }
+
+ /* "All other components will be initialized to the identity matrix." */
+ for (unsigned i = cols; i < type->matrix_columns; i++)
+ this->value.f[i * type->vector_elements + i] = 1.0;
+
+ return;
+ }
+
+ /* 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_sentinel());
+
+ 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;
+ }
+}
+
+ir_constant *
+ir_constant::zero(void *mem_ctx, const glsl_type *type)
+{
+ assert(type->is_numeric() || type->is_boolean());
+
+ ir_constant *c = new(mem_ctx) ir_constant;
+ c->type = type;
+ memset(&c->value, 0, sizeof(c->value));
+
+ return c;
+}
+
+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_array_element(unsigned i) const
+{
+ assert(this->type->is_array());
+
+ /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "Behavior is undefined if a shader subscripts an array with an index
+ * less than 0 or greater than or equal to the size the array was
+ * declared with."
+ *
+ * Most out-of-bounds accesses are removed before things could get this far.
+ * There are cases where non-constant array index values can get constant
+ * folded.
+ */
+ if (int(i) < 0)
+ i = 0;
+ else if (i >= this->type->length)
+ i = this->type->length - 1;
+
+ return array_elements[i];
+}
+
+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_sentinel())
+ return NULL;
+ }
+
+ return (ir_constant *) node;
+}
+
+
+bool
+ir_constant::has_value(const ir_constant *c) const
+{
+ if (this->type != c->type)
+ return false;
+
+ if (this->type->is_array()) {
+ for (unsigned i = 0; i < this->type->length; i++) {
+ if (!this->array_elements[i]->has_value(c->array_elements[i]))
+ return false;
+ }
+ return true;
+ }
+
+ 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_sentinel()) {
+ assert(!b_node->is_tail_sentinel());
+
+ 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;
+}
+
+bool
+ir_constant::is_zero() const
+{
+ if (!this->type->is_scalar() && !this->type->is_vector())
+ return false;
+
+ for (unsigned c = 0; c < this->type->vector_elements; c++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ if (this->value.f[c] != 0.0)
+ return false;
+ break;
+ case GLSL_TYPE_INT:
+ if (this->value.i[c] != 0)
+ return false;
+ break;
+ case GLSL_TYPE_UINT:
+ if (this->value.u[c] != 0)
+ return false;
+ break;
+ case GLSL_TYPE_BOOL:
+ if (this->value.b[c] != false)
+ return false;
+ break;
+ default:
+ /* The only other base types are structures, arrays, and samplers.
+ * Samplers cannot be constants, and the others should have been
+ * filtered out above.
+ */
+ assert(!"Should not get here.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+ir_constant::is_one() const
+{
+ if (!this->type->is_scalar() && !this->type->is_vector())
+ return false;
+
+ for (unsigned c = 0; c < this->type->vector_elements; c++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ if (this->value.f[c] != 1.0)
+ return false;
+ break;
+ case GLSL_TYPE_INT:
+ if (this->value.i[c] != 1)
+ return false;
+ break;
+ case GLSL_TYPE_UINT:
+ if (this->value.u[c] != 1)
+ return false;
+ break;
+ case GLSL_TYPE_BOOL:
+ if (this->value.b[c] != true)
+ return false;
+ break;
+ default:
+ /* The only other base types are structures, arrays, and samplers.
+ * Samplers cannot be constants, and the others should have been
+ * filtered out above.
+ */
+ assert(!"Should not get here.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+ir_constant::is_negative_one() const
+{
+ if (!this->type->is_scalar() && !this->type->is_vector())
+ return false;
+
+ if (this->type->is_boolean())
+ return false;
+
+ for (unsigned c = 0; c < this->type->vector_elements; c++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ if (this->value.f[c] != -1.0)
+ return false;
+ break;
+ case GLSL_TYPE_INT:
+ if (this->value.i[c] != -1)
+ return false;
+ break;
+ case GLSL_TYPE_UINT:
+ if (int(this->value.u[c]) != -1)
+ return false;
+ break;
+ default:
+ /* The only other base types are structures, arrays, samplers, and
+ * booleans. Samplers cannot be constants, and the others should
+ * have been filtered out above.
+ */
+ assert(!"Should not get here.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ir_loop::ir_loop()
+{
+ this->ir_type = ir_type_loop;
+ this->cmp = ir_unop_neg;
+ this->from = NULL;
+ this->to = NULL;
+ this->increment = NULL;
+ this->counter = NULL;
+}
+
+
+ir_dereference_variable::ir_dereference_variable(ir_variable *var)
+{
+ this->ir_type = ir_type_dereference_variable;
+ 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->ir_type = ir_type_dereference_array;
+ 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->ir_type = ir_type_dereference_array;
+ 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->ir_type = ir_type_dereference_record;
+ this->record = value;
+ this->field = talloc_strdup(this, 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->ir_type = ir_type_dereference_record;
+ this->record = new(ctx) ir_dereference_variable(var);
+ this->field = talloc_strdup(this, field);
+ this->type = (this->record != NULL)
+ ? this->record->type->field_type(field) : glsl_type::error_type;
+}
+
+bool type_contains_sampler(const glsl_type *type)
+{
+ if (type->is_array()) {
+ return type_contains_sampler(type->fields.array);
+ } else if (type->is_record()) {
+ for (unsigned int i = 0; i < type->length; i++) {
+ if (type_contains_sampler(type->fields.structure[i].type))
+ return true;
+ }
+ return false;
+ } else {
+ return type->is_sampler();
+ }
+}
+
+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;
+
+ /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "Samplers cannot be treated as l-values; hence cannot be used
+ * as out or inout function parameters, nor can they be
+ * assigned into."
+ */
+ if (type_contains_sampler(this->type))
+ 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;
+ }
+}
+
+
+void
+ir_swizzle::init_mask(const unsigned *comp, unsigned count)
+{
+ assert((count >= 1) && (count <= 4));
+
+ memset(&this->mask, 0, sizeof(this->mask));
+ this->mask.num_components = count;
+
+ unsigned dup_mask = 0;
+ switch (count) {
+ case 4:
+ assert(comp[3] <= 3);
+ dup_mask |= (1U << comp[3])
+ & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
+ this->mask.w = comp[3];
+
+ case 3:
+ assert(comp[2] <= 3);
+ dup_mask |= (1U << comp[2])
+ & ((1U << comp[0]) | (1U << comp[1]));
+ this->mask.z = comp[2];
+
+ case 2:
+ assert(comp[1] <= 3);
+ dup_mask |= (1U << comp[1])
+ & ((1U << comp[0]));
+ this->mask.y = comp[1];
+
+ case 1:
+ assert(comp[0] <= 3);
+ this->mask.x = comp[0];
+ }
+
+ this->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, unsigned x, unsigned y, unsigned z,
+ unsigned w, unsigned count)
+ : val(val)
+{
+ const unsigned components[4] = { x, y, z, w };
+ this->ir_type = ir_type_swizzle;
+ this->init_mask(components, count);
+}
+
+ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
+ unsigned count)
+ : val(val)
+{
+ this->ir_type = ir_type_swizzle;
+ this->init_mask(comp, count);
+}
+
+ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
+{
+ this->ir_type = ir_type_swizzle;
+ 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,
+ ir_variable_mode mode)
+ : max_array_access(0), read_only(false), centroid(false), invariant(false),
+ mode(mode), interpolation(ir_var_smooth), array_lvalue(false)
+{
+ this->ir_type = ir_type_variable;
+ this->type = type;
+ this->name = talloc_strdup(this, name);
+ this->explicit_location = false;
+ this->location = -1;
+ this->warn_extension = NULL;
+ this->constant_value = NULL;
+ this->origin_upper_left = false;
+ this->pixel_center_integer = false;
+
+ if (type && type->base_type == GLSL_TYPE_SAMPLER)
+ this->read_only = true;
+}
+
+
+const char *
+ir_variable::interpolation_string() const
+{
+ 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), _function(NULL)
+{
+ this->ir_type = ir_type_function_signature;
+ this->is_builtin = false;
+}
+
+
+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)
+{
+ this->ir_type = ir_type_function;
+ this->name = talloc_strdup(this, name);
+}
+
+
+bool
+ir_function::has_user_signature()
+{
+ foreach_list(n, &this->signatures) {
+ ir_function_signature *const sig = (ir_function_signature *) n;
+ if (!sig->is_builtin)
+ return true;
+ }
+ return false;
+}
+
+
+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
+ir_call::set_callee(ir_function_signature *sig)
+{
+ assert((this->type == NULL) || (this->type == sig->return_type));
+
+ this->callee = sig;
+}
+
+void
+visit_exec_list(exec_list *list, ir_visitor *visitor)
+{
+ foreach_iter(exec_list_iterator, iter, *list) {
+ ((ir_instruction *)iter.get())->accept(visitor);
+ }
+}
+
+
+static void
+steal_memory(ir_instruction *ir, void *new_ctx)
+{
+ ir_variable *var = ir->as_variable();
+ ir_constant *constant = ir->as_constant();
+ if (var != NULL && var->constant_value != NULL)
+ steal_memory(var->constant_value, ir);
+
+ /* The components of aggregate constants are not visited by the normal
+ * visitor, so steal their values by hand.
+ */
+ if (constant != NULL) {
+ if (constant->type->is_record()) {
+ foreach_iter(exec_list_iterator, iter, constant->components) {
+ ir_constant *field = (ir_constant *)iter.get();
+ steal_memory(field, ir);
+ }
+ } else if (constant->type->is_array()) {
+ for (unsigned int i = 0; i < constant->type->length; i++) {
+ steal_memory(constant->array_elements[i], ir);
+ }
+ }
+ }
+
+ talloc_steal(new_ctx, ir);
+}
+
+
+void
+reparent_ir(exec_list *list, void *mem_ctx)
+{
+ foreach_list(node, list) {
+ visit_tree((ir_instruction *) node, steal_memory, mem_ctx);
+ }
+}
+
+
+static ir_rvalue *
+try_min_one(ir_rvalue *ir)
+{
+ ir_expression *expr = ir->as_expression();
+
+ if (!expr || expr->operation != ir_binop_min)
+ return NULL;
+
+ if (expr->operands[0]->is_one())
+ return expr->operands[1];
+
+ if (expr->operands[1]->is_one())
+ return expr->operands[0];
+
+ return NULL;
+}
+
+static ir_rvalue *
+try_max_zero(ir_rvalue *ir)
+{
+ ir_expression *expr = ir->as_expression();
+
+ if (!expr || expr->operation != ir_binop_max)
+ return NULL;
+
+ if (expr->operands[0]->is_zero())
+ return expr->operands[1];
+
+ if (expr->operands[1]->is_zero())
+ return expr->operands[0];
+
+ return NULL;
+}
+
+ir_rvalue *
+ir_rvalue::as_rvalue_to_saturate()
+{
+ ir_expression *expr = this->as_expression();
+
+ if (!expr)
+ return NULL;
+
+ ir_rvalue *max_zero = try_max_zero(expr);
+ if (max_zero) {
+ return try_min_one(max_zero);
+ } else {
+ ir_rvalue *min_one = try_min_one(expr);
+ if (min_one) {
+ return try_max_zero(min_one);
+ }
+ }
+
+ return NULL;
+}
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index fa246b5e5..b143827a7 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -1,1511 +1,1606 @@ -/* -*- 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 - -/** - * \defgroup IR Intermediate representation nodes - * - * @{ - */ - -/** - * Class tags - * - * Each concrete class derived from \c ir_instruction has a value in this - * enumerant. The value for the type is stored in \c ir_instruction::ir_type - * by the constructor. While using type tags is not very C++, it is extremely - * convenient. For example, during debugging you can simply inspect - * \c ir_instruction::ir_type to find out the actual type of the object. - * - * In addition, it is possible to use a switch-statement based on \c - * \c ir_instruction::ir_type to select different behavior for different object - * types. For functions that have only slight differences for several object - * types, this allows writing very straightforward, readable code. - */ -enum ir_node_type { - /** - * Zero is unused so that the IR validator can detect cases where - * \c ir_instruction::ir_type has not been initialized. - */ - ir_type_unset, - ir_type_variable, - ir_type_assignment, - ir_type_call, - ir_type_constant, - ir_type_dereference_array, - ir_type_dereference_record, - ir_type_dereference_variable, - ir_type_discard, - ir_type_expression, - ir_type_function, - ir_type_function_signature, - ir_type_if, - ir_type_loop, - ir_type_loop_jump, - ir_type_return, - ir_type_swizzle, - ir_type_texture, - ir_type_max /**< maximum ir_type enum number, for validation */ -}; - -/** - * Base class of all IR instructions - */ -class ir_instruction : public exec_node { -public: - enum ir_node_type ir_type; - const struct glsl_type *type; - - /** 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(void *mem_ctx, - 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_dereference_variable *as_dereference_variable() { return NULL; } - virtual class ir_expression * as_expression() { 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() - { - ir_type = ir_type_unset; - type = NULL; - } -}; - - -class ir_rvalue : public ir_instruction { -public: - virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0; - - virtual ir_constant *constant_expression_value() = 0; - - 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(); -}; - - -/** - * Variable storage classes - */ -enum ir_variable_mode { - ir_var_auto = 0, /**< Function local variables and globals. */ - ir_var_uniform, /**< Variable declared as a uniform. */ - ir_var_in, - ir_var_out, - ir_var_inout, - ir_var_temporary /**< Temporary variable generated during compilation. */ -}; - -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 *, ir_variable_mode); - - virtual ir_variable *clone(void *mem_ctx, 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 The string that would be used in a shader to specify \c - * mode will be returned. - * - * This function should only be used on a shader input or output variable. - */ - 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; - - /** - * Delcared name of the variable - */ - const char *name; - - /** - * Highest element accessed with a constant expression array index - * - * Not used for non-array variables. - */ - unsigned max_array_access; - - /** - * Is the variable read-only? - * - * This is set for variables declared as \c const, shader inputs, - * and uniforms. - */ - unsigned read_only:1; - unsigned centroid:1; - unsigned invariant:1; - - /** - * Storage class of the variable. - * - * \sa ir_variable_mode - */ - unsigned mode:3; - - /** - * Interpolation mode for shader inputs / outputs - * - * \sa ir_variable_interpolation - */ - 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; - - /** - * \name ARB_fragment_coord_conventions - * @{ - */ - unsigned origin_upper_left:1; - unsigned pixel_center_integer: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_function_signature *clone(void *mem_ctx, - 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; - - /** - * Get a handle to the function for which this is a signature - * - * There is no setter function, this function returns a \c const pointer, - * and \c ir_function_signature::_function is private for a reason. The - * only way to make a connection between a function and function signature - * is via \c ir_function::add_signature. This helps ensure that certain - * invariants (i.e., a function signature is in the list of signatures for - * its \c _function) are met. - * - * \sa ir_function::add_signature - */ - inline const class ir_function *function() const - { - return this->_function; - } - - /** - * 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; - - /** Whether or not this function signature is a built-in. */ - unsigned is_builtin: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_function *clone(void *mem_ctx, 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; - 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. - */ - ir_function_signature *matching_signature(const 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(const exec_list *actual_ps); - - /** - * Name of the function. - */ - const char *name; - - /** Whether or not this function has a signature that isn't a built-in. */ - bool has_user_signature(); - - /** - * 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 this->_function->name; -} -/*@}*/ - - -/** - * IR instruction representing high-level if-statements - */ -class ir_if : public ir_instruction { -public: - ir_if(ir_rvalue *condition) - : condition(condition) - { - ir_type = ir_type_if; - } - - virtual ir_if *clone(void *mem_ctx, 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(); - - virtual ir_loop *clone(void *mem_ctx, 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 - * - * Represents a loop like a FORTRAN \c do-loop. - * - * \note - * If \c from and \c to are the same value, the loop will execute once. - */ - /*@{*/ - ir_rvalue *from; /** Value of the loop counter on the first - * iteration of the loop. - */ - ir_rvalue *to; /** Value of the loop counter on the last - * iteration of the loop. - */ - ir_rvalue *increment; - ir_variable *counter; - - /** - * Comparison operation in the loop terminator. - * - * If any of the loop control fields are non-\c NULL, this field must be - * one of \c ir_binop_less, \c ir_binop_greater, \c ir_binop_lequal, - * \c ir_binop_gequal, \c ir_binop_equal, or \c ir_binop_nequal. - */ - int cmp; - /*@}*/ -}; - - -class ir_assignment : public ir_instruction { -public: - ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); - - /** - * Construct an assignment with an explicit write mask - * - * \note - * Since a write mask is supplied, the LHS must already be a bare - * \c ir_dereference. The cannot be any swizzles in the LHS. - */ - ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition, - unsigned write_mask); - - virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; - - virtual ir_constant *constant_expression_value(); - - virtual void accept(ir_visitor *v) - { - v->visit(this); - } - - virtual ir_visitor_status accept(ir_hierarchical_visitor *); - - virtual ir_assignment * as_assignment() - { - return this; - } - - /** - * Get a whole variable written by an assignment - * - * If the LHS of the assignment writes a whole variable, the variable is - * returned. Otherwise \c NULL is returned. Examples of whole-variable - * assignment are: - * - * - Assigning to a scalar - * - Assigning to all components of a vector - * - Whole array (or matrix) assignment - * - Whole structure assignment - */ - ir_variable *whole_variable_written(); - - /** - * Set the LHS of an assignment - */ - void set_lhs(ir_rvalue *lhs); - - /** - * Left-hand side of the assignment. - * - * This should be treated as read only. If you need to set the LHS of an - * assignment, use \c ir_assignment::set_lhs. - */ - ir_dereference *lhs; - - /** - * Value being assigned - */ - ir_rvalue *rhs; - - /** - * Optional condition for the assignment. - */ - ir_rvalue *condition; - - - /** - * Component mask written - * - * For non-vector types in the LHS, this field will be zero. For vector - * types, a bit will be set for each component that is written. Note that - * for \c vec2 and \c vec3 types only the lower bits will ever be set. - * - * A partially-set write mask means that each enabled channel gets - * the value from a consecutive channel of the rhs. For example, - * to write just .xyw of gl_FrontColor with color: - * - * (assign (constant bool (1)) (xyw) - * (var_ref gl_FragColor) - * (swiz xyw (var_ref color))) - */ - unsigned write_mask:4; -}; - -/* 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, /**< Log base e on gentype */ - ir_unop_log, /**< Natural log on gentype */ - 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. */ - ir_unop_any, - - /** - * \name Unary floating-point rounding operations. - */ - /*@{*/ - ir_unop_trunc, - ir_unop_ceil, - ir_unop_floor, - ir_unop_fract, - /*@}*/ - - /** - * \name Trigonometric operations. - */ - /*@{*/ - ir_unop_sin, - ir_unop_cos, - /*@}*/ - - /** - * \name Partial derivatives. - */ - /*@{*/ - ir_unop_dFdx, - ir_unop_dFdy, - /*@}*/ - - ir_unop_noise, - - ir_binop_add, - ir_binop_sub, - ir_binop_mul, - ir_binop_div, - - /** - * Takes one of two combinations of arguments: - * - * - mod(vecN, vecN) - * - mod(vecN, float) - * - * Does not take integer types. - */ - ir_binop_mod, - - /** - * \name Binary comparison operators which return a boolean vector. - * The type of both operands must be equal. - */ - /*@{*/ - ir_binop_less, - ir_binop_greater, - ir_binop_lequal, - ir_binop_gequal, - ir_binop_equal, - ir_binop_nequal, - /** - * Returns single boolean for whether all components of operands[0] - * equal the components of operands[1]. - */ - ir_binop_all_equal, - /** - * Returns single boolean for whether any component of operands[0] - * is not equal to the corresponding component of operands[1]. - */ - ir_binop_any_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_cross, - 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_expression *as_expression() - { - return this; - } - - virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; - - /** - * Attempt to constant-fold the expression - * - * If the expression cannot be constant folded, this method will return - * \c NULL. - */ - virtual ir_constant *constant_expression_value(); - - /** - * Determine the number of operands used by an expression - */ - static unsigned int get_num_operands(ir_expression_operation); - - /** - * Determine the number of operands used by an expression - */ - unsigned int get_num_operands() const - { - return get_num_operands(operation); - } - - /** - * Return a string representing this expression's operator. - */ - const char *operator_string(); - - /** - * Return a string representing this expression's operator. - */ - static const char *operator_string(ir_expression_operation); - - - /** - * 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(ir_function_signature *callee, exec_list *actual_parameters) - : callee(callee) - { - ir_type = ir_type_call; - assert(callee->return_type != NULL); - type = callee->return_type; - actual_parameters->move_nodes_to(& this->actual_parameters); - } - - virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; - - virtual ir_constant *constant_expression_value(); - - 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(); - } - - /** - * Get the function signature bound to this function call - */ - ir_function_signature *get_callee() - { - return callee; - } - - /** - * Set the function call target - */ - void set_callee(ir_function_signature *sig); - - /** - * Generates an inline version of the function before @ir, - * returning the return value of the function. - */ - ir_rvalue *generate_inline(ir_instruction *ir); - - /* List of ir_rvalue of paramaters passed in this call. */ - exec_list actual_parameters; - -private: - ir_call() - : callee(NULL) - { - this->ir_type = ir_type_call; - } - - ir_function_signature *callee; -}; - - -/** - * \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() - { - ir_type = ir_type_unset; - } -}; - -class ir_return : public ir_jump { -public: - ir_return() - : value(NULL) - { - this->ir_type = ir_type_return; - } - - ir_return(ir_rvalue *value) - : value(value) - { - this->ir_type = ir_type_return; - } - - virtual ir_return *clone(void *mem_ctx, 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->ir_type = ir_type_loop_jump; - this->mode = mode; - this->loop = loop; - } - - virtual ir_loop_jump *clone(void *mem_ctx, 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; -}; - -/** - * IR instruction representing discard statements. - */ -class ir_discard : public ir_jump { -public: - ir_discard() - { - this->ir_type = ir_type_discard; - this->condition = NULL; - } - - ir_discard(ir_rvalue *cond) - { - this->ir_type = ir_type_discard; - this->condition = cond; - } - - virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const; - - virtual void accept(ir_visitor *v) - { - v->visit(this); - } - - virtual ir_visitor_status accept(ir_hierarchical_visitor *); - - ir_rvalue *condition; -}; -/*@}*/ - - -/** - * 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) - { - this->ir_type = ir_type_texture; - } - - virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; - - virtual ir_constant *constant_expression_value(); - - 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, const unsigned *components, unsigned count); - - ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); - - virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; - - virtual ir_constant *constant_expression_value(); - - 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; - -private: - /** - * Initialize the mask component of a swizzle - * - * This is used by the \c ir_swizzle constructors. - */ - void init_mask(const unsigned *components, unsigned count); -}; - - -class ir_dereference : public ir_rvalue { -public: - virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; - - 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_dereference_variable *clone(void *mem_ctx, - struct hash_table *) const; - - virtual ir_constant *constant_expression_value(); - - virtual ir_dereference_variable *as_dereference_variable() - { - return this; - } - - /** - * 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_dereference_array *clone(void *mem_ctx, - struct hash_table *) const; - - virtual ir_constant *constant_expression_value(); - - 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_dereference_record *clone(void *mem_ctx, - struct hash_table *) const; - - virtual ir_constant *constant_expression_value(); - - /** - * 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); - - /** - * Return a new ir_constant of the specified type containing all zeros. - */ - static ir_constant *zero(void *mem_ctx, const glsl_type *type); - - virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; - - virtual ir_constant *constant_expression_value(); - - 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_array_element(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; - - /* Array elements */ - ir_constant **array_elements; - - /* Structure fields */ - exec_list components; - -private: - /** - * Parameterless constructor only used by the clone method - */ - ir_constant(void); -}; - -/*@}*/ - -/** - * Apply a visitor to each IR node in a list - */ -void -visit_exec_list(exec_list *list, ir_visitor *visitor); - -/** - * Validate invariants on each IR node in a list - */ -void validate_ir_tree(exec_list *instructions); - -/** - * Make a clone of each IR instruction in a list - * - * \param in List of IR instructions that are to be cloned - * \param out List to hold the cloned instructions - */ -void -clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in); - -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); - -extern void -_mesa_glsl_release_functions(void); - -extern void -reparent_ir(exec_list *list, void *mem_ctx); - -struct glsl_symbol_table; - -extern void -import_prototypes(const exec_list *source, exec_list *dest, - struct glsl_symbol_table *symbols, void *mem_ctx); - -extern bool -ir_has_call(ir_instruction *ir); - -extern void -do_set_program_inouts(exec_list *instructions, struct gl_program *prog); - -#endif /* IR_H */ +/* -*- 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 "glsl_types.h"
+#include "list.h"
+#include "ir_visitor.h"
+#include "ir_hierarchical_visitor.h"
+
+/**
+ * \defgroup IR Intermediate representation nodes
+ *
+ * @{
+ */
+
+/**
+ * Class tags
+ *
+ * Each concrete class derived from \c ir_instruction has a value in this
+ * enumerant. The value for the type is stored in \c ir_instruction::ir_type
+ * by the constructor. While using type tags is not very C++, it is extremely
+ * convenient. For example, during debugging you can simply inspect
+ * \c ir_instruction::ir_type to find out the actual type of the object.
+ *
+ * In addition, it is possible to use a switch-statement based on \c
+ * \c ir_instruction::ir_type to select different behavior for different object
+ * types. For functions that have only slight differences for several object
+ * types, this allows writing very straightforward, readable code.
+ */
+enum ir_node_type {
+ /**
+ * Zero is unused so that the IR validator can detect cases where
+ * \c ir_instruction::ir_type has not been initialized.
+ */
+ ir_type_unset,
+ ir_type_variable,
+ ir_type_assignment,
+ ir_type_call,
+ ir_type_constant,
+ ir_type_dereference_array,
+ ir_type_dereference_record,
+ ir_type_dereference_variable,
+ ir_type_discard,
+ ir_type_expression,
+ ir_type_function,
+ ir_type_function_signature,
+ ir_type_if,
+ ir_type_loop,
+ ir_type_loop_jump,
+ ir_type_return,
+ ir_type_swizzle,
+ ir_type_texture,
+ ir_type_max /**< maximum ir_type enum number, for validation */
+};
+
+/**
+ * Base class of all IR instructions
+ */
+class ir_instruction : public exec_node {
+public:
+ enum ir_node_type ir_type;
+ const struct glsl_type *type;
+
+ /** 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(void *mem_ctx,
+ 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_dereference_variable *as_dereference_variable() { return NULL; }
+ virtual class ir_expression * as_expression() { 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; }
+ virtual class ir_discard * as_discard() { return NULL; }
+ /*@}*/
+
+protected:
+ ir_instruction()
+ {
+ ir_type = ir_type_unset;
+ type = NULL;
+ }
+};
+
+
+class ir_rvalue : public ir_instruction {
+public:
+ virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0;
+
+ virtual ir_constant *constant_expression_value() = 0;
+
+ virtual ir_rvalue * as_rvalue()
+ {
+ return this;
+ }
+
+ ir_rvalue *as_rvalue_to_saturate();
+
+ 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;
+ }
+
+ /**
+ * Determine if an r-value has the value zero
+ *
+ * The base implementation of this function always returns \c false. The
+ * \c ir_constant class over-rides this function to return \c true \b only
+ * for vector and scalar types that have all elements set to the value
+ * zero (or \c false for booleans).
+ *
+ * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one
+ */
+ virtual bool is_zero() const;
+
+ /**
+ * Determine if an r-value has the value one
+ *
+ * The base implementation of this function always returns \c false. The
+ * \c ir_constant class over-rides this function to return \c true \b only
+ * for vector and scalar types that have all elements set to the value
+ * one (or \c true for booleans).
+ *
+ * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one
+ */
+ virtual bool is_one() const;
+
+ /**
+ * Determine if an r-value has the value negative one
+ *
+ * The base implementation of this function always returns \c false. The
+ * \c ir_constant class over-rides this function to return \c true \b only
+ * for vector and scalar types that have all elements set to the value
+ * negative one. For boolean times, the result is always \c false.
+ *
+ * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one
+ */
+ virtual bool is_negative_one() const;
+
+protected:
+ ir_rvalue();
+};
+
+
+/**
+ * Variable storage classes
+ */
+enum ir_variable_mode {
+ ir_var_auto = 0, /**< Function local variables and globals. */
+ ir_var_uniform, /**< Variable declared as a uniform. */
+ ir_var_in,
+ ir_var_out,
+ ir_var_inout,
+ ir_var_temporary /**< Temporary variable generated during compilation. */
+};
+
+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 *, ir_variable_mode);
+
+ virtual ir_variable *clone(void *mem_ctx, 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 The string that would be used in a shader to specify \c
+ * mode will be returned.
+ *
+ * This function should only be used on a shader input or output variable.
+ */
+ 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;
+
+ /**
+ * Delcared name of the variable
+ */
+ const char *name;
+
+ /**
+ * Highest element accessed with a constant expression array index
+ *
+ * Not used for non-array variables.
+ */
+ unsigned max_array_access;
+
+ /**
+ * Is the variable read-only?
+ *
+ * This is set for variables declared as \c const, shader inputs,
+ * and uniforms.
+ */
+ unsigned read_only:1;
+ unsigned centroid:1;
+ unsigned invariant:1;
+
+ /**
+ * Storage class of the variable.
+ *
+ * \sa ir_variable_mode
+ */
+ unsigned mode:3;
+
+ /**
+ * Interpolation mode for shader inputs / outputs
+ *
+ * \sa ir_variable_interpolation
+ */
+ 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;
+
+ /**
+ * \name ARB_fragment_coord_conventions
+ * @{
+ */
+ unsigned origin_upper_left:1;
+ unsigned pixel_center_integer:1;
+ /*@}*/
+
+ /**
+ * Was the location explicitly set in the shader?
+ *
+ * If the location is explicitly set in the shader, it \b cannot be changed
+ * by the linker or by the API (e.g., calls to \c glBindAttribLocation have
+ * no effect).
+ */
+ unsigned explicit_location: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_function_signature *clone(void *mem_ctx,
+ struct hash_table *ht) const;
+ ir_function_signature *clone_prototype(void *mem_ctx,
+ 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;
+
+ /**
+ * Get a handle to the function for which this is a signature
+ *
+ * There is no setter function, this function returns a \c const pointer,
+ * and \c ir_function_signature::_function is private for a reason. The
+ * only way to make a connection between a function and function signature
+ * is via \c ir_function::add_signature. This helps ensure that certain
+ * invariants (i.e., a function signature is in the list of signatures for
+ * its \c _function) are met.
+ *
+ * \sa ir_function::add_signature
+ */
+ inline const class ir_function *function() const
+ {
+ return this->_function;
+ }
+
+ /**
+ * 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;
+
+ /** Whether or not this function signature is a built-in. */
+ unsigned is_builtin: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_function *clone(void *mem_ctx, 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;
+ 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.
+ */
+ ir_function_signature *matching_signature(const 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(const exec_list *actual_ps);
+
+ /**
+ * Name of the function.
+ */
+ const char *name;
+
+ /** Whether or not this function has a signature that isn't a built-in. */
+ bool has_user_signature();
+
+ /**
+ * 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 this->_function->name;
+}
+/*@}*/
+
+
+/**
+ * IR instruction representing high-level if-statements
+ */
+class ir_if : public ir_instruction {
+public:
+ ir_if(ir_rvalue *condition)
+ : condition(condition)
+ {
+ ir_type = ir_type_if;
+ }
+
+ virtual ir_if *clone(void *mem_ctx, 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();
+
+ virtual ir_loop *clone(void *mem_ctx, 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
+ *
+ * Represents a loop like a FORTRAN \c do-loop.
+ *
+ * \note
+ * If \c from and \c to are the same value, the loop will execute once.
+ */
+ /*@{*/
+ ir_rvalue *from; /** Value of the loop counter on the first
+ * iteration of the loop.
+ */
+ ir_rvalue *to; /** Value of the loop counter on the last
+ * iteration of the loop.
+ */
+ ir_rvalue *increment;
+ ir_variable *counter;
+
+ /**
+ * Comparison operation in the loop terminator.
+ *
+ * If any of the loop control fields are non-\c NULL, this field must be
+ * one of \c ir_binop_less, \c ir_binop_greater, \c ir_binop_lequal,
+ * \c ir_binop_gequal, \c ir_binop_equal, or \c ir_binop_nequal.
+ */
+ int cmp;
+ /*@}*/
+};
+
+
+class ir_assignment : public ir_instruction {
+public:
+ ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
+
+ /**
+ * Construct an assignment with an explicit write mask
+ *
+ * \note
+ * Since a write mask is supplied, the LHS must already be a bare
+ * \c ir_dereference. The cannot be any swizzles in the LHS.
+ */
+ ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition,
+ unsigned write_mask);
+
+ virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ virtual ir_assignment * as_assignment()
+ {
+ return this;
+ }
+
+ /**
+ * Get a whole variable written by an assignment
+ *
+ * If the LHS of the assignment writes a whole variable, the variable is
+ * returned. Otherwise \c NULL is returned. Examples of whole-variable
+ * assignment are:
+ *
+ * - Assigning to a scalar
+ * - Assigning to all components of a vector
+ * - Whole array (or matrix) assignment
+ * - Whole structure assignment
+ */
+ ir_variable *whole_variable_written();
+
+ /**
+ * Set the LHS of an assignment
+ */
+ void set_lhs(ir_rvalue *lhs);
+
+ /**
+ * Left-hand side of the assignment.
+ *
+ * This should be treated as read only. If you need to set the LHS of an
+ * assignment, use \c ir_assignment::set_lhs.
+ */
+ ir_dereference *lhs;
+
+ /**
+ * Value being assigned
+ */
+ ir_rvalue *rhs;
+
+ /**
+ * Optional condition for the assignment.
+ */
+ ir_rvalue *condition;
+
+
+ /**
+ * Component mask written
+ *
+ * For non-vector types in the LHS, this field will be zero. For vector
+ * types, a bit will be set for each component that is written. Note that
+ * for \c vec2 and \c vec3 types only the lower bits will ever be set.
+ *
+ * A partially-set write mask means that each enabled channel gets
+ * the value from a consecutive channel of the rhs. For example,
+ * to write just .xyw of gl_FrontColor with color:
+ *
+ * (assign (constant bool (1)) (xyw)
+ * (var_ref gl_FragColor)
+ * (swiz xyw (var_ref color)))
+ */
+ unsigned write_mask:4;
+};
+
+/* 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, /**< Log base e on gentype */
+ ir_unop_log, /**< Natural log on gentype */
+ 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. */
+ ir_unop_any,
+
+ /**
+ * \name Unary floating-point rounding operations.
+ */
+ /*@{*/
+ ir_unop_trunc,
+ ir_unop_ceil,
+ ir_unop_floor,
+ ir_unop_fract,
+ ir_unop_round_even,
+ /*@}*/
+
+ /**
+ * \name Trigonometric operations.
+ */
+ /*@{*/
+ ir_unop_sin,
+ ir_unop_cos,
+ ir_unop_sin_reduced, /**< Reduced range sin. [-pi, pi] */
+ ir_unop_cos_reduced, /**< Reduced range cos. [-pi, pi] */
+ /*@}*/
+
+ /**
+ * \name Partial derivatives.
+ */
+ /*@{*/
+ ir_unop_dFdx,
+ ir_unop_dFdy,
+ /*@}*/
+
+ ir_unop_noise,
+
+ /**
+ * A sentinel marking the last of the unary operations.
+ */
+ ir_last_unop = ir_unop_noise,
+
+ ir_binop_add,
+ ir_binop_sub,
+ ir_binop_mul,
+ ir_binop_div,
+
+ /**
+ * Takes one of two combinations of arguments:
+ *
+ * - mod(vecN, vecN)
+ * - mod(vecN, float)
+ *
+ * Does not take integer types.
+ */
+ ir_binop_mod,
+
+ /**
+ * \name Binary comparison operators which return a boolean vector.
+ * The type of both operands must be equal.
+ */
+ /*@{*/
+ ir_binop_less,
+ ir_binop_greater,
+ ir_binop_lequal,
+ ir_binop_gequal,
+ ir_binop_equal,
+ ir_binop_nequal,
+ /**
+ * Returns single boolean for whether all components of operands[0]
+ * equal the components of operands[1].
+ */
+ ir_binop_all_equal,
+ /**
+ * Returns single boolean for whether any component of operands[0]
+ * is not equal to the corresponding component of operands[1].
+ */
+ ir_binop_any_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,
+
+ /**
+ * A sentinel marking the last of the binary operations.
+ */
+ ir_last_binop = ir_binop_pow,
+
+ ir_quadop_vector,
+
+ /**
+ * A sentinel marking the last of all operations.
+ */
+ ir_last_opcode = ir_last_binop
+};
+
+class ir_expression : public ir_rvalue {
+public:
+ /**
+ * Constructor for unary operation expressions
+ */
+ ir_expression(int op, const struct glsl_type *type, ir_rvalue *);
+ ir_expression(int op, ir_rvalue *);
+
+ /**
+ * Constructor for binary operation expressions
+ */
+ ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *, ir_rvalue *);
+ ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
+
+ /**
+ * Constructor for quad operator expressions
+ */
+ ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *, ir_rvalue *, ir_rvalue *, ir_rvalue *);
+
+ virtual ir_expression *as_expression()
+ {
+ return this;
+ }
+
+ virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
+
+ /**
+ * Attempt to constant-fold the expression
+ *
+ * If the expression cannot be constant folded, this method will return
+ * \c NULL.
+ */
+ virtual ir_constant *constant_expression_value();
+
+ /**
+ * Determine the number of operands used by an expression
+ */
+ static unsigned int get_num_operands(ir_expression_operation);
+
+ /**
+ * Determine the number of operands used by an expression
+ */
+ unsigned int get_num_operands() const
+ {
+ return (this->operation == ir_quadop_vector)
+ ? this->type->vector_elements : get_num_operands(operation);
+ }
+
+ /**
+ * Return a string representing this expression's operator.
+ */
+ const char *operator_string();
+
+ /**
+ * Return a string representing this expression's operator.
+ */
+ static const char *operator_string(ir_expression_operation);
+
+
+ /**
+ * 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[4];
+};
+
+
+/**
+ * IR instruction representing a function call
+ */
+class ir_call : public ir_rvalue {
+public:
+ ir_call(ir_function_signature *callee, exec_list *actual_parameters)
+ : callee(callee)
+ {
+ ir_type = ir_type_call;
+ assert(callee->return_type != NULL);
+ type = callee->return_type;
+ actual_parameters->move_nodes_to(& this->actual_parameters);
+ }
+
+ virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ 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();
+ }
+
+ /**
+ * Get the function signature bound to this function call
+ */
+ ir_function_signature *get_callee()
+ {
+ return callee;
+ }
+
+ /**
+ * Set the function call target
+ */
+ void set_callee(ir_function_signature *sig);
+
+ /**
+ * Generates an inline version of the function before @ir,
+ * returning the return value of the function.
+ */
+ ir_rvalue *generate_inline(ir_instruction *ir);
+
+ /* List of ir_rvalue of paramaters passed in this call. */
+ exec_list actual_parameters;
+
+private:
+ ir_call()
+ : callee(NULL)
+ {
+ this->ir_type = ir_type_call;
+ }
+
+ ir_function_signature *callee;
+};
+
+
+/**
+ * \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()
+ {
+ ir_type = ir_type_unset;
+ }
+};
+
+class ir_return : public ir_jump {
+public:
+ ir_return()
+ : value(NULL)
+ {
+ this->ir_type = ir_type_return;
+ }
+
+ ir_return(ir_rvalue *value)
+ : value(value)
+ {
+ this->ir_type = ir_type_return;
+ }
+
+ virtual ir_return *clone(void *mem_ctx, 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->ir_type = ir_type_loop_jump;
+ this->mode = mode;
+ this->loop = loop;
+ }
+
+ virtual ir_loop_jump *clone(void *mem_ctx, 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;
+};
+
+/**
+ * IR instruction representing discard statements.
+ */
+class ir_discard : public ir_jump {
+public:
+ ir_discard()
+ {
+ this->ir_type = ir_type_discard;
+ this->condition = NULL;
+ }
+
+ ir_discard(ir_rvalue *cond)
+ {
+ this->ir_type = ir_type_discard;
+ this->condition = cond;
+ }
+
+ virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const;
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+ virtual ir_discard *as_discard()
+ {
+ return this;
+ }
+
+ ir_rvalue *condition;
+};
+/*@}*/
+
+
+/**
+ * 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)
+ {
+ this->ir_type = ir_type_texture;
+ }
+
+ virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ 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, const unsigned *components, unsigned count);
+
+ ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
+
+ virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ 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;
+
+private:
+ /**
+ * Initialize the mask component of a swizzle
+ *
+ * This is used by the \c ir_swizzle constructors.
+ */
+ void init_mask(const unsigned *components, unsigned count);
+};
+
+
+class ir_dereference : public ir_rvalue {
+public:
+ virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0;
+
+ 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_dereference_variable *clone(void *mem_ctx,
+ struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ virtual ir_dereference_variable *as_dereference_variable()
+ {
+ return this;
+ }
+
+ /**
+ * 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_dereference_array *clone(void *mem_ctx,
+ struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ 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_dereference_record *clone(void *mem_ctx,
+ struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ /**
+ * 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);
+
+ /**
+ * Return a new ir_constant of the specified type containing all zeros.
+ */
+ static ir_constant *zero(void *mem_ctx, const glsl_type *type);
+
+ virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
+
+ 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_array_element(unsigned i) const;
+
+ ir_constant *get_record_field(const char *name);
+
+ /**
+ * Determine whether a constant has the same value as another constant
+ *
+ * \sa ir_constant::is_zero, ir_constant::is_one,
+ * ir_constant::is_negative_one
+ */
+ bool has_value(const ir_constant *) const;
+
+ virtual bool is_zero() const;
+ virtual bool is_one() const;
+ virtual bool is_negative_one() 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;
+
+ /* Array elements */
+ ir_constant **array_elements;
+
+ /* Structure fields */
+ exec_list components;
+
+private:
+ /**
+ * Parameterless constructor only used by the clone method
+ */
+ ir_constant(void);
+};
+
+/*@}*/
+
+/**
+ * Apply a visitor to each IR node in a list
+ */
+void
+visit_exec_list(exec_list *list, ir_visitor *visitor);
+
+/**
+ * Validate invariants on each IR node in a list
+ */
+void validate_ir_tree(exec_list *instructions);
+
+/**
+ * Make a clone of each IR instruction in a list
+ *
+ * \param in List of IR instructions that are to be cloned
+ * \param out List to hold the cloned instructions
+ */
+void
+clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in);
+
+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);
+
+extern void
+_mesa_glsl_release_functions(void);
+
+extern void
+reparent_ir(exec_list *list, void *mem_ctx);
+
+struct glsl_symbol_table;
+
+extern void
+import_prototypes(const exec_list *source, exec_list *dest,
+ struct glsl_symbol_table *symbols, void *mem_ctx);
+
+extern bool
+ir_has_call(ir_instruction *ir);
+
+extern void
+do_set_program_inouts(exec_list *instructions, struct gl_program *prog);
+
+#endif /* IR_H */
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index 18543a35a..a3c35f042 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -1,405 +1,420 @@ -/* - * 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" -extern "C" { -#include "program/hash_table.h" -} - -/** - * Duplicate an IR variable - * - * \note - * This will probably be made \c virtual and moved to the base class - * eventually. - */ -ir_variable * -ir_variable::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name, - (ir_variable_mode) this->mode); - - var->max_array_access = this->max_array_access; - var->read_only = this->read_only; - var->centroid = this->centroid; - var->invariant = this->invariant; - var->interpolation = this->interpolation; - var->array_lvalue = this->array_lvalue; - var->location = this->location; - var->warn_extension = this->warn_extension; - var->origin_upper_left = this->origin_upper_left; - var->pixel_center_integer = this->pixel_center_integer; - - if (this->constant_value) - var->constant_value = this->constant_value->clone(mem_ctx, ht); - - if (ht) { - hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this)); - } - - return var; -} - -ir_swizzle * -ir_swizzle::clone(void *mem_ctx, struct hash_table *ht) const -{ - return new(mem_ctx) ir_swizzle(this->val->clone(mem_ctx, ht), this->mask); -} - -ir_return * -ir_return::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_rvalue *new_value = NULL; - - if (this->value) - new_value = this->value->clone(mem_ctx, ht); - - return new(mem_ctx) ir_return(new_value); -} - -ir_discard * -ir_discard::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_rvalue *new_condition = NULL; - - if (this->condition != NULL) - new_condition = this->condition->clone(mem_ctx, ht); - - return new(mem_ctx) ir_discard(new_condition); -} - -ir_loop_jump * -ir_loop_jump::clone(void *mem_ctx, struct hash_table *ht) const -{ - (void)ht; - - return new(mem_ctx) ir_loop_jump(this->mode); -} - -ir_if * -ir_if::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, 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(mem_ctx, 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(mem_ctx, ht)); - } - - return new_if; -} - -ir_loop * -ir_loop::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_loop *new_loop = new(mem_ctx) ir_loop(); - - if (this->from) - new_loop->from = this->from->clone(mem_ctx, ht); - if (this->to) - new_loop->to = this->to->clone(mem_ctx, ht); - if (this->increment) - new_loop->increment = this->increment->clone(mem_ctx, 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(mem_ctx, ht)); - } - - new_loop->cmp = this->cmp; - return new_loop; -} - -ir_call * -ir_call::clone(void *mem_ctx, struct hash_table *ht) const -{ - if (this->type == glsl_type::error_type) - return ir_call::get_error_instruction(mem_ctx); - - 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(mem_ctx, ht)); - } - - return new(mem_ctx) ir_call(this->callee, &new_parameters); -} - -ir_expression * -ir_expression::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_rvalue *op[2] = {NULL, NULL}; - unsigned int i; - - for (i = 0; i < get_num_operands(); i++) { - op[i] = this->operands[i]->clone(mem_ctx, ht); - } - - return new(mem_ctx) ir_expression(this->operation, this->type, op[0], op[1]); -} - -ir_dereference_variable * -ir_dereference_variable::clone(void *mem_ctx, struct hash_table *ht) const -{ - 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(mem_ctx) ir_dereference_variable(new_var); -} - -ir_dereference_array * -ir_dereference_array::clone(void *mem_ctx, struct hash_table *ht) const -{ - return new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, ht), - this->array_index->clone(mem_ctx, - ht)); -} - -ir_dereference_record * -ir_dereference_record::clone(void *mem_ctx, struct hash_table *ht) const -{ - return new(mem_ctx) ir_dereference_record(this->record->clone(mem_ctx, ht), - this->field); -} - -ir_texture * -ir_texture::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_texture *new_tex = new(mem_ctx) ir_texture(this->op); - new_tex->type = this->type; - - new_tex->sampler = this->sampler->clone(mem_ctx, ht); - new_tex->coordinate = this->coordinate->clone(mem_ctx, ht); - if (this->projector) - new_tex->projector = this->projector->clone(mem_ctx, ht); - if (this->shadow_comparitor) { - new_tex->shadow_comparitor = this->shadow_comparitor->clone(mem_ctx, 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 = this->lod_info.bias->clone(mem_ctx, ht); - break; - case ir_txl: - case ir_txf: - new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht); - break; - case ir_txd: - new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht); - new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht); - break; - } - - return new_tex; -} - -ir_assignment * -ir_assignment::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_rvalue *new_condition = NULL; - - if (this->condition) - new_condition = this->condition->clone(mem_ctx, ht); - - return new(mem_ctx) ir_assignment(this->lhs->clone(mem_ctx, ht), - this->rhs->clone(mem_ctx, ht), - new_condition, - this->write_mask); -} - -ir_function * -ir_function::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_function *copy = new(mem_ctx) ir_function(this->name); - - foreach_list_const(node, &this->signatures) { - const ir_function_signature *const sig = - (const ir_function_signature *const) node; - - ir_function_signature *sig_copy = sig->clone(mem_ctx, ht); - copy->add_signature(sig_copy); - - if (ht != NULL) - hash_table_insert(ht, sig_copy, - (void *)const_cast<ir_function_signature *>(sig)); - } - - return copy; -} - -ir_function_signature * -ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const -{ - ir_function_signature *copy = - new(mem_ctx) ir_function_signature(this->return_type); - - copy->is_defined = this->is_defined; - copy->is_builtin = this->is_builtin; - - /* Clone the parameter list. - */ - foreach_list_const(node, &this->parameters) { - const ir_variable *const param = (const ir_variable *) node; - - assert(const_cast<ir_variable *>(param)->as_variable() != NULL); - - ir_variable *const param_copy = param->clone(mem_ctx, ht); - copy->parameters.push_tail(param_copy); - } - - /* Clone the instruction list. - */ - foreach_list_const(node, &this->body) { - const ir_instruction *const inst = (const ir_instruction *) node; - - ir_instruction *const inst_copy = inst->clone(mem_ctx, ht); - copy->body.push_tail(inst_copy); - } - - return copy; -} - -ir_constant * -ir_constant::clone(void *mem_ctx, struct hash_table *ht) const -{ - (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(mem_ctx) ir_constant(this->type, &this->value); - - case GLSL_TYPE_STRUCT: { - ir_constant *c = new(mem_ctx) ir_constant; - - c->type = this->type; - for (exec_node *node = this->components.head - ; !node->is_tail_sentinel() - ; node = node->next) { - ir_constant *const orig = (ir_constant *) node; - - c->components.push_tail(orig->clone(mem_ctx, NULL)); - } - - return c; - } - - case GLSL_TYPE_ARRAY: { - ir_constant *c = new(mem_ctx) ir_constant; - - c->type = this->type; - c->array_elements = talloc_array(c, ir_constant *, this->type->length); - for (unsigned i = 0; i < this->type->length; i++) { - c->array_elements[i] = this->array_elements[i]->clone(mem_ctx, NULL); - } - return c; - } - - default: - assert(!"Should not get here."); - return NULL; - } -} - - -class fixup_ir_call_visitor : public ir_hierarchical_visitor { -public: - fixup_ir_call_visitor(struct hash_table *ht) - { - this->ht = ht; - } - - virtual ir_visitor_status visit_enter(ir_call *ir) - { - /* Try to find the function signature referenced by the ir_call in the - * table. If it is found, replace it with the value from the table. - */ - ir_function_signature *sig = - (ir_function_signature *) hash_table_find(this->ht, ir->get_callee()); - if (sig != NULL) - ir->set_callee(sig); - - /* Since this may be used before function call parameters are flattened, - * the children also need to be processed. - */ - return visit_continue; - } - -private: - struct hash_table *ht; -}; - - -static void -fixup_function_calls(struct hash_table *ht, exec_list *instructions) -{ - fixup_ir_call_visitor v(ht); - v.run(instructions); -} - - -void -clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in) -{ - struct hash_table *ht = - hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); - - foreach_list_const(node, in) { - const ir_instruction *const original = (ir_instruction *) node; - ir_instruction *copy = original->clone(mem_ctx, ht); - - out->push_tail(copy); - } - - /* Make a pass over the cloned tree to fix up ir_call nodes to point to the - * cloned ir_function_signature nodes. This cannot be done automatically - * during cloning because the ir_call might be a forward reference (i.e., - * the function signature that it references may not have been cloned yet). - */ - fixup_function_calls(ht, out); - - hash_table_dtor(ht); -} +/*
+ * 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/compiler.h"
+#include "ir.h"
+#include "glsl_types.h"
+extern "C" {
+#include "program/hash_table.h"
+}
+
+/**
+ * Duplicate an IR variable
+ *
+ * \note
+ * This will probably be made \c virtual and moved to the base class
+ * eventually.
+ */
+ir_variable *
+ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name,
+ (ir_variable_mode) this->mode);
+
+ var->max_array_access = this->max_array_access;
+ var->read_only = this->read_only;
+ var->centroid = this->centroid;
+ var->invariant = this->invariant;
+ var->interpolation = this->interpolation;
+ var->array_lvalue = this->array_lvalue;
+ var->location = this->location;
+ var->warn_extension = this->warn_extension;
+ var->origin_upper_left = this->origin_upper_left;
+ var->pixel_center_integer = this->pixel_center_integer;
+ var->explicit_location = this->explicit_location;
+ if (this->explicit_location)
+ var->location = this->location;
+
+ if (this->constant_value)
+ var->constant_value = this->constant_value->clone(mem_ctx, ht);
+
+ if (ht) {
+ hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this));
+ }
+
+ return var;
+}
+
+ir_swizzle *
+ir_swizzle::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ return new(mem_ctx) ir_swizzle(this->val->clone(mem_ctx, ht), this->mask);
+}
+
+ir_return *
+ir_return::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_rvalue *new_value = NULL;
+
+ if (this->value)
+ new_value = this->value->clone(mem_ctx, ht);
+
+ return new(mem_ctx) ir_return(new_value);
+}
+
+ir_discard *
+ir_discard::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_rvalue *new_condition = NULL;
+
+ if (this->condition != NULL)
+ new_condition = this->condition->clone(mem_ctx, ht);
+
+ return new(mem_ctx) ir_discard(new_condition);
+}
+
+ir_loop_jump *
+ir_loop_jump::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ (void)ht;
+
+ return new(mem_ctx) ir_loop_jump(this->mode);
+}
+
+ir_if *
+ir_if::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, 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(mem_ctx, 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(mem_ctx, ht));
+ }
+
+ return new_if;
+}
+
+ir_loop *
+ir_loop::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_loop *new_loop = new(mem_ctx) ir_loop();
+
+ if (this->from)
+ new_loop->from = this->from->clone(mem_ctx, ht);
+ if (this->to)
+ new_loop->to = this->to->clone(mem_ctx, ht);
+ if (this->increment)
+ new_loop->increment = this->increment->clone(mem_ctx, 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(mem_ctx, ht));
+ }
+
+ new_loop->cmp = this->cmp;
+ return new_loop;
+}
+
+ir_call *
+ir_call::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ if (this->type == glsl_type::error_type)
+ return ir_call::get_error_instruction(mem_ctx);
+
+ 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(mem_ctx, ht));
+ }
+
+ return new(mem_ctx) ir_call(this->callee, &new_parameters);
+}
+
+ir_expression *
+ir_expression::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_rvalue *op[Elements(this->operands)] = { NULL, };
+ unsigned int i;
+
+ for (i = 0; i < get_num_operands(); i++) {
+ op[i] = this->operands[i]->clone(mem_ctx, ht);
+ }
+
+ return new(mem_ctx) ir_expression(this->operation, this->type,
+ op[0], op[1], op[2], op[3]);
+}
+
+ir_dereference_variable *
+ir_dereference_variable::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ 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(mem_ctx) ir_dereference_variable(new_var);
+}
+
+ir_dereference_array *
+ir_dereference_array::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ return new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, ht),
+ this->array_index->clone(mem_ctx,
+ ht));
+}
+
+ir_dereference_record *
+ir_dereference_record::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ return new(mem_ctx) ir_dereference_record(this->record->clone(mem_ctx, ht),
+ this->field);
+}
+
+ir_texture *
+ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_texture *new_tex = new(mem_ctx) ir_texture(this->op);
+ new_tex->type = this->type;
+
+ new_tex->sampler = this->sampler->clone(mem_ctx, ht);
+ new_tex->coordinate = this->coordinate->clone(mem_ctx, ht);
+ if (this->projector)
+ new_tex->projector = this->projector->clone(mem_ctx, ht);
+ if (this->shadow_comparitor) {
+ new_tex->shadow_comparitor = this->shadow_comparitor->clone(mem_ctx, 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 = this->lod_info.bias->clone(mem_ctx, ht);
+ break;
+ case ir_txl:
+ case ir_txf:
+ new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht);
+ break;
+ case ir_txd:
+ new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht);
+ new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht);
+ break;
+ }
+
+ return new_tex;
+}
+
+ir_assignment *
+ir_assignment::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_rvalue *new_condition = NULL;
+
+ if (this->condition)
+ new_condition = this->condition->clone(mem_ctx, ht);
+
+ return new(mem_ctx) ir_assignment(this->lhs->clone(mem_ctx, ht),
+ this->rhs->clone(mem_ctx, ht),
+ new_condition,
+ this->write_mask);
+}
+
+ir_function *
+ir_function::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_function *copy = new(mem_ctx) ir_function(this->name);
+
+ foreach_list_const(node, &this->signatures) {
+ const ir_function_signature *const sig =
+ (const ir_function_signature *const) node;
+
+ ir_function_signature *sig_copy = sig->clone(mem_ctx, ht);
+ copy->add_signature(sig_copy);
+
+ if (ht != NULL)
+ hash_table_insert(ht, sig_copy,
+ (void *)const_cast<ir_function_signature *>(sig));
+ }
+
+ return copy;
+}
+
+ir_function_signature *
+ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_function_signature *copy = this->clone_prototype(mem_ctx, ht);
+
+ copy->is_defined = this->is_defined;
+
+ /* Clone the instruction list.
+ */
+ foreach_list_const(node, &this->body) {
+ const ir_instruction *const inst = (const ir_instruction *) node;
+
+ ir_instruction *const inst_copy = inst->clone(mem_ctx, ht);
+ copy->body.push_tail(inst_copy);
+ }
+
+ return copy;
+}
+
+ir_function_signature *
+ir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) const
+{
+ ir_function_signature *copy =
+ new(mem_ctx) ir_function_signature(this->return_type);
+
+ copy->is_defined = false;
+ copy->is_builtin = this->is_builtin;
+
+ /* Clone the parameter list, but NOT the body.
+ */
+ foreach_list_const(node, &this->parameters) {
+ const ir_variable *const param = (const ir_variable *) node;
+
+ assert(const_cast<ir_variable *>(param)->as_variable() != NULL);
+
+ ir_variable *const param_copy = param->clone(mem_ctx, ht);
+ copy->parameters.push_tail(param_copy);
+ }
+
+ return copy;
+}
+
+ir_constant *
+ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
+{
+ (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(mem_ctx) ir_constant(this->type, &this->value);
+
+ case GLSL_TYPE_STRUCT: {
+ ir_constant *c = new(mem_ctx) ir_constant;
+
+ c->type = this->type;
+ for (exec_node *node = this->components.head
+ ; !node->is_tail_sentinel()
+ ; node = node->next) {
+ ir_constant *const orig = (ir_constant *) node;
+
+ c->components.push_tail(orig->clone(mem_ctx, NULL));
+ }
+
+ return c;
+ }
+
+ case GLSL_TYPE_ARRAY: {
+ ir_constant *c = new(mem_ctx) ir_constant;
+
+ c->type = this->type;
+ c->array_elements = talloc_array(c, ir_constant *, this->type->length);
+ for (unsigned i = 0; i < this->type->length; i++) {
+ c->array_elements[i] = this->array_elements[i]->clone(mem_ctx, NULL);
+ }
+ return c;
+ }
+
+ default:
+ assert(!"Should not get here.");
+ return NULL;
+ }
+}
+
+
+class fixup_ir_call_visitor : public ir_hierarchical_visitor {
+public:
+ fixup_ir_call_visitor(struct hash_table *ht)
+ {
+ this->ht = ht;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_call *ir)
+ {
+ /* Try to find the function signature referenced by the ir_call in the
+ * table. If it is found, replace it with the value from the table.
+ */
+ ir_function_signature *sig =
+ (ir_function_signature *) hash_table_find(this->ht, ir->get_callee());
+ if (sig != NULL)
+ ir->set_callee(sig);
+
+ /* Since this may be used before function call parameters are flattened,
+ * the children also need to be processed.
+ */
+ return visit_continue;
+ }
+
+private:
+ struct hash_table *ht;
+};
+
+
+static void
+fixup_function_calls(struct hash_table *ht, exec_list *instructions)
+{
+ fixup_ir_call_visitor v(ht);
+ v.run(instructions);
+}
+
+
+void
+clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in)
+{
+ struct hash_table *ht =
+ hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare);
+
+ foreach_list_const(node, in) {
+ const ir_instruction *const original = (ir_instruction *) node;
+ ir_instruction *copy = original->clone(mem_ctx, ht);
+
+ out->push_tail(copy);
+ }
+
+ /* Make a pass over the cloned tree to fix up ir_call nodes to point to the
+ * cloned ir_function_signature nodes. This cannot be done automatically
+ * during cloning because the ir_call might be a forward reference (i.e.,
+ * the function signature that it references may not have been cloned yet).
+ */
+ fixup_function_calls(ht, out);
+
+ hash_table_dtor(ht);
+}
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index 61a708f6e..53162f127 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -1,1194 +1,1354 @@ -/* - * 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 "main/core.h" /* for MAX2, MIN2, CLAMP */ -#include "ir.h" -#include "ir_visitor.h" -#include "glsl_types.h" - -static float -dot(ir_constant *op0, ir_constant *op1) -{ - assert(op0->type->is_float() && op1->type->is_float()); - - float result = 0; - for (unsigned c = 0; c < op0->type->components(); c++) - result += op0->value.f[c] * op1->value.f[c]; - - return result; -} - -ir_constant * -ir_expression::constant_expression_value() -{ - ir_constant *op[2] = { NULL, NULL }; - ir_constant_data data; - - memset(&data, 0, sizeof(data)); - - for (unsigned operand = 0; operand < this->get_num_operands(); operand++) { - op[operand] = this->operands[operand]->constant_expression_value(); - if (!op[operand]) - return NULL; - } - - if (op[1] != NULL) - assert(op[0]->type->base_type == op[1]->type->base_type); - - bool op0_scalar = op[0]->type->is_scalar(); - bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar(); - - /* When iterating over a vector or matrix's components, we want to increase - * the loop counter. However, for scalars, we want to stay at 0. - */ - unsigned c0_inc = op0_scalar ? 0 : 1; - unsigned c1_inc = op1_scalar ? 0 : 1; - unsigned components; - if (op1_scalar || !op[1]) { - components = op[0]->type->components(); - } else { - components = op[1]->type->components(); - } - - void *ctx = talloc_parent(this); - - /* Handle array operations here, rather than below. */ - if (op[0]->type->is_array()) { - assert(op[1] != NULL && op[1]->type->is_array()); - switch (this->operation) { - case ir_binop_all_equal: - return new(ctx) ir_constant(op[0]->has_value(op[1])); - case ir_binop_any_nequal: - return new(ctx) ir_constant(!op[0]->has_value(op[1])); - default: - break; - } - return NULL; - } - - switch (this->operation) { - case ir_unop_logic_not: - assert(op[0]->type->base_type == GLSL_TYPE_BOOL); - for (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[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_INT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = op[0]->value.i[c]; - } - break; - case ir_unop_u2f: - assert(op[0]->type->base_type == GLSL_TYPE_UINT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = op[0]->value.u[c]; - } - break; - case ir_unop_b2f: - assert(op[0]->type->base_type == GLSL_TYPE_BOOL); - for (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[0]->type->components(); c++) { - data.b[c] = bool(op[0]->value.u[c]); - } - break; - - case ir_unop_any: - assert(op[0]->type->is_boolean()); - data.b[0] = false; - for (unsigned c = 0; c < op[0]->type->components(); c++) { - if (op[0]->value.b[c]) - data.b[0] = true; - } - break; - - case ir_unop_trunc: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = truncf(op[0]->value.f[c]); - } - break; - - case ir_unop_ceil: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = ceilf(op[0]->value.f[c]); - } - break; - - case ir_unop_floor: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = floorf(op[0]->value.f[c]); - } - break; - - case ir_unop_fract: - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (this->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = 0; - break; - case GLSL_TYPE_INT: - data.i[c] = 0; - break; - case GLSL_TYPE_FLOAT: - data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]); - break; - default: - assert(0); - } - } - break; - - case ir_unop_sin: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = sinf(op[0]->value.f[c]); - } - break; - - case ir_unop_cos: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = cosf(op[0]->value.f[c]); - } - break; - - case ir_unop_neg: - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (this->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: - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (this->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_sign: - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (this->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = op[0]->value.i[c] > 0; - break; - case GLSL_TYPE_INT: - data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0); - break; - case GLSL_TYPE_FLOAT: - data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0)); - break; - default: - assert(0); - } - } - break; - - case ir_unop_rcp: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (this->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 (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = expf(op[0]->value.f[c]); - } - break; - - case ir_unop_exp2: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = exp2f(op[0]->value.f[c]); - } - break; - - case ir_unop_log: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = logf(op[0]->value.f[c]); - } - break; - - case ir_unop_log2: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = log2f(op[0]->value.f[c]); - } - break; - - case ir_unop_dFdx: - case ir_unop_dFdy: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = 0.0; - } - break; - - case ir_binop_pow: - assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]); - } - break; - - case ir_binop_dot: - data.f[0] = dot(op[0], op[1]); - break; - - case ir_binop_min: - assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); - for (unsigned c = 0, c0 = 0, c1 = 0; - c < components; - c0 += c0_inc, c1 += c1_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]); - break; - case GLSL_TYPE_INT: - data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]); - break; - case GLSL_TYPE_FLOAT: - data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]); - break; - default: - assert(0); - } - } - - break; - case ir_binop_max: - assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); - for (unsigned c = 0, c0 = 0, c1 = 0; - c < components; - c0 += c0_inc, c1 += c1_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]); - break; - case GLSL_TYPE_INT: - data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]); - break; - case GLSL_TYPE_FLOAT: - data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]); - break; - default: - assert(0); - } - } - break; - - case ir_binop_cross: - assert(op[0]->type == glsl_type::vec3_type); - assert(op[1]->type == glsl_type::vec3_type); - data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] - - op[1]->value.f[1] * op[0]->value.f[2]); - data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] - - op[1]->value.f[2] * op[0]->value.f[0]); - data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] - - op[1]->value.f[0] * op[0]->value.f[1]); - break; - - case ir_binop_add: - assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); - for (unsigned c = 0, c0 = 0, c1 = 0; - c < components; - c0 += c0_inc, c1 += c1_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1]; - break; - case GLSL_TYPE_INT: - data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1]; - break; - case GLSL_TYPE_FLOAT: - data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1]; - break; - default: - assert(0); - } - } - - break; - case ir_binop_sub: - assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); - for (unsigned c = 0, c0 = 0, c1 = 0; - c < components; - c0 += c0_inc, c1 += c1_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1]; - break; - case GLSL_TYPE_INT: - data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1]; - break; - case GLSL_TYPE_FLOAT: - data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]; - break; - default: - assert(0); - } - } - - break; - case ir_binop_mul: - /* Check for equal types, or unequal types involving scalars */ - if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix()) - || op0_scalar || op1_scalar) { - for (unsigned c = 0, c0 = 0, c1 = 0; - c < components; - c0 += c0_inc, c1 += c1_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1]; - break; - case GLSL_TYPE_INT: - data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1]; - break; - case GLSL_TYPE_FLOAT: - data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1]; - break; - default: - assert(0); - } - } - } else { - assert(op[0]->type->is_matrix() || op[1]->type->is_matrix()); - - /* Multiply an N-by-M matrix with an M-by-P matrix. Since either - * matrix can be a GLSL vector, either N or P can be 1. - * - * For vec*mat, the vector is treated as a row vector. This - * means the vector is a 1-row x M-column matrix. - * - * For mat*vec, the vector is treated as a column vector. Since - * matrix_columns is 1 for vectors, this just works. - */ - const unsigned n = op[0]->type->is_vector() - ? 1 : op[0]->type->vector_elements; - const unsigned m = op[1]->type->vector_elements; - const unsigned p = op[1]->type->matrix_columns; - for (unsigned j = 0; j < p; j++) { - for (unsigned i = 0; i < n; i++) { - for (unsigned k = 0; k < m; k++) { - data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j]; - } - } - } - } - - break; - case ir_binop_div: - assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); - for (unsigned c = 0, c0 = 0, c1 = 0; - c < components; - c0 += c0_inc, c1 += c1_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1]; - break; - case GLSL_TYPE_INT: - data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1]; - break; - case GLSL_TYPE_FLOAT: - data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1]; - break; - default: - assert(0); - } - } - - break; - case ir_binop_mod: - assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); - for (unsigned c = 0, c0 = 0, c1 = 0; - c < components; - c0 += c0_inc, c1 += c1_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1]; - break; - case GLSL_TYPE_INT: - data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1]; - break; - case GLSL_TYPE_FLOAT: - /* We don't use fmod because it rounds toward zero; GLSL specifies - * the use of floor. - */ - data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1] - * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]); - break; - default: - assert(0); - } - } - - break; - - case ir_binop_logic_and: - assert(op[0]->type->base_type == GLSL_TYPE_BOOL); - for (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[0]->type->components(); c++) - data.b[c] = op[0]->value.b[c] || op[1]->value.b[c]; - break; - - case ir_binop_less: - switch (op[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 (op[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 (op[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 (op[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: - assert(op[0]->type == op[1]->type); - for (unsigned c = 0; c < components; c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] == op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] == op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; - break; - default: - assert(0); - } - } - break; - case ir_binop_nequal: - assert(op[0]->type != op[1]->type); - for (unsigned c = 0; c < components; c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] != op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] != op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] != op[1]->value.f[c]; - break; - default: - assert(0); - } - } - break; - case ir_binop_all_equal: - data.b[0] = op[0]->has_value(op[1]); - break; - case ir_binop_any_nequal: - data.b[0] = !op[0]->has_value(op[1]); - break; - - default: - /* FINISHME: Should handle all expression types. */ - return NULL; - } - - return new(ctx) ir_constant(this->type, &data); -} - - -ir_constant * -ir_texture::constant_expression_value() -{ - /* texture lookups aren't constant expressions */ - return NULL; -} - - -ir_constant * -ir_swizzle::constant_expression_value() -{ - ir_constant *v = this->val->constant_expression_value(); - - if (v != NULL) { - ir_constant_data data = { { 0 } }; - - const unsigned swiz_idx[4] = { - this->mask.x, this->mask.y, this->mask.z, this->mask.w - }; - - for (unsigned i = 0; i < this->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(this); - return new(ctx) ir_constant(this->type, &data); - } - return NULL; -} - - -ir_constant * -ir_dereference_variable::constant_expression_value() -{ - /* This may occur during compile and var->type is glsl_type::error_type */ - if (!var) - return NULL; - - /* The constant_value of a uniform variable is its initializer, - * not the lifetime constant value of the uniform. - */ - if (var->mode == ir_var_uniform) - return NULL; - - if (!var->constant_value) - return NULL; - - return var->constant_value->clone(talloc_parent(var), NULL); -} - - -ir_constant * -ir_dereference_array::constant_expression_value() -{ - ir_constant *array = this->array->constant_expression_value(); - ir_constant *idx = this->array_index->constant_expression_value(); - - if ((array != NULL) && (idx != NULL)) { - void *ctx = talloc_parent(this); - 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; - } - - return new(ctx) ir_constant(column_type, &data); - } else if (array->type->is_vector()) { - const unsigned component = idx->value.u[0]; - - return new(ctx) ir_constant(array, component); - } else { - const unsigned index = idx->value.u[0]; - return array->get_array_element(index)->clone(ctx, NULL); - } - } - return NULL; -} - - -ir_constant * -ir_dereference_record::constant_expression_value() -{ - ir_constant *v = this->record->constant_expression_value(); - - return (v != NULL) ? v->get_record_field(this->field) : NULL; -} - - -ir_constant * -ir_assignment::constant_expression_value() -{ - /* FINISHME: Handle CEs involving assignment (return RHS) */ - return NULL; -} - - -ir_constant * -ir_constant::constant_expression_value() -{ - return this; -} - - -ir_constant * -ir_call::constant_expression_value() -{ - if (this->type == glsl_type::error_type) - return NULL; - - /* From the GLSL 1.20 spec, page 23: - * "Function calls to user-defined functions (non-built-in functions) - * cannot be used to form constant expressions." - */ - if (!this->callee->is_builtin) - return NULL; - - unsigned num_parameters = 0; - - /* Check if all parameters are constant */ - ir_constant *op[3]; - foreach_list(n, &this->actual_parameters) { - ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(); - if (constant == NULL) - return NULL; - - op[num_parameters] = constant; - - assert(num_parameters < 3); - num_parameters++; - } - - /* Individual cases below can either: - * - Assign "expr" a new ir_expression to evaluate (for basic opcodes) - * - Fill "data" with appopriate constant data - * - Return an ir_constant directly. - */ - void *mem_ctx = talloc_parent(this); - ir_expression *expr = NULL; - - ir_constant_data data; - memset(&data, 0, sizeof(data)); - - const char *callee = this->callee_name(); - if (strcmp(callee, "abs") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL); - } else if (strcmp(callee, "all") == 0) { - assert(op[0]->type->is_boolean()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - if (!op[0]->value.b[c]) - return new(mem_ctx) ir_constant(false); - } - return new(mem_ctx) ir_constant(true); - } else if (strcmp(callee, "any") == 0) { - assert(op[0]->type->is_boolean()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - if (op[0]->value.b[c]) - return new(mem_ctx) ir_constant(true); - } - return new(mem_ctx) ir_constant(false); - } else if (strcmp(callee, "acos") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = acosf(op[0]->value.f[c]); - } else if (strcmp(callee, "asin") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = asinf(op[0]->value.f[c]); - } else if (strcmp(callee, "atan") == 0) { - assert(op[0]->type->is_float()); - if (num_parameters == 2) { - assert(op[1]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]); - } else { - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = atanf(op[0]->value.f[c]); - } - } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) { - return ir_constant::zero(mem_ctx, this->type); - } else if (strcmp(callee, "ceil") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL); - } else if (strcmp(callee, "clamp") == 0) { - assert(num_parameters == 3); - unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1; - unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; - for (unsigned c = 0, c1 = 0, c2 = 0; - c < op[0]->type->components(); - c1 += c1_inc, c2 += c2_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1], - op[2]->value.u[c2]); - break; - case GLSL_TYPE_INT: - data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1], - op[2]->value.i[c2]); - break; - case GLSL_TYPE_FLOAT: - data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1], - op[2]->value.f[c2]); - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "cos") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL); - } else if (strcmp(callee, "cosh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = coshf(op[0]->value.f[c]); - } else if (strcmp(callee, "cross") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]); - } else if (strcmp(callee, "degrees") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = 180.0/M_PI * op[0]->value.f[c]; - } else if (strcmp(callee, "distance") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - float length_squared = 0.0; - for (unsigned c = 0; c < op[0]->type->components(); c++) { - float t = op[0]->value.f[c] - op[1]->value.f[c]; - length_squared += t * t; - } - return new(mem_ctx) ir_constant(sqrtf(length_squared)); - } else if (strcmp(callee, "dot") == 0) { - return new(mem_ctx) ir_constant(dot(op[0], op[1])); - } else if (strcmp(callee, "equal") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] == op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] == op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; - break; - case GLSL_TYPE_BOOL: - data.b[c] = op[0]->value.b[c] == op[1]->value.b[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "exp") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL); - } else if (strcmp(callee, "exp2") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL); - } else if (strcmp(callee, "faceforward") == 0) { - if (dot(op[2], op[1]) < 0) - return op[0]; - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = -op[0]->value.f[c]; - } else if (strcmp(callee, "floor") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL); - } else if (strcmp(callee, "fract") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL); - } else if (strcmp(callee, "fwidth") == 0) { - return ir_constant::zero(mem_ctx, this->type); - } else if (strcmp(callee, "greaterThan") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] > op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] > op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] > op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "greaterThanEqual") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "inversesqrt") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL); - } else if (strcmp(callee, "length") == 0) { - return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0]))); - } else if (strcmp(callee, "lessThan") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] < op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] < op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] < op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "lessThanEqual") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "log") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL); - } else if (strcmp(callee, "log2") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL); - } else if (strcmp(callee, "matrixCompMult") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[0]->value.f[c] * op[1]->value.f[c]; - } else if (strcmp(callee, "max") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]); - } else if (strcmp(callee, "min") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]); - } else if (strcmp(callee, "mix") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - if (op[2]->type->is_float()) { - unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; - unsigned components = op[0]->type->components(); - for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) { - data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) + - op[1]->value.f[c] * op[2]->value.f[c2]; - } - } else { - assert(op[2]->type->is_boolean()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c]; - } - } else if (strcmp(callee, "mod") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]); - } else if (strcmp(callee, "normalize") == 0) { - assert(op[0]->type->is_float()); - float length = sqrtf(dot(op[0], op[0])); - - if (length == 0) - return ir_constant::zero(mem_ctx, this->type); - - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[0]->value.f[c] / length; - } else if (strcmp(callee, "not") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL); - } else if (strcmp(callee, "notEqual") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] != op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] != op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] != op[1]->value.f[c]; - break; - case GLSL_TYPE_BOOL: - data.b[c] = op[0]->value.b[c] != op[1]->value.b[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "outerProduct") == 0) { - assert(op[0]->type->is_vector() && op[1]->type->is_vector()); - const unsigned m = op[0]->type->vector_elements; - const unsigned n = op[1]->type->vector_elements; - for (unsigned j = 0; j < n; j++) { - for (unsigned i = 0; i < m; i++) { - data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j]; - } - } - } else if (strcmp(callee, "pow") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]); - } else if (strcmp(callee, "radians") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = M_PI/180.0 * op[0]->value.f[c]; - } else if (strcmp(callee, "reflect") == 0) { - assert(op[0]->type->is_float()); - float dot_NI = dot(op[1], op[0]); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c]; - } else if (strcmp(callee, "refract") == 0) { - const float eta = op[2]->value.f[0]; - const float dot_NI = dot(op[1], op[0]); - const float k = 1.0 - eta * eta * (1.0 - dot_NI * dot_NI); - if (k < 0.0) { - return ir_constant::zero(mem_ctx, this->type); - } else { - for (unsigned c = 0; c < type->components(); c++) { - data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k)) - * op[1]->value.f[c]; - } - } - } else if (strcmp(callee, "sign") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL); - } else if (strcmp(callee, "sin") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL); - } else if (strcmp(callee, "sinh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = sinhf(op[0]->value.f[c]); - } else if (strcmp(callee, "smoothstep") == 0) { - assert(num_parameters == 3); - assert(op[1]->type == op[0]->type); - unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1; - for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) { - const float edge0 = op[0]->value.f[e]; - const float edge1 = op[1]->value.f[e]; - if (edge0 == edge1) { - data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */ - } else { - const float numerator = op[2]->value.f[c] - edge0; - const float denominator = edge1 - edge0; - const float t = CLAMP(numerator/denominator, 0, 1); - data.f[c] = t * t * (3 - 2 * t); - } - } - } else if (strcmp(callee, "sqrt") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL); - } else if (strcmp(callee, "step") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - /* op[0] (edge) may be either a scalar or a vector */ - const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1; - for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++) - data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0 : 1.0; - } else if (strcmp(callee, "tan") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = tanf(op[0]->value.f[c]); - } else if (strcmp(callee, "tanh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = tanhf(op[0]->value.f[c]); - } else if (strcmp(callee, "transpose") == 0) { - assert(op[0]->type->is_matrix()); - const unsigned n = op[0]->type->vector_elements; - const unsigned m = op[0]->type->matrix_columns; - for (unsigned j = 0; j < m; j++) { - for (unsigned i = 0; i < n; i++) { - data.f[m*i+j] += op[0]->value.f[i+n*j]; - } - } - } else { - /* Unsupported builtin - some are not allowed in constant expressions. */ - return NULL; - } - - if (expr != NULL) - return expr->constant_expression_value(); - - return new(mem_ctx) ir_constant(this->type, &data); -} +/*
+ * 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 "main/core.h" /* for MAX2, MIN2, CLAMP */
+#include "ir.h"
+#include "ir_visitor.h"
+#include "glsl_types.h"
+
+static float
+dot(ir_constant *op0, ir_constant *op1)
+{
+ assert(op0->type->is_float() && op1->type->is_float());
+
+ float result = 0;
+ for (unsigned c = 0; c < op0->type->components(); c++)
+ result += op0->value.f[c] * op1->value.f[c];
+
+ return result;
+}
+
+ir_constant *
+ir_expression::constant_expression_value()
+{
+ if (this->type->is_error())
+ return NULL;
+
+ ir_constant *op[Elements(this->operands)] = { NULL, };
+ ir_constant_data data;
+
+ memset(&data, 0, sizeof(data));
+
+ for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
+ op[operand] = this->operands[operand]->constant_expression_value();
+ if (!op[operand])
+ return NULL;
+ }
+
+ if (op[1] != NULL)
+ assert(op[0]->type->base_type == op[1]->type->base_type);
+
+ bool op0_scalar = op[0]->type->is_scalar();
+ bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
+
+ /* When iterating over a vector or matrix's components, we want to increase
+ * the loop counter. However, for scalars, we want to stay at 0.
+ */
+ unsigned c0_inc = op0_scalar ? 0 : 1;
+ unsigned c1_inc = op1_scalar ? 0 : 1;
+ unsigned components;
+ if (op1_scalar || !op[1]) {
+ components = op[0]->type->components();
+ } else {
+ components = op[1]->type->components();
+ }
+
+ void *ctx = talloc_parent(this);
+
+ /* Handle array operations here, rather than below. */
+ if (op[0]->type->is_array()) {
+ assert(op[1] != NULL && op[1]->type->is_array());
+ switch (this->operation) {
+ case ir_binop_all_equal:
+ return new(ctx) ir_constant(op[0]->has_value(op[1]));
+ case ir_binop_any_nequal:
+ return new(ctx) ir_constant(!op[0]->has_value(op[1]));
+ default:
+ break;
+ }
+ return NULL;
+ }
+
+ switch (this->operation) {
+ case ir_unop_bit_not:
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_INT:
+ for (unsigned c = 0; c < components; c++)
+ data.i[c] = ~ op[0]->value.i[c];
+ break;
+ case GLSL_TYPE_UINT:
+ for (unsigned c = 0; c < components; c++)
+ data.u[c] = ~ op[0]->value.u[c];
+ break;
+ default:
+ assert(0);
+ }
+ break;
+
+ case ir_unop_logic_not:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.i[c] = (int) op[0]->value.f[c];
+ }
+ break;
+ case ir_unop_i2f:
+ assert(op[0]->type->base_type == GLSL_TYPE_INT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = (float) op[0]->value.i[c];
+ }
+ break;
+ case ir_unop_u2f:
+ assert(op[0]->type->base_type == GLSL_TYPE_UINT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = (float) op[0]->value.u[c];
+ }
+ break;
+ case ir_unop_b2f:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = op[0]->value.b[c] ? 1.0F : 0.0F;
+ }
+ break;
+ case ir_unop_f2b:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.b[c] = op[0]->value.f[c] != 0.0F ? true : false;
+ }
+ break;
+ case ir_unop_b2i:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.b[c] = op[0]->value.u[c] ? true : false;
+ }
+ break;
+
+ case ir_unop_any:
+ assert(op[0]->type->is_boolean());
+ data.b[0] = false;
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ if (op[0]->value.b[c])
+ data.b[0] = true;
+ }
+ break;
+
+ case ir_unop_trunc:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = truncf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_ceil:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = ceilf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_floor:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = floorf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_fract:
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = 0;
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = 0;
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_unop_sin:
+ case ir_unop_sin_reduced:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = sinf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_cos:
+ case ir_unop_cos_reduced:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = cosf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_neg:
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = -((int) 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:
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (this->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_sign:
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.i[c] > 0;
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_unop_rcp:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (this->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.0F / op[0]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_unop_rsq:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_sqrt:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = expf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_exp2:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = exp2f(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_log:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = logf(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_log2:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = log2f(op[0]->value.f[c]);
+ }
+ break;
+
+ case ir_unop_dFdx:
+ case ir_unop_dFdy:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = 0.0;
+ }
+ break;
+
+ case ir_binop_pow:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
+ }
+ break;
+
+ case ir_binop_dot:
+ data.f[0] = dot(op[0], op[1]);
+ break;
+
+ case ir_binop_min:
+ assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ break;
+ case ir_binop_max:
+ assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_binop_add:
+ assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ break;
+ case ir_binop_sub:
+ assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ break;
+ case ir_binop_mul:
+ /* Check for equal types, or unequal types involving scalars */
+ if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
+ || op0_scalar || op1_scalar) {
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ } else {
+ assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
+
+ /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
+ * matrix can be a GLSL vector, either N or P can be 1.
+ *
+ * For vec*mat, the vector is treated as a row vector. This
+ * means the vector is a 1-row x M-column matrix.
+ *
+ * For mat*vec, the vector is treated as a column vector. Since
+ * matrix_columns is 1 for vectors, this just works.
+ */
+ const unsigned n = op[0]->type->is_vector()
+ ? 1 : op[0]->type->vector_elements;
+ const unsigned m = op[1]->type->vector_elements;
+ const unsigned p = op[1]->type->matrix_columns;
+ for (unsigned j = 0; j < p; j++) {
+ for (unsigned i = 0; i < n; i++) {
+ for (unsigned k = 0; k < m; k++) {
+ data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
+ }
+ }
+ }
+ }
+
+ break;
+ case ir_binop_div:
+ assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ break;
+ case ir_binop_mod:
+ assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_FLOAT:
+ /* We don't use fmod because it rounds toward zero; GLSL specifies
+ * the use of floor.
+ */
+ data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
+ * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ break;
+
+ case ir_binop_logic_and:
+ assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+ for (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[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 (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
+ break;
+
+ case ir_binop_less:
+ assert(op[0]->type == op[1]->type);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[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:
+ assert(op[0]->type == op[1]->type);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+ case ir_binop_lequal:
+ assert(op[0]->type == op[1]->type);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[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:
+ assert(op[0]->type == op[1]->type);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[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:
+ assert(op[0]->type == op[1]->type);
+ for (unsigned c = 0; c < components; c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+ case ir_binop_nequal:
+ assert(op[0]->type != op[1]->type);
+ for (unsigned c = 0; c < components; c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+ case ir_binop_all_equal:
+ data.b[0] = op[0]->has_value(op[1]);
+ break;
+ case ir_binop_any_nequal:
+ data.b[0] = !op[0]->has_value(op[1]);
+ break;
+
+ case ir_binop_lshift:
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ if (op[0]->type->base_type == GLSL_TYPE_INT &&
+ op[1]->type->base_type == GLSL_TYPE_INT) {
+ data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
+
+ } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
+ op[1]->type->base_type == GLSL_TYPE_UINT) {
+ data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
+
+ } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
+ op[1]->type->base_type == GLSL_TYPE_INT) {
+ data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
+
+ } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
+ op[1]->type->base_type == GLSL_TYPE_UINT) {
+ data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
+ }
+ }
+ break;
+
+ case ir_binop_rshift:
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ if (op[0]->type->base_type == GLSL_TYPE_INT &&
+ op[1]->type->base_type == GLSL_TYPE_INT) {
+ data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
+
+ } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
+ op[1]->type->base_type == GLSL_TYPE_UINT) {
+ data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
+
+ } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
+ op[1]->type->base_type == GLSL_TYPE_INT) {
+ data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
+
+ } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
+ op[1]->type->base_type == GLSL_TYPE_UINT) {
+ data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
+ }
+ }
+ break;
+
+ case ir_binop_bit_and:
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_binop_bit_or:
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_binop_bit_xor:
+ for (unsigned c = 0, c0 = 0, c1 = 0;
+ c < components;
+ c0 += c0_inc, c1 += c1_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_INT:
+ data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
+ break;
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ case ir_quadop_vector:
+ for (unsigned c = 0; c < this->type->vector_elements; c++) {
+ switch (this->type->base_type) {
+ case GLSL_TYPE_INT:
+ data.i[c] = op[c]->value.i[0];
+ break;
+ case GLSL_TYPE_UINT:
+ data.u[c] = op[c]->value.u[0];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = op[c]->value.f[0];
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
+
+ default:
+ /* FINISHME: Should handle all expression types. */
+ return NULL;
+ }
+
+ return new(ctx) ir_constant(this->type, &data);
+}
+
+
+ir_constant *
+ir_texture::constant_expression_value()
+{
+ /* texture lookups aren't constant expressions */
+ return NULL;
+}
+
+
+ir_constant *
+ir_swizzle::constant_expression_value()
+{
+ ir_constant *v = this->val->constant_expression_value();
+
+ if (v != NULL) {
+ ir_constant_data data = { { 0 } };
+
+ const unsigned swiz_idx[4] = {
+ this->mask.x, this->mask.y, this->mask.z, this->mask.w
+ };
+
+ for (unsigned i = 0; i < this->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(this);
+ return new(ctx) ir_constant(this->type, &data);
+ }
+ return NULL;
+}
+
+
+ir_constant *
+ir_dereference_variable::constant_expression_value()
+{
+ /* This may occur during compile and var->type is glsl_type::error_type */
+ if (!var)
+ return NULL;
+
+ /* The constant_value of a uniform variable is its initializer,
+ * not the lifetime constant value of the uniform.
+ */
+ if (var->mode == ir_var_uniform)
+ return NULL;
+
+ if (!var->constant_value)
+ return NULL;
+
+ return var->constant_value->clone(talloc_parent(var), NULL);
+}
+
+
+ir_constant *
+ir_dereference_array::constant_expression_value()
+{
+ ir_constant *array = this->array->constant_expression_value();
+ ir_constant *idx = this->array_index->constant_expression_value();
+
+ if ((array != NULL) && (idx != NULL)) {
+ void *ctx = talloc_parent(this);
+ 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 = { { 0 } };
+
+ 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;
+ }
+
+ return new(ctx) ir_constant(column_type, &data);
+ } else if (array->type->is_vector()) {
+ const unsigned component = idx->value.u[0];
+
+ return new(ctx) ir_constant(array, component);
+ } else {
+ const unsigned index = idx->value.u[0];
+ return array->get_array_element(index)->clone(ctx, NULL);
+ }
+ }
+ return NULL;
+}
+
+
+ir_constant *
+ir_dereference_record::constant_expression_value()
+{
+ ir_constant *v = this->record->constant_expression_value();
+
+ return (v != NULL) ? v->get_record_field(this->field) : NULL;
+}
+
+
+ir_constant *
+ir_assignment::constant_expression_value()
+{
+ /* FINISHME: Handle CEs involving assignment (return RHS) */
+ return NULL;
+}
+
+
+ir_constant *
+ir_constant::constant_expression_value()
+{
+ return this;
+}
+
+
+ir_constant *
+ir_call::constant_expression_value()
+{
+ if (this->type == glsl_type::error_type)
+ return NULL;
+
+ /* From the GLSL 1.20 spec, page 23:
+ * "Function calls to user-defined functions (non-built-in functions)
+ * cannot be used to form constant expressions."
+ */
+ if (!this->callee->is_builtin)
+ return NULL;
+
+ unsigned num_parameters = 0;
+
+ /* Check if all parameters are constant */
+ ir_constant *op[3];
+ foreach_list(n, &this->actual_parameters) {
+ ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
+ if (constant == NULL)
+ return NULL;
+
+ op[num_parameters] = constant;
+
+ assert(num_parameters < 3);
+ num_parameters++;
+ }
+
+ /* Individual cases below can either:
+ * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
+ * - Fill "data" with appopriate constant data
+ * - Return an ir_constant directly.
+ */
+ void *mem_ctx = talloc_parent(this);
+ ir_expression *expr = NULL;
+
+ ir_constant_data data;
+ memset(&data, 0, sizeof(data));
+
+ const char *callee = this->callee_name();
+ if (strcmp(callee, "abs") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
+ } else if (strcmp(callee, "all") == 0) {
+ assert(op[0]->type->is_boolean());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ if (!op[0]->value.b[c])
+ return new(mem_ctx) ir_constant(false);
+ }
+ return new(mem_ctx) ir_constant(true);
+ } else if (strcmp(callee, "any") == 0) {
+ assert(op[0]->type->is_boolean());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ if (op[0]->value.b[c])
+ return new(mem_ctx) ir_constant(true);
+ }
+ return new(mem_ctx) ir_constant(false);
+ } else if (strcmp(callee, "acos") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = acosf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "acosh") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = acoshf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "asin") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = asinf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "asinh") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = asinhf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "atan") == 0) {
+ assert(op[0]->type->is_float());
+ if (num_parameters == 2) {
+ assert(op[1]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
+ } else {
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = atanf(op[0]->value.f[c]);
+ }
+ } else if (strcmp(callee, "atanh") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = atanhf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
+ return ir_constant::zero(mem_ctx, this->type);
+ } else if (strcmp(callee, "ceil") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
+ } else if (strcmp(callee, "clamp") == 0) {
+ assert(num_parameters == 3);
+ unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
+ unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
+ for (unsigned c = 0, c1 = 0, c2 = 0;
+ c < op[0]->type->components();
+ c1 += c1_inc, c2 += c2_inc, c++) {
+
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
+ op[2]->value.u[c2]);
+ break;
+ case GLSL_TYPE_INT:
+ data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
+ op[2]->value.i[c2]);
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
+ op[2]->value.f[c2]);
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+ }
+ } else if (strcmp(callee, "cos") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
+ } else if (strcmp(callee, "cosh") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = coshf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "cross") == 0) {
+ assert(op[0]->type == glsl_type::vec3_type);
+ assert(op[1]->type == glsl_type::vec3_type);
+ data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
+ op[1]->value.f[1] * op[0]->value.f[2]);
+ data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
+ op[1]->value.f[2] * op[0]->value.f[0]);
+ data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
+ op[1]->value.f[0] * op[0]->value.f[1]);
+ } else if (strcmp(callee, "degrees") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
+ } else if (strcmp(callee, "distance") == 0) {
+ assert(op[0]->type->is_float() && op[1]->type->is_float());
+ float length_squared = 0.0;
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ float t = op[0]->value.f[c] - op[1]->value.f[c];
+ length_squared += t * t;
+ }
+ return new(mem_ctx) ir_constant(sqrtf(length_squared));
+ } else if (strcmp(callee, "dot") == 0) {
+ return new(mem_ctx) ir_constant(dot(op[0], op[1]));
+ } else if (strcmp(callee, "equal") == 0) {
+ assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
+ break;
+ case GLSL_TYPE_BOOL:
+ data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+ }
+ } else if (strcmp(callee, "exp") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
+ } else if (strcmp(callee, "exp2") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
+ } else if (strcmp(callee, "faceforward") == 0) {
+ if (dot(op[2], op[1]) < 0)
+ return op[0];
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = -op[0]->value.f[c];
+ } else if (strcmp(callee, "floor") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
+ } else if (strcmp(callee, "fract") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
+ } else if (strcmp(callee, "fwidth") == 0) {
+ return ir_constant::zero(mem_ctx, this->type);
+ } else if (strcmp(callee, "greaterThan") == 0) {
+ assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+ }
+ } else if (strcmp(callee, "greaterThanEqual") == 0) {
+ assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+ }
+ } else if (strcmp(callee, "inversesqrt") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
+ } else if (strcmp(callee, "length") == 0) {
+ return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
+ } else if (strcmp(callee, "lessThan") == 0) {
+ assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+ }
+ } else if (strcmp(callee, "lessThanEqual") == 0) {
+ assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+ }
+ } else if (strcmp(callee, "log") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
+ } else if (strcmp(callee, "log2") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
+ } else if (strcmp(callee, "matrixCompMult") == 0) {
+ assert(op[0]->type->is_float() && op[1]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
+ } else if (strcmp(callee, "max") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
+ } else if (strcmp(callee, "min") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
+ } else if (strcmp(callee, "mix") == 0) {
+ assert(op[0]->type->is_float() && op[1]->type->is_float());
+ if (op[2]->type->is_float()) {
+ unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
+ unsigned components = op[0]->type->components();
+ for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
+ data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
+ op[1]->value.f[c] * op[2]->value.f[c2];
+ }
+ } else {
+ assert(op[2]->type->is_boolean());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
+ }
+ } else if (strcmp(callee, "mod") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
+ } else if (strcmp(callee, "normalize") == 0) {
+ assert(op[0]->type->is_float());
+ float length = sqrtf(dot(op[0], op[0]));
+
+ if (length == 0)
+ return ir_constant::zero(mem_ctx, this->type);
+
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = op[0]->value.f[c] / length;
+ } else if (strcmp(callee, "not") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
+ } else if (strcmp(callee, "notEqual") == 0) {
+ assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ switch (op[0]->type->base_type) {
+ case GLSL_TYPE_UINT:
+ data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
+ break;
+ case GLSL_TYPE_INT:
+ data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
+ break;
+ case GLSL_TYPE_FLOAT:
+ data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
+ break;
+ case GLSL_TYPE_BOOL:
+ data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+ }
+ } else if (strcmp(callee, "outerProduct") == 0) {
+ assert(op[0]->type->is_vector() && op[1]->type->is_vector());
+ const unsigned m = op[0]->type->vector_elements;
+ const unsigned n = op[1]->type->vector_elements;
+ for (unsigned j = 0; j < n; j++) {
+ for (unsigned i = 0; i < m; i++) {
+ data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
+ }
+ }
+ } else if (strcmp(callee, "pow") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
+ } else if (strcmp(callee, "radians") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
+ } else if (strcmp(callee, "reflect") == 0) {
+ assert(op[0]->type->is_float());
+ float dot_NI = dot(op[1], op[0]);
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
+ } else if (strcmp(callee, "refract") == 0) {
+ const float eta = op[2]->value.f[0];
+ const float dot_NI = dot(op[1], op[0]);
+ const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
+ if (k < 0.0) {
+ return ir_constant::zero(mem_ctx, this->type);
+ } else {
+ for (unsigned c = 0; c < type->components(); c++) {
+ data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
+ * op[1]->value.f[c];
+ }
+ }
+ } else if (strcmp(callee, "sign") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
+ } else if (strcmp(callee, "sin") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
+ } else if (strcmp(callee, "sinh") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = sinhf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "smoothstep") == 0) {
+ assert(num_parameters == 3);
+ assert(op[1]->type == op[0]->type);
+ unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
+ for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
+ const float edge0 = op[0]->value.f[e];
+ const float edge1 = op[1]->value.f[e];
+ if (edge0 == edge1) {
+ data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
+ } else {
+ const float numerator = op[2]->value.f[c] - edge0;
+ const float denominator = edge1 - edge0;
+ const float t = CLAMP(numerator/denominator, 0, 1);
+ data.f[c] = t * t * (3 - 2 * t);
+ }
+ }
+ } else if (strcmp(callee, "sqrt") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
+ } else if (strcmp(callee, "step") == 0) {
+ assert(op[0]->type->is_float() && op[1]->type->is_float());
+ /* op[0] (edge) may be either a scalar or a vector */
+ const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
+ for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
+ data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
+ } else if (strcmp(callee, "tan") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = tanf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "tanh") == 0) {
+ assert(op[0]->type->is_float());
+ for (unsigned c = 0; c < op[0]->type->components(); c++)
+ data.f[c] = tanhf(op[0]->value.f[c]);
+ } else if (strcmp(callee, "transpose") == 0) {
+ assert(op[0]->type->is_matrix());
+ const unsigned n = op[0]->type->vector_elements;
+ const unsigned m = op[0]->type->matrix_columns;
+ for (unsigned j = 0; j < m; j++) {
+ for (unsigned i = 0; i < n; i++) {
+ data.f[m*i+j] += op[0]->value.f[i+n*j];
+ }
+ }
+ } else {
+ /* Unsupported builtin - some are not allowed in constant expressions. */
+ return NULL;
+ }
+
+ if (expr != NULL)
+ return expr->constant_expression_value();
+
+ return new(mem_ctx) ir_constant(this->type, &data);
+}
diff --git a/mesalib/src/glsl/ir_div_to_mul_rcp.cpp b/mesalib/src/glsl/ir_div_to_mul_rcp.cpp deleted file mode 100644 index 640d5d64f..000000000 --- a/mesalib/src/glsl/ir_div_to_mul_rcp.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file ir_div_to_mul_rcp.cpp - * - * Breaks an ir_unop_div expression down to op0 * (rcp(op1)). - * - * Many GPUs don't have a divide instruction (945 and 965 included), - * but they do have an RCP instruction to compute an approximate - * reciprocal. By breaking the operation down, constant reciprocals - * can get constant folded. - */ - -#include "ir.h" -#include "glsl_types.h" - -class ir_div_to_mul_rcp_visitor : public ir_hierarchical_visitor { -public: - ir_div_to_mul_rcp_visitor() - { - this->made_progress = false; - } - - ir_visitor_status visit_leave(ir_expression *); - - bool made_progress; -}; - -bool -do_div_to_mul_rcp(exec_list *instructions) -{ - ir_div_to_mul_rcp_visitor v; - - visit_list_elements(&v, instructions); - return v.made_progress; -} - -ir_visitor_status -ir_div_to_mul_rcp_visitor::visit_leave(ir_expression *ir) -{ - if (ir->operation != ir_binop_div) - return visit_continue; - - if (ir->operands[1]->type->base_type != GLSL_TYPE_INT && - ir->operands[1]->type->base_type != GLSL_TYPE_UINT) { - /* New expression for the 1.0 / op1 */ - ir_rvalue *expr; - expr = new(ir) ir_expression(ir_unop_rcp, - ir->operands[1]->type, - ir->operands[1], - NULL); - - /* op0 / op1 -> op0 * (1.0 / op1) */ - ir->operation = ir_binop_mul; - ir->operands[1] = expr; - } else { - /* Be careful with integer division -- we need to do it as a - * float and re-truncate, since rcp(n > 1) of an integer would - * just be 0. - */ - ir_rvalue *op0, *op1; - const struct glsl_type *vec_type; - - vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, - ir->operands[1]->type->vector_elements, - ir->operands[1]->type->matrix_columns); - - if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) - op1 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[1], NULL); - else - op1 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[1], NULL); - - op1 = new(ir) ir_expression(ir_unop_rcp, op1->type, op1, NULL); - - vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, - ir->operands[0]->type->vector_elements, - ir->operands[0]->type->matrix_columns); - - if (ir->operands[0]->type->base_type == GLSL_TYPE_INT) - op0 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[0], NULL); - else - op0 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[0], NULL); - - op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1); - - ir->operation = ir_unop_f2i; - ir->operands[0] = op0; - ir->operands[1] = NULL; - } - - this->made_progress = true; - - return visit_continue; -} diff --git a/mesalib/src/glsl/ir_explog_to_explog2.cpp b/mesalib/src/glsl/ir_explog_to_explog2.cpp deleted file mode 100644 index 78694a202..000000000 --- a/mesalib/src/glsl/ir_explog_to_explog2.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file ir_explog_to_explog2.cpp - * - * Many GPUs don't have a base e log or exponent instruction, but they - * do have base 2 versions, so this pass converts exp and log to exp2 - * and log2 operations. - */ - -#include "main/core.h" /* for log2f on MSVC */ -#include "ir.h" -#include "glsl_types.h" - -class ir_explog_to_explog2_visitor : public ir_hierarchical_visitor { -public: - ir_explog_to_explog2_visitor() - { - this->progress = false; - } - - ir_visitor_status visit_leave(ir_expression *); - - bool progress; -}; - -bool -do_explog_to_explog2(exec_list *instructions) -{ - ir_explog_to_explog2_visitor v; - - visit_list_elements(&v, instructions); - return v.progress; -} - -ir_visitor_status -ir_explog_to_explog2_visitor::visit_leave(ir_expression *ir) -{ - if (ir->operation == ir_unop_exp) { - void *mem_ctx = talloc_parent(ir); - ir_constant *log2_e = new(mem_ctx) ir_constant(log2f(M_E)); - - ir->operation = ir_unop_exp2; - ir->operands[0] = new(mem_ctx) ir_expression(ir_binop_mul, - ir->operands[0]->type, - ir->operands[0], - log2_e); - this->progress = true; - } - - if (ir->operation == ir_unop_log) { - void *mem_ctx = talloc_parent(ir); - - ir->operation = ir_binop_mul; - ir->operands[0] = new(mem_ctx) ir_expression(ir_unop_log2, - ir->operands[0]->type, - ir->operands[0], - NULL); - ir->operands[1] = new(mem_ctx) ir_constant(1.0f / log2f(M_E)); - this->progress = true; - } - - return visit_continue; -} diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index dfdec144b..4997570d0 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -1,227 +1,226 @@ -/* - * 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(const exec_list *list_a, const exec_list *list_b) -{ - const exec_node *node_a = list_a->head; - const exec_node *node_b = list_b->head; - int total_score = 0; - - for (/* empty */ - ; !node_a->is_tail_sentinel() - ; node_a = node_a->next, node_b = node_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 (node_b->is_tail_sentinel()) - return -1; - - - const ir_variable *const param = (ir_variable *) node_a; - const ir_instruction *const actual = (ir_instruction *) node_b; - - /* 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: - case ir_var_temporary: - /* 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; - - default: - assert(false); - } - - 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 (!node_b->is_tail_sentinel()) - return -1; - - return total_score; -} - - -ir_function_signature * -ir_function::matching_signature(const 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(const exec_list *list_a, const exec_list *list_b) -{ - const exec_node *node_a = list_a->head; - const exec_node *node_b = list_b->head; - - for (/* empty */ - ; !node_a->is_tail_sentinel() && !node_b->is_tail_sentinel() - ; node_a = node_a->next, node_b = node_b->next) { - ir_variable *a = (ir_variable *) node_a; - ir_variable *b = (ir_variable *) node_b; - - /* If the types of the parameters do not match, the parameters lists - * are different. - */ - if (a->type != b->type) - return false; - } - - /* Unless both lists are exhausted, they differ in length and, by - * definition, do not match. - */ - return (node_a->is_tail_sentinel() == node_b->is_tail_sentinel()); -} - -ir_function_signature * -ir_function::exact_matching_signature(const 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; -} +/*
+ * 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_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(const exec_list *list_a, const exec_list *list_b)
+{
+ const exec_node *node_a = list_a->head;
+ const exec_node *node_b = list_b->head;
+ int total_score = 0;
+
+ for (/* empty */
+ ; !node_a->is_tail_sentinel()
+ ; node_a = node_a->next, node_b = node_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 (node_b->is_tail_sentinel())
+ return -1;
+
+
+ const ir_variable *const param = (ir_variable *) node_a;
+ const ir_instruction *const actual = (ir_instruction *) node_b;
+
+ /* 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:
+ case ir_var_temporary:
+ /* 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;
+
+ default:
+ assert(false);
+ }
+
+ 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 (!node_b->is_tail_sentinel())
+ return -1;
+
+ return total_score;
+}
+
+
+ir_function_signature *
+ir_function::matching_signature(const 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(const exec_list *list_a, const exec_list *list_b)
+{
+ const exec_node *node_a = list_a->head;
+ const exec_node *node_b = list_b->head;
+
+ for (/* empty */
+ ; !node_a->is_tail_sentinel() && !node_b->is_tail_sentinel()
+ ; node_a = node_a->next, node_b = node_b->next) {
+ ir_variable *a = (ir_variable *) node_a;
+ ir_variable *b = (ir_variable *) node_b;
+
+ /* If the types of the parameters do not match, the parameters lists
+ * are different.
+ */
+ if (a->type != b->type)
+ return false;
+ }
+
+ /* Unless both lists are exhausted, they differ in length and, by
+ * definition, do not match.
+ */
+ return (node_a->is_tail_sentinel() == node_b->is_tail_sentinel());
+}
+
+ir_function_signature *
+ir_function::exact_matching_signature(const 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;
+}
diff --git a/mesalib/src/glsl/ir_function_can_inline.cpp b/mesalib/src/glsl/ir_function_can_inline.cpp index f29f277ef..2ed3aaa49 100644 --- a/mesalib/src/glsl/ir_function_can_inline.cpp +++ b/mesalib/src/glsl/ir_function_can_inline.cpp @@ -1,74 +1,76 @@ -/* - * 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); - - /* If the function is empty (no last instruction) or does not end with a - * return statement, we need to count the implicit return. - */ - ir_instruction *last = (ir_instruction *)callee->body.get_tail(); - if (last == NULL || !last->as_return()) - v.num_returns++; - - return v.num_returns == 1; -} +/*
+ * 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();
+ if (!callee->is_defined)
+ return false;
+
+ v.run((exec_list *) &callee->body);
+
+ /* If the function is empty (no last instruction) or does not end with a
+ * return statement, we need to count the implicit return.
+ */
+ ir_instruction *last = (ir_instruction *)callee->body.get_tail();
+ if (last == NULL || !last->as_return())
+ v.num_returns++;
+
+ return v.num_returns == 1;
+}
diff --git a/mesalib/src/glsl/ir_import_prototypes.cpp b/mesalib/src/glsl/ir_import_prototypes.cpp index 066137e60..fcd552870 100644 --- a/mesalib/src/glsl/ir_import_prototypes.cpp +++ b/mesalib/src/glsl/ir_import_prototypes.cpp @@ -1,138 +1,123 @@ -/* - * 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_import_prototypes.cpp - * Import function prototypes from one IR tree into another. - * - * \author Ian Romanick - */ -#include <cstdio> -#include "ir.h" -#include "glsl_symbol_table.h" - -/** - * Visitor used to import function prototypes - * - * Normally the \c clone method of either \c ir_function or - * \c ir_function_signature could be used. However, we don't want a complete - * clone of the \c ir_function_signature. We want everything \b except the - * body of the function. - */ -class import_prototype_visitor : public ir_hierarchical_visitor { -public: - /** - */ - import_prototype_visitor(exec_list *list, glsl_symbol_table *symbols, - void *mem_ctx) - { - this->mem_ctx = mem_ctx; - this->list = list; - this->symbols = symbols; - this->function = NULL; - } - - virtual ir_visitor_status visit_enter(ir_function *ir) - { - assert(this->function == NULL); - - this->function = this->symbols->get_function(ir->name); - if (!this->function) { - this->function = new(this->mem_ctx) ir_function(ir->name); - - list->push_tail(this->function); - - /* Add the new function to the symbol table. - */ - this->symbols->add_function(this->function->name, this->function); - } - return visit_continue; - } - - virtual ir_visitor_status visit_leave(ir_function *ir) - { - (void) ir; - assert(this->function != NULL); - - this->function = NULL; - return visit_continue; - } - - ir_visitor_status visit_enter(ir_function_signature *ir) - { - assert(this->function != NULL); - - ir_function_signature *copy = - new(mem_ctx) ir_function_signature(ir->return_type); - - copy->is_defined = false; - copy->is_builtin = ir->is_builtin; - - /* Clone the parameter list, but NOT the body. - */ - foreach_list_const(node, &ir->parameters) { - const ir_variable *const param = (const ir_variable *) node; - - assert(const_cast<ir_variable *>(param)->as_variable() != NULL); - - ir_variable *const param_copy = param->clone(mem_ctx, NULL); - copy->parameters.push_tail(param_copy); - } - - this->function->add_signature(copy); - - /* Do not process child nodes of the ir_function_signature. There can - * never be any nodes inside the ir_function_signature that we care - * about. Instead continue with the next sibling. - */ - return visit_continue_with_parent; - } - -private: - exec_list *list; - ir_function *function; - glsl_symbol_table *symbols; - void *mem_ctx; -}; - - -/** - * Import function prototypes from one IR tree into another - * - * \param source Source instruction stream containing functions whose - * prototypes are to be imported - * \param dest Destination instruction stream where new \c ir_function and - * \c ir_function_signature nodes will be stored - * \param symbols Symbol table where new functions will be stored - * \param mem_ctx talloc memory context used for new allocations - */ -void -import_prototypes(const exec_list *source, exec_list *dest, - glsl_symbol_table *symbols, void *mem_ctx) -{ - import_prototype_visitor v(dest, symbols, mem_ctx); - - /* Making source be const is just extra documentation. - */ - v.run(const_cast<exec_list *>(source)); -} +/*
+ * 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_import_prototypes.cpp
+ * Import function prototypes from one IR tree into another.
+ *
+ * \author Ian Romanick
+ */
+#include <cstdio>
+#include "ir.h"
+#include "glsl_symbol_table.h"
+
+/**
+ * Visitor used to import function prototypes
+ *
+ * Normally the \c clone method of either \c ir_function or
+ * \c ir_function_signature could be used. However, we don't want a complete
+ * clone of the \c ir_function_signature. We want everything \b except the
+ * body of the function.
+ */
+class import_prototype_visitor : public ir_hierarchical_visitor {
+public:
+ /**
+ */
+ import_prototype_visitor(exec_list *list, glsl_symbol_table *symbols,
+ void *mem_ctx)
+ {
+ this->mem_ctx = mem_ctx;
+ this->list = list;
+ this->symbols = symbols;
+ this->function = NULL;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_function *ir)
+ {
+ assert(this->function == NULL);
+
+ this->function = this->symbols->get_function(ir->name);
+ if (!this->function) {
+ this->function = new(this->mem_ctx) ir_function(ir->name);
+
+ list->push_tail(this->function);
+
+ /* Add the new function to the symbol table.
+ */
+ this->symbols->add_function(this->function);
+ }
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_function *ir)
+ {
+ (void) ir;
+ assert(this->function != NULL);
+
+ this->function = NULL;
+ return visit_continue;
+ }
+
+ ir_visitor_status visit_enter(ir_function_signature *ir)
+ {
+ assert(this->function != NULL);
+
+ ir_function_signature *copy = ir->clone_prototype(mem_ctx, NULL);
+
+ this->function->add_signature(copy);
+
+ /* Do not process child nodes of the ir_function_signature. There can
+ * never be any nodes inside the ir_function_signature that we care
+ * about. Instead continue with the next sibling.
+ */
+ return visit_continue_with_parent;
+ }
+
+private:
+ exec_list *list;
+ ir_function *function;
+ glsl_symbol_table *symbols;
+ void *mem_ctx;
+};
+
+
+/**
+ * Import function prototypes from one IR tree into another
+ *
+ * \param source Source instruction stream containing functions whose
+ * prototypes are to be imported
+ * \param dest Destination instruction stream where new \c ir_function and
+ * \c ir_function_signature nodes will be stored
+ * \param symbols Symbol table where new functions will be stored
+ * \param mem_ctx talloc memory context used for new allocations
+ */
+void
+import_prototypes(const exec_list *source, exec_list *dest,
+ glsl_symbol_table *symbols, void *mem_ctx)
+{
+ import_prototype_visitor v(dest, symbols, mem_ctx);
+
+ /* Making source be const is just extra documentation.
+ */
+ v.run(const_cast<exec_list *>(source));
+}
diff --git a/mesalib/src/glsl/ir_mod_to_fract.cpp b/mesalib/src/glsl/ir_mod_to_fract.cpp deleted file mode 100644 index c82a1f64f..000000000 --- a/mesalib/src/glsl/ir_mod_to_fract.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file ir_mod_to_fract.cpp - * - * Breaks an ir_unop_mod expression down to (op1 * fract(op0 / op1)) - * - * Many GPUs don't have a MOD instruction (945 and 965 included), and - * if we have to break it down like this anyway, it gives an - * opportunity to do things like constant fold the (1.0 / op1) easily. - */ - -#include "ir.h" - -class ir_mod_to_fract_visitor : public ir_hierarchical_visitor { -public: - ir_mod_to_fract_visitor() - { - this->made_progress = false; - } - - ir_visitor_status visit_leave(ir_expression *); - - bool made_progress; -}; - -bool -do_mod_to_fract(exec_list *instructions) -{ - ir_mod_to_fract_visitor v; - - visit_list_elements(&v, instructions); - return v.made_progress; -} - -ir_visitor_status -ir_mod_to_fract_visitor::visit_leave(ir_expression *ir) -{ - if (ir->operation != ir_binop_mod) - return visit_continue; - - ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b", - ir_var_temporary); - this->base_ir->insert_before(temp); - - ir_assignment *assign; - ir_rvalue *expr; - - assign = new(ir) ir_assignment(new(ir) ir_dereference_variable(temp), - ir->operands[1], NULL); - this->base_ir->insert_before(assign); - - expr = new(ir) ir_expression(ir_binop_div, - ir->operands[0]->type, - ir->operands[0], - new(ir) ir_dereference_variable(temp)); - - expr = new(ir) ir_expression(ir_unop_fract, - ir->operands[0]->type, - expr, - NULL); - - ir->operation = ir_binop_mul; - ir->operands[0] = new(ir) ir_dereference_variable(temp); - ir->operands[1] = expr; - this->made_progress = true; - - return visit_continue; -} diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h index 6a37e167f..609092e76 100644 --- a/mesalib/src/glsl/ir_optimization.h +++ b/mesalib/src/glsl/ir_optimization.h @@ -1,61 +1,72 @@ -/* - * 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_optimization.h - * - * Prototypes for optimization passes to be called by the compiler and drivers. - */ - -bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations); - -bool do_algebraic(exec_list *instructions); -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_constant_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_dead_functions(exec_list *instructions); -bool do_div_to_mul_rcp(exec_list *instructions); -bool do_explog_to_explog2(exec_list *instructions); -bool do_function_inlining(exec_list *instructions); -bool do_lower_jumps(exec_list *instructions, bool pull_out_jumps = true, bool lower_sub_return = true, bool lower_main_return = false, bool lower_continue = false, bool lower_break = false); -bool do_if_simplification(exec_list *instructions); -bool do_if_to_cond_assign(exec_list *instructions); -bool do_mat_op_to_vec(exec_list *instructions); -bool do_mod_to_fract(exec_list *instructions); -bool do_noop_swizzle(exec_list *instructions); -bool do_structure_splitting(exec_list *instructions); -bool do_sub_to_add_neg(exec_list *instructions); -bool do_swizzle_swizzle(exec_list *instructions); -bool do_tree_grafting(exec_list *instructions); -bool do_vec_index_to_cond_assign(exec_list *instructions); -bool do_vec_index_to_swizzle(exec_list *instructions); -bool lower_noise(exec_list *instructions); -bool lower_variable_index_to_cond_assign(exec_list *instructions, - bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform); -bool optimize_redundant_jumps(exec_list *instructions); +/*
+ * 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_optimization.h
+ *
+ * Prototypes for optimization passes to be called by the compiler and drivers.
+ */
+
+/* Operations for lower_instructions() */
+#define SUB_TO_ADD_NEG 0x01
+#define DIV_TO_MUL_RCP 0x02
+#define EXP_TO_EXP2 0x04
+#define POW_TO_EXP2 0x08
+#define LOG_TO_LOG2 0x10
+#define MOD_TO_FRACT 0x20
+
+bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations);
+
+bool do_algebraic(exec_list *instructions);
+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_constant_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_dead_functions(exec_list *instructions);
+bool do_function_inlining(exec_list *instructions);
+bool do_lower_jumps(exec_list *instructions, bool pull_out_jumps = true, bool lower_sub_return = true, bool lower_main_return = false, bool lower_continue = false, bool lower_break = false);
+bool do_lower_texture_projection(exec_list *instructions);
+bool do_if_simplification(exec_list *instructions);
+bool do_discard_simplification(exec_list *instructions);
+bool lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth = 0);
+bool do_mat_op_to_vec(exec_list *instructions);
+bool do_mod_to_fract(exec_list *instructions);
+bool do_noop_swizzle(exec_list *instructions);
+bool do_structure_splitting(exec_list *instructions);
+bool do_sub_to_add_neg(exec_list *instructions);
+bool do_swizzle_swizzle(exec_list *instructions);
+bool do_tree_grafting(exec_list *instructions);
+bool do_vec_index_to_cond_assign(exec_list *instructions);
+bool do_vec_index_to_swizzle(exec_list *instructions);
+bool lower_discard(exec_list *instructions);
+bool lower_instructions(exec_list *instructions, unsigned what_to_lower);
+bool lower_noise(exec_list *instructions);
+bool lower_variable_index_to_cond_assign(exec_list *instructions,
+ bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform);
+bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz);
+bool optimize_redundant_jumps(exec_list *instructions);
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 5c19db132..bed838fe8 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -1,465 +1,466 @@ -/* - * 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) -{ - if (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, (void *) 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 *ir = (ir_instruction *)iter.get(); - ir->print(); - if (ir->ir_type != ir_type_function) - printf("\n"); - } - printf("\n)"); -} - - -void ir_print_visitor::indent(void) -{ - for (int i = 0; i < indentation; i++) - printf(" "); -} - -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, (void *) 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 ", - "temporary " }; - 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, (void *) ir); -} - - -void ir_print_visitor::visit(ir_function_signature *ir) -{ - printf("(signature "); - indentation++; - - print_type(ir->return_type); - printf("\n"); - indent(); - - printf("(parameters\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->parameters) { - ir_variable *const inst = (ir_variable *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - - indent(); - printf(")\n"); - - indent(); - - printf("(\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->body) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf("))\n"); - indentation--; -} - - -void ir_print_visitor::visit(ir_function *ir) -{ - if (!ir->has_user_signature()) - return; - - printf("(function %s\n", ir->name); - indentation++; - foreach_iter(exec_list_iterator, iter, *ir) { - ir_function_signature *const sig = (ir_function_signature *) iter.get(); - - if (sig->is_builtin) - continue; - - indent(); - sig->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf(")\n\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, (void *) 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))"); - - - char mask[5]; - unsigned j = 0; - - for (unsigned i = 0; i < 4; i++) { - if ((ir->write_mask & (1 << i)) != 0) { - mask[j] = "xyzw"[i]; - j++; - } - } - mask[j] = '\0'; - - printf(" (%s) ", mask); - - 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(" ("); - - if (ir->type->is_array()) { - for (unsigned i = 0; i < ir->type->length; i++) - ir->get_array_element(i)->accept(this); - } else { - 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_discard *ir) -{ - printf("(discard "); - - if (ir->condition != NULL) { - printf(" "); - ir->condition->accept(this); - } - - printf(")"); -} - - -void -ir_print_visitor::visit(ir_if *ir) -{ - printf("(if "); - ir->condition->accept(this); - - printf("(\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->then_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - - indentation--; - indent(); - printf(")\n"); - - indent(); - if (!ir->else_instructions.is_empty()) { - printf("(\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->else_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf("))\n"); - } else { - 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"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->body_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf("))\n"); -} - - -void -ir_print_visitor::visit(ir_loop_jump *ir) -{ - printf("%s", ir->is_break() ? "break" : "continue"); -} +/*
+ * 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)
+{
+ if (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, (void *) 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 *ir = (ir_instruction *)iter.get();
+ ir->print();
+ if (ir->ir_type != ir_type_function)
+ printf("\n");
+ }
+ printf("\n)");
+}
+
+
+void ir_print_visitor::indent(void)
+{
+ for (int i = 0; i < indentation; i++)
+ printf(" ");
+}
+
+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, (void *) 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 ",
+ "temporary " };
+ 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, (void *) ir);
+}
+
+
+void ir_print_visitor::visit(ir_function_signature *ir)
+{
+ printf("(signature ");
+ indentation++;
+
+ print_type(ir->return_type);
+ printf("\n");
+ indent();
+
+ printf("(parameters\n");
+ indentation++;
+
+ foreach_iter(exec_list_iterator, iter, ir->parameters) {
+ ir_variable *const inst = (ir_variable *) iter.get();
+
+ indent();
+ inst->accept(this);
+ printf("\n");
+ }
+ indentation--;
+
+ indent();
+ printf(")\n");
+
+ indent();
+
+ printf("(\n");
+ indentation++;
+
+ foreach_iter(exec_list_iterator, iter, ir->body) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ indent();
+ inst->accept(this);
+ printf("\n");
+ }
+ indentation--;
+ indent();
+ printf("))\n");
+ indentation--;
+}
+
+
+void ir_print_visitor::visit(ir_function *ir)
+{
+ printf("(function %s\n", ir->name);
+ indentation++;
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_function_signature *const sig = (ir_function_signature *) iter.get();
+ indent();
+ sig->accept(this);
+ printf("\n");
+ }
+ indentation--;
+ indent();
+ printf(")\n\n");
+}
+
+
+void ir_print_visitor::visit(ir_expression *ir)
+{
+ printf("(expression ");
+
+ print_type(ir->type);
+
+ printf(" %s ", ir->operator_string());
+
+ for (unsigned i = 0; i < ir->get_num_operands(); i++) {
+ ir->operands[i]->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, (void *) 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))");
+
+
+ char mask[5];
+ unsigned j = 0;
+
+ for (unsigned i = 0; i < 4; i++) {
+ if ((ir->write_mask & (1 << i)) != 0) {
+ mask[j] = "xyzw"[i];
+ j++;
+ }
+ }
+ mask[j] = '\0';
+
+ printf(" (%s) ", mask);
+
+ 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(" (");
+
+ if (ir->type->is_array()) {
+ for (unsigned i = 0; i < ir->type->length; i++)
+ ir->get_array_element(i)->accept(this);
+ } else if (ir->type->is_record()) {
+ ir_constant *value = (ir_constant *) ir->components.get_head();
+ for (unsigned i = 0; i < ir->type->length; i++) {
+ printf("(%s ", ir->type->fields.structure->name);
+ value->accept(this);
+ printf(")");
+
+ value = (ir_constant *) value->next;
+ }
+ } else {
+ 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_discard *ir)
+{
+ printf("(discard ");
+
+ if (ir->condition != NULL) {
+ printf(" ");
+ ir->condition->accept(this);
+ }
+
+ printf(")");
+}
+
+
+void
+ir_print_visitor::visit(ir_if *ir)
+{
+ printf("(if ");
+ ir->condition->accept(this);
+
+ printf("(\n");
+ indentation++;
+
+ foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ indent();
+ inst->accept(this);
+ printf("\n");
+ }
+
+ indentation--;
+ indent();
+ printf(")\n");
+
+ indent();
+ if (!ir->else_instructions.is_empty()) {
+ printf("(\n");
+ indentation++;
+
+ foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ indent();
+ inst->accept(this);
+ printf("\n");
+ }
+ indentation--;
+ indent();
+ printf("))\n");
+ } else {
+ 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");
+ indentation++;
+
+ foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
+ ir_instruction *const inst = (ir_instruction *) iter.get();
+
+ indent();
+ inst->accept(this);
+ printf("\n");
+ }
+ indentation--;
+ indent();
+ printf("))\n");
+}
+
+
+void
+ir_print_visitor::visit(ir_loop_jump *ir)
+{
+ printf("%s", ir->is_break() ? "break" : "continue");
+}
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index a9cbf8ea9..b15df6ddf 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -1,1146 +1,1143 @@ -/* - * 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" - -const static bool debug = false; - -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, bool scan_for_protos) -{ - s_expression *expr = s_expression::read_expression(state, src); - if (expr == NULL) { - ir_read_error(state, NULL, "couldn't parse S-Expression."); - return; - } - - if (scan_for_protos) { - scan_for_prototypes(state, instructions, expr); - if (state->error) - return; - } - - read_instructions(state, instructions, expr, NULL); - talloc_free(expr); - - if (debug) - validate_ir_tree(instructions); -} - -static void -ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr, - const char *fmt, ...) -{ - va_list ap; - - state->error = true; - - if (state->current_function != NULL) - state->info_log = talloc_asprintf_append(state->info_log, - "In function %s:\n", - state->current_function->function_name()); - 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(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 = st; - bool added = false; - 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()); - added = st->symbols->add_function(f->name, 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 added ? f : NULL; -} - -static void -read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list, - bool skip_body) -{ - void *ctx = 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 && skip_body) { - /* If scanning for prototypes, generate a new signature. */ - sig = new(ctx) ir_function_signature(return_type); - sig->is_builtin = true; - f->add_signature(sig); - } else 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 { - /* No prototype for this body exists - skip it. */ - st->symbols->pop_scope(); - return; - } - assert(sig != NULL); - - sig->replace_parameters(&hir_parameters); - - if (!skip_body && !body_list->subexpressions.is_empty()) { - if (sig->is_defined) { - ir_read_error(st, list, "function %s redefined", f->name); - return; - } - st->current_function = sig; - read_instructions(st, &sig->body, body_list, NULL); - st->current_function = 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) { - /* Global variable declarations should be moved to the top, before - * any functions that might use them. Functions are added to the - * instruction stream when scanning for prototypes, so without this - * hack, they always appear before variable declarations. - */ - if (st->current_function == NULL && ir->as_variable() != NULL) - instructions->push_head(ir); - else - instructions->push_tail(ir); - } - } -} - - -static ir_instruction * -read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, - ir_loop *loop_ctx) -{ - void *ctx = 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()) { - ir_read_error(st, expr, "Invalid instruction.\n"); - 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(), "assign") == 0) { - inst = read_assignment(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 = 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(), - ir_var_auto); - - 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, var); - - return var; -} - - -static ir_if * -read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx) -{ - void *ctx = 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 = 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 = 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(), "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 = st; - if (list->length() != 5) { - ir_read_error(st, list, "expected (assign <condition> (<write mask>) " - "<lhs> <rhs>)"); - return NULL; - } - - s_expression *cond_expr = (s_expression*) list->subexpressions.head->next; - s_list *mask_list = SX_AS_LIST(cond_expr->next); - s_expression *lhs_expr = (s_expression*) cond_expr->next->next; - s_expression *rhs_expr = (s_expression*) lhs_expr->next; - - ir_rvalue *condition = read_rvalue(st, cond_expr); - if (condition == NULL) { - ir_read_error(st, NULL, "when reading condition of assignment"); - return NULL; - } - - if (mask_list == NULL || mask_list->length() > 1) { - ir_read_error(st, mask_list, "expected () or (<write mask>)"); - return NULL; - } - - unsigned mask = 0; - if (mask_list->length() == 1) { - s_symbol *mask_symbol = SX_AS_SYMBOL(mask_list->subexpressions.head); - if (mask_symbol == NULL) { - ir_read_error(st, list, "expected a write mask; found non-symbol"); - return NULL; - } - - const char *mask_str = mask_symbol->value(); - unsigned mask_length = strlen(mask_str); - if (mask_length > 4) { - ir_read_error(st, list, "invalid write mask: %s", mask_str); - return NULL; - } - - const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */ - - for (unsigned i = 0; i < mask_length; i++) { - if (mask_str[i] < 'w' || mask_str[i] > 'z') { - ir_read_error(st, list, "write mask contains invalid character: %c", - mask_str[i]); - return NULL; - } - mask |= 1 << idx_map[mask_str[i] - 'w']; - } - } - - ir_dereference *lhs = read_dereference(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; - } - - if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) { - ir_read_error(st, list, "non-zero write mask required."); - return NULL; - } - - return new(ctx) ir_assignment(lhs, rhs, condition, mask); -} - -static ir_call * -read_call(_mesa_glsl_parse_state *st, s_list *list) -{ - void *ctx = 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; - } - - 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 = 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 = st; - if (list->length() != 3) { - ir_read_error(st, list, "expected (constant <type> (...))"); - 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> (...))"); - return NULL; - } - - if (type->is_array()) { - const unsigned elements_supplied = values->length(); - if (elements_supplied != type->length) { - ir_read_error(st, values, "expected exactly %u array elements, " - "given %u", type->length, elements_supplied); - return NULL; - } - - exec_list elements; - foreach_iter(exec_list_iterator, it, values->subexpressions) { - s_expression *expr = (s_expression *) it.get(); - s_list *elt = SX_AS_LIST(expr); - if (elt == NULL) { - ir_read_error(st, expr, "expected (constant ...) array element"); - return NULL; - } - - ir_constant *ir_elt = read_constant(st, elt); - if (ir_elt == NULL) - return NULL; - elements.push_tail(ir_elt); - } - return new(ctx) ir_constant(type, &elements); - } - - const glsl_type *const base_type = type->get_base_type(); - - ir_constant_data data = { { 0 } }; - - // 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 = 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 = 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 = 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 = 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; -} +/*
+ * 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"
+
+const static bool debug = false;
+
+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_variable *
+read_var_ref(_mesa_glsl_parse_state *, s_list *);
+static ir_dereference_array *
+read_array_ref(_mesa_glsl_parse_state *, s_list *);
+static ir_dereference_record *
+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, bool scan_for_protos)
+{
+ s_expression *expr = s_expression::read_expression(state, src);
+ if (expr == NULL) {
+ ir_read_error(state, NULL, "couldn't parse S-Expression.");
+ return;
+ }
+
+ if (scan_for_protos) {
+ scan_for_prototypes(state, instructions, expr);
+ if (state->error)
+ return;
+ }
+
+ read_instructions(state, instructions, expr, NULL);
+ talloc_free(expr);
+
+ if (debug)
+ validate_ir_tree(instructions);
+}
+
+static void
+ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ state->error = true;
+
+ if (state->current_function != NULL)
+ state->info_log = talloc_asprintf_append(state->info_log,
+ "In function %s:\n",
+ state->current_function->function_name());
+ 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(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 = st;
+ bool added = false;
+ 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());
+ added = st->symbols->add_function(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 added ? f : NULL;
+}
+
+static void
+read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
+ bool skip_body)
+{
+ void *ctx = 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(type_expr->next->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 && skip_body) {
+ /* If scanning for prototypes, generate a new signature. */
+ sig = new(ctx) ir_function_signature(return_type);
+ sig->is_builtin = true;
+ f->add_signature(sig);
+ } else 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 {
+ /* No prototype for this body exists - skip it. */
+ st->symbols->pop_scope();
+ return;
+ }
+ assert(sig != NULL);
+
+ sig->replace_parameters(&hir_parameters);
+
+ if (!skip_body && !body_list->subexpressions.is_empty()) {
+ if (sig->is_defined) {
+ ir_read_error(st, list, "function %s redefined", f->name);
+ return;
+ }
+ st->current_function = sig;
+ read_instructions(st, &sig->body, body_list, NULL);
+ st->current_function = 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) {
+ /* Global variable declarations should be moved to the top, before
+ * any functions that might use them. Functions are added to the
+ * instruction stream when scanning for prototypes, so without this
+ * hack, they always appear before variable declarations.
+ */
+ if (st->current_function == NULL && ir->as_variable() != NULL)
+ instructions->push_head(ir);
+ else
+ instructions->push_tail(ir);
+ }
+ }
+}
+
+
+static ir_instruction *
+read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
+ ir_loop *loop_ctx)
+{
+ void *ctx = 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()) {
+ ir_read_error(st, expr, "Invalid instruction.\n");
+ 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(), "assign") == 0) {
+ inst = read_assignment(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 = 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(),
+ ir_var_auto);
+
+ 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);
+
+ return var;
+}
+
+
+static ir_if *
+read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
+{
+ void *ctx = 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 = 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 = 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(), "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 = st;
+ if (list->length() != 5) {
+ ir_read_error(st, list, "expected (assign <condition> (<write mask>) "
+ "<lhs> <rhs>)");
+ return NULL;
+ }
+
+ s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
+ s_list *mask_list = SX_AS_LIST(cond_expr->next);
+ s_expression *lhs_expr = (s_expression*) cond_expr->next->next;
+ s_expression *rhs_expr = (s_expression*) lhs_expr->next;
+
+ ir_rvalue *condition = read_rvalue(st, cond_expr);
+ if (condition == NULL) {
+ ir_read_error(st, NULL, "when reading condition of assignment");
+ return NULL;
+ }
+
+ if (mask_list == NULL || mask_list->length() > 1) {
+ ir_read_error(st, mask_list, "expected () or (<write mask>)");
+ return NULL;
+ }
+
+ unsigned mask = 0;
+ if (mask_list->length() == 1) {
+ s_symbol *mask_symbol = SX_AS_SYMBOL(mask_list->subexpressions.head);
+ if (mask_symbol == NULL) {
+ ir_read_error(st, list, "expected a write mask; found non-symbol");
+ return NULL;
+ }
+
+ const char *mask_str = mask_symbol->value();
+ unsigned mask_length = strlen(mask_str);
+ if (mask_length > 4) {
+ ir_read_error(st, list, "invalid write mask: %s", mask_str);
+ return NULL;
+ }
+
+ const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */
+
+ for (unsigned i = 0; i < mask_length; i++) {
+ if (mask_str[i] < 'w' || mask_str[i] > 'z') {
+ ir_read_error(st, list, "write mask contains invalid character: %c",
+ mask_str[i]);
+ return NULL;
+ }
+ mask |= 1 << idx_map[mask_str[i] - 'w'];
+ }
+ }
+
+ ir_dereference *lhs = read_dereference(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;
+ }
+
+ if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) {
+ ir_read_error(st, list, "non-zero write mask required.");
+ return NULL;
+ }
+
+ return new(ctx) ir_assignment(lhs, rhs, condition, mask);
+}
+
+static ir_call *
+read_call(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = 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(list->subexpressions.head->next->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;
+ }
+
+ 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 = 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;
+ 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 = st;
+ if (list->length() != 3) {
+ ir_read_error(st, list, "expected (constant <type> (...))");
+ 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> (...))");
+ return NULL;
+ }
+
+ if (type->is_array()) {
+ const unsigned elements_supplied = values->length();
+ if (elements_supplied != type->length) {
+ ir_read_error(st, values, "expected exactly %u array elements, "
+ "given %u", type->length, elements_supplied);
+ return NULL;
+ }
+
+ exec_list elements;
+ foreach_iter(exec_list_iterator, it, values->subexpressions) {
+ s_expression *expr = (s_expression *) it.get();
+ s_list *elt = SX_AS_LIST(expr);
+ if (elt == NULL) {
+ ir_read_error(st, expr, "expected (constant ...) array element");
+ return NULL;
+ }
+
+ ir_constant *ir_elt = read_constant(st, elt);
+ if (ir_elt == NULL)
+ return NULL;
+ elements.push_tail(ir_elt);
+ }
+ return new(ctx) ir_constant(type, &elements);
+ }
+
+ const glsl_type *const base_type = type->get_base_type();
+
+ ir_constant_data data = { { 0 } };
+
+ // 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_variable *
+read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = 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_array *
+read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = 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_record *
+read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
+{
+ void *ctx = 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 = 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_list->subexpressions.head->next);
+ s_int *offset_z = SX_AS_INT(offset_list->subexpressions.head->next->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;
+}
diff --git a/mesalib/src/glsl/ir_set_program_inouts.cpp b/mesalib/src/glsl/ir_set_program_inouts.cpp index b3f1cc0d8..fc789913f 100644 --- a/mesalib/src/glsl/ir_set_program_inouts.cpp +++ b/mesalib/src/glsl/ir_set_program_inouts.cpp @@ -1,167 +1,162 @@ -/* - * 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_set_program_inouts.cpp - * - * Sets the InputsRead and OutputsWritten of Mesa programs. - * - * Mesa programs (gl_program, not gl_shader_program) have a set of - * flags indicating which varyings are read and written. Computing - * which are actually read from some sort of backend code can be - * tricky when variable array indexing involved. So this pass - * provides support for setting InputsRead and OutputsWritten right - * from the GLSL IR. - */ - -extern "C" { -#include "main/core.h" /* for struct gl_program */ -#include "program/hash_table.h" -} -#include "ir.h" -#include "ir_visitor.h" -#include "glsl_types.h" - -class ir_set_program_inouts_visitor : public ir_hierarchical_visitor { -public: - ir_set_program_inouts_visitor(struct gl_program *prog) - { - this->prog = prog; - this->ht = hash_table_ctor(0, - hash_table_pointer_hash, - hash_table_pointer_compare); - } - ~ir_set_program_inouts_visitor() - { - hash_table_dtor(this->ht); - } - - virtual ir_visitor_status visit_enter(ir_dereference_array *); - virtual ir_visitor_status visit_enter(ir_function_signature *); - virtual ir_visitor_status visit(ir_dereference_variable *); - virtual ir_visitor_status visit(ir_variable *); - - struct gl_program *prog; - struct hash_table *ht; -}; - -static void -mark(struct gl_program *prog, ir_variable *var, int index) -{ - /* As of GLSL 1.20, varyings can only be floats, floating-point - * vectors or matrices, or arrays of them. For Mesa programs using - * InputsRead/OutputsWritten, everything but matrices uses one - * slot, while matrices use a slot per column. Presumably - * something doing a more clever packing would use something other - * than InputsRead/OutputsWritten. - */ - const glsl_type *element_type; - int element_size; - - if (var->type->is_array()) - element_type = var->type->fields.array; - else - element_type = var->type; - - if (element_type->is_matrix()) - element_size = element_type->matrix_columns; - else - element_size = 1; - - index *= element_size; - for (int i = 0; i < element_size; i++) { - if (var->mode == ir_var_in) - prog->InputsRead |= BITFIELD64_BIT(var->location + index + i); - else - prog->OutputsWritten |= BITFIELD64_BIT(var->location + index + i); - } -} - -/* Default handler: Mark all the locations in the variable as used. */ -ir_visitor_status -ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir) -{ - if (hash_table_find(this->ht, ir->var) == NULL) - return visit_continue; - - if (ir->type->is_array()) { - for (unsigned int i = 0; i < ir->type->length; i++) { - mark(this->prog, ir->var, i); - } - } else { - mark(this->prog, ir->var, 0); - } - - return visit_continue; -} - -ir_visitor_status -ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) -{ - ir_dereference_variable *deref_var; - ir_constant *index = ir->array_index->as_constant(); - deref_var = ir->array->as_dereference_variable(); - ir_variable *var = NULL; - - /* Check that we're dereferencing a shader in or out */ - if (deref_var) - var = (ir_variable *)hash_table_find(this->ht, deref_var->var); - - if (index && var) { - mark(this->prog, var, index->value.i[0]); - return visit_continue_with_parent; - } - - return visit_continue; -} - -ir_visitor_status -ir_set_program_inouts_visitor::visit(ir_variable *ir) -{ - if (ir->mode == ir_var_in || - ir->mode == ir_var_out) { - hash_table_insert(this->ht, ir, ir); - } - - return visit_continue; -} - -ir_visitor_status -ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir) -{ - /* We don't want to descend into the function parameters and - * consider them as shader inputs or outputs. - */ - visit_list_elements(this, &ir->body); - return visit_continue_with_parent; -} - -void -do_set_program_inouts(exec_list *instructions, struct gl_program *prog) -{ - ir_set_program_inouts_visitor v(prog); - - prog->InputsRead = 0; - prog->OutputsWritten = 0; - visit_list_elements(&v, instructions); -} +/*
+ * 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_set_program_inouts.cpp
+ *
+ * Sets the InputsRead and OutputsWritten of Mesa programs.
+ *
+ * Mesa programs (gl_program, not gl_shader_program) have a set of
+ * flags indicating which varyings are read and written. Computing
+ * which are actually read from some sort of backend code can be
+ * tricky when variable array indexing involved. So this pass
+ * provides support for setting InputsRead and OutputsWritten right
+ * from the GLSL IR.
+ */
+
+extern "C" {
+#include "main/core.h" /* for struct gl_program */
+#include "program/hash_table.h"
+}
+#include "ir.h"
+#include "ir_visitor.h"
+#include "glsl_types.h"
+
+class ir_set_program_inouts_visitor : public ir_hierarchical_visitor {
+public:
+ ir_set_program_inouts_visitor(struct gl_program *prog)
+ {
+ this->prog = prog;
+ this->ht = hash_table_ctor(0,
+ hash_table_pointer_hash,
+ hash_table_pointer_compare);
+ }
+ ~ir_set_program_inouts_visitor()
+ {
+ hash_table_dtor(this->ht);
+ }
+
+ virtual ir_visitor_status visit_enter(ir_dereference_array *);
+ virtual ir_visitor_status visit_enter(ir_function_signature *);
+ virtual ir_visitor_status visit(ir_dereference_variable *);
+ virtual ir_visitor_status visit(ir_variable *);
+
+ struct gl_program *prog;
+ struct hash_table *ht;
+};
+
+static void
+mark(struct gl_program *prog, ir_variable *var, int offset, int len)
+{
+ /* As of GLSL 1.20, varyings can only be floats, floating-point
+ * vectors or matrices, or arrays of them. For Mesa programs using
+ * InputsRead/OutputsWritten, everything but matrices uses one
+ * slot, while matrices use a slot per column. Presumably
+ * something doing a more clever packing would use something other
+ * than InputsRead/OutputsWritten.
+ */
+
+ for (int i = 0; i < len; i++) {
+ if (var->mode == ir_var_in)
+ prog->InputsRead |= BITFIELD64_BIT(var->location + offset + i);
+ else
+ prog->OutputsWritten |= BITFIELD64_BIT(var->location + offset + i);
+ }
+}
+
+/* Default handler: Mark all the locations in the variable as used. */
+ir_visitor_status
+ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
+{
+ if (hash_table_find(this->ht, ir->var) == NULL)
+ return visit_continue;
+
+ if (ir->type->is_array()) {
+ for (unsigned int i = 0; i < ir->type->length; i++) {
+ mark(this->prog, ir->var, i,
+ ir->type->length * ir->type->fields.array->matrix_columns);
+ }
+ } else {
+ mark(this->prog, ir->var, 0, ir->type->matrix_columns);
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
+{
+ ir_dereference_variable *deref_var;
+ ir_constant *index = ir->array_index->as_constant();
+ deref_var = ir->array->as_dereference_variable();
+ ir_variable *var = NULL;
+
+ /* Check that we're dereferencing a shader in or out */
+ if (deref_var)
+ var = (ir_variable *)hash_table_find(this->ht, deref_var->var);
+
+ if (index && var) {
+ int width = 1;
+
+ if (deref_var->type->is_array() &&
+ deref_var->type->fields.array->is_matrix()) {
+ width = deref_var->type->fields.array->matrix_columns;
+ }
+
+ mark(this->prog, var, index->value.i[0] * width, width);
+ return visit_continue_with_parent;
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_set_program_inouts_visitor::visit(ir_variable *ir)
+{
+ if (ir->mode == ir_var_in ||
+ ir->mode == ir_var_out) {
+ hash_table_insert(this->ht, ir, ir);
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir)
+{
+ /* We don't want to descend into the function parameters and
+ * consider them as shader inputs or outputs.
+ */
+ visit_list_elements(this, &ir->body);
+ return visit_continue_with_parent;
+}
+
+void
+do_set_program_inouts(exec_list *instructions, struct gl_program *prog)
+{
+ ir_set_program_inouts_visitor v(prog);
+
+ prog->InputsRead = 0;
+ prog->OutputsWritten = 0;
+ visit_list_elements(&v, instructions);
+}
diff --git a/mesalib/src/glsl/ir_sub_to_add_neg.cpp b/mesalib/src/glsl/ir_sub_to_add_neg.cpp deleted file mode 100644 index 7ed8c1495..000000000 --- a/mesalib/src/glsl/ir_sub_to_add_neg.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file ir_sub_to_add_neg.cpp - * - * Breaks an ir_binop_sub expression down to add(op0, neg(op1)) - * - * This simplifies expression reassociation, and for many backends - * there is no subtract operation separate from adding the negation. - * For backends with native subtract operations, they will probably - * want to recognize add(op0, neg(op1)) or the other way around to - * produce a subtract anyway. - */ - -#include "ir.h" - -class ir_sub_to_add_neg_visitor : public ir_hierarchical_visitor { -public: - ir_sub_to_add_neg_visitor() - { - this->progress = false; - } - - ir_visitor_status visit_leave(ir_expression *); - - bool progress; -}; - -bool -do_sub_to_add_neg(exec_list *instructions) -{ - ir_sub_to_add_neg_visitor v; - - visit_list_elements(&v, instructions); - return v.progress; -} - -ir_visitor_status -ir_sub_to_add_neg_visitor::visit_leave(ir_expression *ir) -{ - if (ir->operation != ir_binop_sub) - return visit_continue; - - void *mem_ctx = talloc_parent(ir); - - ir->operation = ir_binop_add; - ir->operands[1] = new(mem_ctx) ir_expression(ir_unop_neg, - ir->operands[1]->type, - ir->operands[1], - NULL); - - this->progress = true; - - return visit_continue; -} diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index e35514aa6..9e2f7751c 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -1,452 +1,529 @@ -/* - * 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 "program/hash_table.h" -#include "glsl_types.h" - -class ir_validate : public ir_hierarchical_visitor { -public: - ir_validate() - { - this->ht = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); - - this->current_function = NULL; - - this->callback = ir_validate::validate_ir; - this->data = ht; - } - - ~ir_validate() - { - hash_table_dtor(this->ht); - } - - virtual ir_visitor_status visit(ir_variable *v); - virtual ir_visitor_status visit(ir_dereference_variable *ir); - virtual ir_visitor_status visit(ir_if *ir); - - virtual ir_visitor_status visit_leave(ir_loop *ir); - virtual ir_visitor_status visit_enter(ir_function *ir); - virtual ir_visitor_status visit_leave(ir_function *ir); - virtual ir_visitor_status visit_enter(ir_function_signature *ir); - - virtual ir_visitor_status visit_leave(ir_expression *ir); - - virtual ir_visitor_status visit_enter(ir_assignment *ir); - - static void validate_ir(ir_instruction *ir, void *data); - - ir_function *current_function; - - struct hash_table *ht; -}; - - -ir_visitor_status -ir_validate::visit(ir_dereference_variable *ir) -{ - if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) { - printf("ir_dereference_variable @ %p does not specify a variable %p\n", - (void *) ir, (void *) ir->var); - abort(); - } - - if (hash_table_find(ht, ir->var) == NULL) { - printf("ir_dereference_variable @ %p specifies undeclared variable " - "`%s' @ %p\n", - (void *) ir, ir->var->name, (void *) ir->var); - abort(); - } - - this->validate_ir(ir, this->data); - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit(ir_if *ir) -{ - if (ir->condition->type != glsl_type::bool_type) { - printf("ir_if condition %s type instead of bool.\n", - ir->condition->type->name); - ir->print(); - printf("\n"); - abort(); - } - - return visit_continue; -} - - -ir_visitor_status -ir_validate::visit_leave(ir_loop *ir) -{ - if (ir->counter != NULL) { - if ((ir->from == NULL) || (ir->from == NULL) || (ir->increment == NULL)) { - printf("ir_loop has invalid loop controls:\n" - " counter: %p\n" - " from: %p\n" - " to: %p\n" - " increment: %p\n", - (void *) ir->counter, (void *) ir->from, (void *) ir->to, - (void *) ir->increment); - abort(); - } - - if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) { - printf("ir_loop has invalid comparitor %d\n", ir->cmp); - abort(); - } - } else { - if ((ir->from != NULL) || (ir->from != NULL) || (ir->increment != NULL)) { - printf("ir_loop has invalid loop controls:\n" - " counter: %p\n" - " from: %p\n" - " to: %p\n" - " increment: %p\n", - (void *) ir->counter, (void *) ir->from, (void *) ir->to, - (void *) ir->increment); - abort(); - } - } - - return visit_continue; -} - - -ir_visitor_status -ir_validate::visit_enter(ir_function *ir) -{ - /* Function definitions cannot be nested. - */ - if (this->current_function != NULL) { - printf("Function definition nested inside another function " - "definition:\n"); - printf("%s %p inside %s %p\n", - ir->name, (void *) ir, - this->current_function->name, (void *) this->current_function); - abort(); - } - - /* Store the current function hierarchy being traversed. This is used - * by the function signature visitor to ensure that the signatures are - * linked with the correct functions. - */ - this->current_function = ir; - - this->validate_ir(ir, this->data); - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_leave(ir_function *ir) -{ - assert(talloc_parent(ir->name) == ir); - - this->current_function = NULL; - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_enter(ir_function_signature *ir) -{ - if (this->current_function != ir->function()) { - printf("Function signature nested inside wrong function " - "definition:\n"); - printf("%p inside %s %p instead of %s %p\n", - (void *) ir, - this->current_function->name, (void *) this->current_function, - ir->function_name(), (void *) ir->function()); - abort(); - } - - this->validate_ir(ir, this->data); - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_leave(ir_expression *ir) -{ - switch (ir->operation) { - case ir_unop_bit_not: - assert(ir->operands[0]->type == ir->type); - break; - case ir_unop_logic_not: - assert(ir->type->base_type == GLSL_TYPE_BOOL); - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - break; - - case ir_unop_neg: - case ir_unop_abs: - case ir_unop_sign: - case ir_unop_rcp: - case ir_unop_rsq: - case ir_unop_sqrt: - assert(ir->type == ir->operands[0]->type); - break; - - case ir_unop_exp: - case ir_unop_log: - case ir_unop_exp2: - case ir_unop_log2: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type == ir->operands[0]->type); - break; - - case ir_unop_f2i: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type->base_type == GLSL_TYPE_INT); - break; - case ir_unop_i2f: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); - assert(ir->type->base_type == GLSL_TYPE_FLOAT); - break; - case ir_unop_f2b: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type->base_type == GLSL_TYPE_BOOL); - break; - case ir_unop_b2f: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type->base_type == GLSL_TYPE_FLOAT); - break; - case ir_unop_i2b: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); - assert(ir->type->base_type == GLSL_TYPE_BOOL); - break; - case ir_unop_b2i: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type->base_type == GLSL_TYPE_INT); - break; - case ir_unop_u2f: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); - assert(ir->type->base_type == GLSL_TYPE_FLOAT); - break; - - case ir_unop_any: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type == glsl_type::bool_type); - break; - - case ir_unop_trunc: - case ir_unop_ceil: - case ir_unop_floor: - case ir_unop_fract: - case ir_unop_sin: - case ir_unop_cos: - case ir_unop_dFdx: - case ir_unop_dFdy: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->operands[0]->type == ir->type); - break; - - case ir_unop_noise: - /* XXX what can we assert here? */ - break; - - case ir_binop_add: - case ir_binop_sub: - case ir_binop_mul: - case ir_binop_div: - case ir_binop_mod: - case ir_binop_min: - case ir_binop_max: - case ir_binop_pow: - if (ir->operands[0]->type->is_scalar()) - assert(ir->operands[1]->type == ir->type); - else if (ir->operands[1]->type->is_scalar()) - assert(ir->operands[0]->type == ir->type); - else if (ir->operands[0]->type->is_vector() && - ir->operands[1]->type->is_vector()) { - assert(ir->operands[0]->type == ir->operands[1]->type); - assert(ir->operands[0]->type == ir->type); - } - break; - - case ir_binop_less: - case ir_binop_greater: - case ir_binop_lequal: - case ir_binop_gequal: - case ir_binop_equal: - case ir_binop_nequal: - /* The semantics of the IR operators differ from the GLSL <, >, <=, >=, - * ==, and != operators. The IR operators perform a component-wise - * comparison on scalar or vector types and return a boolean scalar or - * vector type of the same size. - */ - assert(ir->type->base_type == GLSL_TYPE_BOOL); - assert(ir->operands[0]->type == ir->operands[1]->type); - assert(ir->operands[0]->type->is_vector() - || ir->operands[0]->type->is_scalar()); - assert(ir->operands[0]->type->vector_elements - == ir->type->vector_elements); - break; - - case ir_binop_all_equal: - case ir_binop_any_nequal: - /* GLSL == and != operate on scalars, vectors, matrices and arrays, and - * return a scalar boolean. The IR matches that. - */ - assert(ir->type == glsl_type::bool_type); - assert(ir->operands[0]->type == ir->operands[1]->type); - break; - - case ir_binop_lshift: - case ir_binop_rshift: - case ir_binop_bit_and: - case ir_binop_bit_xor: - case ir_binop_bit_or: - assert(ir->operands[0]->type == ir->operands[1]->type); - assert(ir->type == ir->operands[0]->type); - assert(ir->type->base_type == GLSL_TYPE_INT || - ir->type->base_type == GLSL_TYPE_UINT); - break; - - case ir_binop_logic_and: - case ir_binop_logic_xor: - case ir_binop_logic_or: - assert(ir->type == glsl_type::bool_type); - assert(ir->operands[0]->type == glsl_type::bool_type); - assert(ir->operands[1]->type == glsl_type::bool_type); - break; - - case ir_binop_dot: - assert(ir->type == glsl_type::float_type); - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->operands[0]->type->is_vector()); - assert(ir->operands[0]->type == ir->operands[1]->type); - break; - - case ir_binop_cross: - assert(ir->operands[0]->type == glsl_type::vec3_type); - assert(ir->operands[1]->type == glsl_type::vec3_type); - assert(ir->type == glsl_type::vec3_type); - break; - } - - return visit_continue; -} - -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. It is added to the hashtable so that it can be used - * in the ir_dereference_variable handler to ensure that a variable is - * declared before it is dereferenced. - */ - if (ir->name) - assert(talloc_parent(ir->name) == ir); - - hash_table_insert(ht, ir, ir); - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_enter(ir_assignment *ir) -{ - const ir_dereference *const lhs = ir->lhs; - if (lhs->type->is_scalar() || lhs->type->is_vector()) { - if (ir->write_mask == 0) { - printf("Assignment LHS is %s, but write mask is 0:\n", - lhs->type->is_scalar() ? "scalar" : "vector"); - ir->print(); - abort(); - } - - int lhs_components = 0; - for (int i = 0; i < 4; i++) { - if (ir->write_mask & (1 << i)) - lhs_components++; - } - - if (lhs_components != ir->rhs->type->vector_elements) { - printf("Assignment count of LHS write mask channels enabled not\n" - "matching RHS vector size (%d LHS, %d RHS).\n", - lhs_components, ir->rhs->type->vector_elements); - ir->print(); - abort(); - } - } - - this->validate_ir(ir, this->data); - - 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 -check_node_type(ir_instruction *ir, void *data) -{ - (void) data; - - if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) { - printf("Instruction node with unset type\n"); - ir->print(); printf("\n"); - } - assert(ir->type != glsl_type::error_type); -} - -void -validate_ir_tree(exec_list *instructions) -{ - ir_validate v; - - v.run(instructions); - - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - - visit_tree(ir, check_node_type, 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 "program/hash_table.h"
+#include "glsl_types.h"
+
+class ir_validate : public ir_hierarchical_visitor {
+public:
+ ir_validate()
+ {
+ this->ht = hash_table_ctor(0, hash_table_pointer_hash,
+ hash_table_pointer_compare);
+
+ this->current_function = NULL;
+
+ this->callback = ir_validate::validate_ir;
+ this->data = ht;
+ }
+
+ ~ir_validate()
+ {
+ hash_table_dtor(this->ht);
+ }
+
+ virtual ir_visitor_status visit(ir_variable *v);
+ virtual ir_visitor_status visit(ir_dereference_variable *ir);
+ virtual ir_visitor_status visit(ir_if *ir);
+
+ virtual ir_visitor_status visit_leave(ir_loop *ir);
+ virtual ir_visitor_status visit_enter(ir_function *ir);
+ virtual ir_visitor_status visit_leave(ir_function *ir);
+ virtual ir_visitor_status visit_enter(ir_function_signature *ir);
+
+ virtual ir_visitor_status visit_leave(ir_expression *ir);
+ virtual ir_visitor_status visit_leave(ir_swizzle *ir);
+
+ virtual ir_visitor_status visit_enter(ir_assignment *ir);
+
+ static void validate_ir(ir_instruction *ir, void *data);
+
+ ir_function *current_function;
+
+ struct hash_table *ht;
+};
+
+
+ir_visitor_status
+ir_validate::visit(ir_dereference_variable *ir)
+{
+ if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) {
+ printf("ir_dereference_variable @ %p does not specify a variable %p\n",
+ (void *) ir, (void *) ir->var);
+ abort();
+ }
+
+ if (hash_table_find(ht, ir->var) == NULL) {
+ printf("ir_dereference_variable @ %p specifies undeclared variable "
+ "`%s' @ %p\n",
+ (void *) ir, ir->var->name, (void *) ir->var);
+ abort();
+ }
+
+ this->validate_ir(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit(ir_if *ir)
+{
+ if (ir->condition->type != glsl_type::bool_type) {
+ printf("ir_if condition %s type instead of bool.\n",
+ ir->condition->type->name);
+ ir->print();
+ printf("\n");
+ abort();
+ }
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+ir_validate::visit_leave(ir_loop *ir)
+{
+ if (ir->counter != NULL) {
+ if ((ir->from == NULL) || (ir->from == NULL) || (ir->increment == NULL)) {
+ printf("ir_loop has invalid loop controls:\n"
+ " counter: %p\n"
+ " from: %p\n"
+ " to: %p\n"
+ " increment: %p\n",
+ (void *) ir->counter, (void *) ir->from, (void *) ir->to,
+ (void *) ir->increment);
+ abort();
+ }
+
+ if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) {
+ printf("ir_loop has invalid comparitor %d\n", ir->cmp);
+ abort();
+ }
+ } else {
+ if ((ir->from != NULL) || (ir->from != NULL) || (ir->increment != NULL)) {
+ printf("ir_loop has invalid loop controls:\n"
+ " counter: %p\n"
+ " from: %p\n"
+ " to: %p\n"
+ " increment: %p\n",
+ (void *) ir->counter, (void *) ir->from, (void *) ir->to,
+ (void *) ir->increment);
+ abort();
+ }
+ }
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+ir_validate::visit_enter(ir_function *ir)
+{
+ /* Function definitions cannot be nested.
+ */
+ if (this->current_function != NULL) {
+ printf("Function definition nested inside another function "
+ "definition:\n");
+ printf("%s %p inside %s %p\n",
+ ir->name, (void *) ir,
+ this->current_function->name, (void *) this->current_function);
+ abort();
+ }
+
+ /* Store the current function hierarchy being traversed. This is used
+ * by the function signature visitor to ensure that the signatures are
+ * linked with the correct functions.
+ */
+ this->current_function = ir;
+
+ this->validate_ir(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit_leave(ir_function *ir)
+{
+ assert(talloc_parent(ir->name) == ir);
+
+ this->current_function = NULL;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit_enter(ir_function_signature *ir)
+{
+ if (this->current_function != ir->function()) {
+ printf("Function signature nested inside wrong function "
+ "definition:\n");
+ printf("%p inside %s %p instead of %s %p\n",
+ (void *) ir,
+ this->current_function->name, (void *) this->current_function,
+ ir->function_name(), (void *) ir->function());
+ abort();
+ }
+
+ this->validate_ir(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit_leave(ir_expression *ir)
+{
+ switch (ir->operation) {
+ case ir_unop_bit_not:
+ assert(ir->operands[0]->type == ir->type);
+ break;
+ case ir_unop_logic_not:
+ assert(ir->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
+ break;
+
+ case ir_unop_neg:
+ case ir_unop_abs:
+ case ir_unop_sign:
+ case ir_unop_rcp:
+ case ir_unop_rsq:
+ case ir_unop_sqrt:
+ assert(ir->type == ir->operands[0]->type);
+ break;
+
+ case ir_unop_exp:
+ case ir_unop_log:
+ case ir_unop_exp2:
+ case ir_unop_log2:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(ir->type == ir->operands[0]->type);
+ break;
+
+ case ir_unop_f2i:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(ir->type->base_type == GLSL_TYPE_INT);
+ break;
+ case ir_unop_i2f:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+ assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+ break;
+ case ir_unop_f2b:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(ir->type->base_type == GLSL_TYPE_BOOL);
+ break;
+ case ir_unop_b2f:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+ break;
+ case ir_unop_i2b:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+ assert(ir->type->base_type == GLSL_TYPE_BOOL);
+ break;
+ case ir_unop_b2i:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->type->base_type == GLSL_TYPE_INT);
+ break;
+ case ir_unop_u2f:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+ assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+ break;
+
+ case ir_unop_any:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->type == glsl_type::bool_type);
+ break;
+
+ case ir_unop_trunc:
+ case ir_unop_round_even:
+ case ir_unop_ceil:
+ case ir_unop_floor:
+ case ir_unop_fract:
+ case ir_unop_sin:
+ case ir_unop_cos:
+ case ir_unop_sin_reduced:
+ case ir_unop_cos_reduced:
+ case ir_unop_dFdx:
+ case ir_unop_dFdy:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(ir->operands[0]->type == ir->type);
+ break;
+
+ case ir_unop_noise:
+ /* XXX what can we assert here? */
+ break;
+
+ case ir_binop_add:
+ case ir_binop_sub:
+ case ir_binop_mul:
+ case ir_binop_div:
+ case ir_binop_mod:
+ case ir_binop_min:
+ case ir_binop_max:
+ case ir_binop_pow:
+ if (ir->operands[0]->type->is_scalar())
+ assert(ir->operands[1]->type == ir->type);
+ else if (ir->operands[1]->type->is_scalar())
+ assert(ir->operands[0]->type == ir->type);
+ else if (ir->operands[0]->type->is_vector() &&
+ ir->operands[1]->type->is_vector()) {
+ assert(ir->operands[0]->type == ir->operands[1]->type);
+ assert(ir->operands[0]->type == ir->type);
+ }
+ break;
+
+ case ir_binop_less:
+ case ir_binop_greater:
+ case ir_binop_lequal:
+ case ir_binop_gequal:
+ case ir_binop_equal:
+ case ir_binop_nequal:
+ /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
+ * ==, and != operators. The IR operators perform a component-wise
+ * comparison on scalar or vector types and return a boolean scalar or
+ * vector type of the same size.
+ */
+ assert(ir->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->operands[0]->type == ir->operands[1]->type);
+ assert(ir->operands[0]->type->is_vector()
+ || ir->operands[0]->type->is_scalar());
+ assert(ir->operands[0]->type->vector_elements
+ == ir->type->vector_elements);
+ break;
+
+ case ir_binop_all_equal:
+ case ir_binop_any_nequal:
+ /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
+ * return a scalar boolean. The IR matches that.
+ */
+ assert(ir->type == glsl_type::bool_type);
+ assert(ir->operands[0]->type == ir->operands[1]->type);
+ break;
+
+ case ir_binop_lshift:
+ case ir_binop_rshift:
+ assert(ir->operands[0]->type->is_integer() &&
+ ir->operands[1]->type->is_integer());
+ if (ir->operands[0]->type->is_scalar()) {
+ assert(ir->operands[1]->type->is_scalar());
+ }
+ if (ir->operands[0]->type->is_vector() &&
+ ir->operands[1]->type->is_vector()) {
+ assert(ir->operands[0]->type->components() ==
+ ir->operands[1]->type->components());
+ }
+ assert(ir->type == ir->operands[0]->type);
+ break;
+
+ case ir_binop_bit_and:
+ case ir_binop_bit_xor:
+ case ir_binop_bit_or:
+ assert(ir->operands[0]->type->base_type ==
+ ir->operands[1]->type->base_type);
+ assert(ir->type->is_integer());
+ if (ir->operands[0]->type->is_vector() &&
+ ir->operands[1]->type->is_vector()) {
+ assert(ir->operands[0]->type->vector_elements ==
+ ir->operands[1]->type->vector_elements);
+ }
+ break;
+
+ case ir_binop_logic_and:
+ case ir_binop_logic_xor:
+ case ir_binop_logic_or:
+ assert(ir->type == glsl_type::bool_type);
+ assert(ir->operands[0]->type == glsl_type::bool_type);
+ assert(ir->operands[1]->type == glsl_type::bool_type);
+ break;
+
+ case ir_binop_dot:
+ assert(ir->type == glsl_type::float_type);
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(ir->operands[0]->type->is_vector());
+ assert(ir->operands[0]->type == ir->operands[1]->type);
+ break;
+
+ case ir_quadop_vector:
+ /* The vector operator collects some number of scalars and generates a
+ * vector from them.
+ *
+ * - All of the operands must be scalar.
+ * - Number of operands must matche the size of the resulting vector.
+ * - Base type of the operands must match the base type of the result.
+ */
+ assert(ir->type->is_vector());
+ switch (ir->type->vector_elements) {
+ case 2:
+ assert(ir->operands[0]->type->is_scalar());
+ assert(ir->operands[0]->type->base_type == ir->type->base_type);
+ assert(ir->operands[1]->type->is_scalar());
+ assert(ir->operands[1]->type->base_type == ir->type->base_type);
+ assert(ir->operands[2] == NULL);
+ assert(ir->operands[3] == NULL);
+ break;
+ case 3:
+ assert(ir->operands[0]->type->is_scalar());
+ assert(ir->operands[0]->type->base_type == ir->type->base_type);
+ assert(ir->operands[1]->type->is_scalar());
+ assert(ir->operands[1]->type->base_type == ir->type->base_type);
+ assert(ir->operands[2]->type->is_scalar());
+ assert(ir->operands[2]->type->base_type == ir->type->base_type);
+ assert(ir->operands[3] == NULL);
+ break;
+ case 4:
+ assert(ir->operands[0]->type->is_scalar());
+ assert(ir->operands[0]->type->base_type == ir->type->base_type);
+ assert(ir->operands[1]->type->is_scalar());
+ assert(ir->operands[1]->type->base_type == ir->type->base_type);
+ assert(ir->operands[2]->type->is_scalar());
+ assert(ir->operands[2]->type->base_type == ir->type->base_type);
+ assert(ir->operands[3]->type->is_scalar());
+ assert(ir->operands[3]->type->base_type == ir->type->base_type);
+ break;
+ default:
+ /* The is_vector assertion above should prevent execution from ever
+ * getting here.
+ */
+ assert(!"Should not get here.");
+ break;
+ }
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit_leave(ir_swizzle *ir)
+{
+ int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w};
+
+ for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
+ if (chans[i] >= ir->val->type->vector_elements) {
+ printf("ir_swizzle @ %p specifies a channel not present "
+ "in the value.\n", (void *) ir);
+ ir->print();
+ abort();
+ }
+ }
+
+ return visit_continue;
+}
+
+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. It is added to the hashtable so that it can be used
+ * in the ir_dereference_variable handler to ensure that a variable is
+ * declared before it is dereferenced.
+ */
+ if (ir->name)
+ assert(talloc_parent(ir->name) == ir);
+
+ hash_table_insert(ht, ir, ir);
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_validate::visit_enter(ir_assignment *ir)
+{
+ const ir_dereference *const lhs = ir->lhs;
+ if (lhs->type->is_scalar() || lhs->type->is_vector()) {
+ if (ir->write_mask == 0) {
+ printf("Assignment LHS is %s, but write mask is 0:\n",
+ lhs->type->is_scalar() ? "scalar" : "vector");
+ ir->print();
+ abort();
+ }
+
+ int lhs_components = 0;
+ for (int i = 0; i < 4; i++) {
+ if (ir->write_mask & (1 << i))
+ lhs_components++;
+ }
+
+ if (lhs_components != ir->rhs->type->vector_elements) {
+ printf("Assignment count of LHS write mask channels enabled not\n"
+ "matching RHS vector size (%d LHS, %d RHS).\n",
+ lhs_components, ir->rhs->type->vector_elements);
+ ir->print();
+ abort();
+ }
+ }
+
+ this->validate_ir(ir, this->data);
+
+ 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
+check_node_type(ir_instruction *ir, void *data)
+{
+ (void) data;
+
+ if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) {
+ printf("Instruction node with unset type\n");
+ ir->print(); printf("\n");
+ }
+ assert(ir->type != glsl_type::error_type);
+}
+
+void
+validate_ir_tree(exec_list *instructions)
+{
+ ir_validate v;
+
+ v.run(instructions);
+
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+
+ visit_tree(ir, check_node_type, NULL);
+ }
+}
diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp index 1eff740ef..f99632b48 100644 --- a/mesalib/src/glsl/ir_variable.cpp +++ b/mesalib/src/glsl/ir_variable.cpp @@ -1,493 +1,508 @@ -/* - * 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" - -static void generate_ARB_draw_buffers_variables(exec_list *, - struct _mesa_glsl_parse_state *, - bool, _mesa_glsl_parser_targets); - -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, mode); - - switch (var->mode) { - case ir_var_auto: - case ir_var_in: - case ir_var_uniform: - var->read_only = true; - break; - case ir_var_inout: - case ir_var_out: - 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 ir_variable * -add_uniform(exec_list *instructions, - struct _mesa_glsl_parse_state *state, - const char *name, const glsl_type *type) -{ - return add_variable(name, ir_var_uniform, -1, type, instructions, - state->symbols); -} - -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 -add_builtin_constant(exec_list *instructions, - struct _mesa_glsl_parse_state *state, - const char *name, int value) -{ - ir_variable *const var = add_variable(name, ir_var_auto, - -1, glsl_type::int_type, - instructions, state->symbols); - var->constant_value = new(var) ir_constant(value); -} - -/* Several constants in GLSL ES have different names than normal desktop GLSL. - * Therefore, this function should only be called on the ES path. - */ -static void -generate_100ES_uniforms(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - add_builtin_constant(instructions, state, "gl_MaxVertexAttribs", - state->Const.MaxVertexAttribs); - add_builtin_constant(instructions, state, "gl_MaxVertexUniformVectors", - state->Const.MaxVertexUniformComponents); - add_builtin_constant(instructions, state, "gl_MaxVaryingVectors", - state->Const.MaxVaryingFloats / 4); - add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits", - state->Const.MaxVertexTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits", - state->Const.MaxCombinedTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits", - state->Const.MaxTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxFragmentUniformVectors", - state->Const.MaxFragmentUniformComponents); - - add_uniform(instructions, state, "gl_DepthRange", - state->symbols->get_type("gl_DepthRangeParameters")); -} - -static void -generate_110_uniforms(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0 - ; i < Elements(builtin_110_deprecated_uniforms) - ; i++) { - add_builtin_variable(& builtin_110_deprecated_uniforms[i], - instructions, state->symbols); - } - - add_builtin_constant(instructions, state, "gl_MaxLights", - state->Const.MaxLights); - add_builtin_constant(instructions, state, "gl_MaxClipPlanes", - state->Const.MaxClipPlanes); - add_builtin_constant(instructions, state, "gl_MaxTextureUnits", - state->Const.MaxTextureUnits); - add_builtin_constant(instructions, state, "gl_MaxTextureCoords", - state->Const.MaxTextureCoords); - add_builtin_constant(instructions, state, "gl_MaxVertexAttribs", - state->Const.MaxVertexAttribs); - add_builtin_constant(instructions, state, "gl_MaxVertexUniformComponents", - state->Const.MaxVertexUniformComponents); - add_builtin_constant(instructions, state, "gl_MaxVaryingFloats", - state->Const.MaxVaryingFloats); - add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits", - state->Const.MaxVertexTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits", - state->Const.MaxCombinedTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits", - state->Const.MaxTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxFragmentUniformComponents", - state->Const.MaxFragmentUniformComponents); - - const glsl_type *const mat4_array_type = - glsl_type::get_array_instance(glsl_type::mat4_type, - state->Const.MaxTextureCoords); - - add_uniform(instructions, state, "gl_TextureMatrix", mat4_array_type); - add_uniform(instructions, state, "gl_TextureMatrixInverse", mat4_array_type); - add_uniform(instructions, state, "gl_TextureMatrixTranspose", mat4_array_type); - add_uniform(instructions, state, "gl_TextureMatrixInverseTranspose", mat4_array_type); - - add_uniform(instructions, state, "gl_DepthRange", - state->symbols->get_type("gl_DepthRangeParameters")); - - add_uniform(instructions, state, "gl_ClipPlane", - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxClipPlanes)); - add_uniform(instructions, state, "gl_Point", - state->symbols->get_type("gl_PointParameters")); - - const glsl_type *const material_parameters_type = - state->symbols->get_type("gl_MaterialParameters"); - add_uniform(instructions, state, "gl_FrontMaterial", material_parameters_type); - add_uniform(instructions, state, "gl_BackMaterial", material_parameters_type); - - const glsl_type *const light_source_array_type = - glsl_type::get_array_instance(state->symbols->get_type("gl_LightSourceParameters"), state->Const.MaxLights); - - add_uniform(instructions, state, "gl_LightSource", light_source_array_type); - - const glsl_type *const light_model_products_type = - state->symbols->get_type("gl_LightModelProducts"); - add_uniform(instructions, state, "gl_FrontLightModelProduct", - light_model_products_type); - add_uniform(instructions, state, "gl_BackLightModelProduct", - light_model_products_type); - - const glsl_type *const light_products_type = - glsl_type::get_array_instance(state->symbols->get_type("gl_LightProducts"), - state->Const.MaxLights); - add_uniform(instructions, state, "gl_FrontLightProduct", light_products_type); - add_uniform(instructions, state, "gl_BackLightProduct", light_products_type); - - add_uniform(instructions, state, "gl_TextureEnvColor", - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxTextureUnits)); - - const glsl_type *const texcoords_vec4 = - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxTextureCoords); - add_uniform(instructions, state, "gl_EyePlaneS", texcoords_vec4); - add_uniform(instructions, state, "gl_EyePlaneT", texcoords_vec4); - add_uniform(instructions, state, "gl_EyePlaneR", texcoords_vec4); - add_uniform(instructions, state, "gl_EyePlaneQ", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneS", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneT", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneR", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneQ", texcoords_vec4); - - add_uniform(instructions, state, "gl_Fog", - state->symbols->get_type("gl_FogParameters")); -} - -/* This function should only be called for ES, not desktop GL. */ -static void -generate_100ES_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { - add_builtin_variable(& builtin_core_vs_variables[i], - instructions, state->symbols); - } - - generate_100ES_uniforms(instructions, state); - - generate_ARB_draw_buffers_variables(instructions, state, false, - vertex_shader); -} - - -static void -generate_110_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { - add_builtin_variable(& builtin_core_vs_variables[i], - instructions, state->symbols); - } - - for (unsigned i = 0 - ; i < Elements(builtin_110_deprecated_vs_variables) - ; i++) { - add_builtin_variable(& builtin_110_deprecated_vs_variables[i], - instructions, state->symbols); - } - generate_110_uniforms(instructions, state); - - /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: - * - * "As with all arrays, indices used to subscript gl_TexCoord must - * either be an integral constant expressions, or this array must be - * re-declared by the shader with a size. The size can be at most - * gl_MaxTextureCoords. Using indexes close to 0 may aid the - * implementation in preserving varying resources." - */ - const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, 0); - - add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type, - instructions, state->symbols); - - generate_ARB_draw_buffers_variables(instructions, state, false, - vertex_shader); -} - - -static void -generate_120_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - /* GLSL version 1.20 did not add any built-in variables in the vertex - * shader. - */ - generate_110_vs_variables(instructions, state); -} - - -static void -generate_130_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - generate_120_vs_variables(instructions, state); - - for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) { - add_builtin_variable(& builtin_130_vs_variables[i], - instructions, state->symbols); - } - - const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(glsl_type::float_type, - state->Const.MaxClipPlanes); - - /* FINISHME: gl_ClipDistance needs a real location assigned. */ - add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type, - instructions, state->symbols); - -} - - -static void -initialize_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - - switch (state->language_version) { - case 100: - generate_100ES_vs_variables(instructions, state); - break; - case 110: - generate_110_vs_variables(instructions, state); - break; - case 120: - generate_120_vs_variables(instructions, state); - break; - case 130: - generate_130_vs_variables(instructions, state); - break; - } -} - -/* This function should only be called for ES, not desktop GL. */ -static void -generate_100ES_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { - add_builtin_variable(& builtin_core_fs_variables[i], - instructions, state->symbols); - } - - for (unsigned i = 0; i < Elements(builtin_100ES_fs_variables); i++) { - add_builtin_variable(& builtin_100ES_fs_variables[i], - instructions, state->symbols); - } - - generate_100ES_uniforms(instructions, state); - - generate_ARB_draw_buffers_variables(instructions, state, false, - fragment_shader); -} - -static void -generate_110_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { - add_builtin_variable(& builtin_core_fs_variables[i], - instructions, state->symbols); - } - - for (unsigned i = 0; i < Elements(builtin_110_fs_variables); i++) { - add_builtin_variable(& builtin_110_fs_variables[i], - instructions, state->symbols); - } - - for (unsigned i = 0 - ; i < Elements(builtin_110_deprecated_fs_variables) - ; i++) { - add_builtin_variable(& builtin_110_deprecated_fs_variables[i], - instructions, state->symbols); - } - generate_110_uniforms(instructions, state); - - /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: - * - * "As with all arrays, indices used to subscript gl_TexCoord must - * either be an integral constant expressions, or this array must be - * re-declared by the shader with a size. The size can be at most - * gl_MaxTextureCoords. Using indexes close to 0 may aid the - * implementation in preserving varying resources." - */ - const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, 0); - - add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type, - instructions, state->symbols); - - generate_ARB_draw_buffers_variables(instructions, state, false, - fragment_shader); -} - - -static void -generate_ARB_draw_buffers_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state, - bool warn, _mesa_glsl_parser_targets target) -{ - /* gl_MaxDrawBuffers is available in all shader stages. - */ - ir_variable *const mdb = - add_variable("gl_MaxDrawBuffers", ir_var_auto, -1, - glsl_type::int_type, instructions, state->symbols); - - if (warn) - mdb->warn_extension = "GL_ARB_draw_buffers"; - - mdb->constant_value = new(mdb) - ir_constant(int(state->Const.MaxDrawBuffers)); - - - /* gl_FragData is only available in the fragment shader. - */ - if (target == fragment_shader) { - const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxDrawBuffers); - - ir_variable *const fd = - add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0, - vec4_array_type, instructions, state->symbols); - - if (warn) - fd->warn_extension = "GL_ARB_draw_buffers"; - } -} - - -static void -generate_120_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - generate_110_fs_variables(instructions, state); - - for (unsigned i = 0 - ; i < Elements(builtin_120_fs_variables) - ; i++) { - add_builtin_variable(& builtin_120_fs_variables[i], - instructions, state->symbols); - } -} - -static void -generate_130_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - generate_120_fs_variables(instructions, state); - - const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(glsl_type::float_type, - state->Const.MaxClipPlanes); - - /* FINISHME: gl_ClipDistance needs a real location assigned. */ - add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type, - instructions, state->symbols); -} - -static void -initialize_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - - switch (state->language_version) { - case 100: - generate_100ES_fs_variables(instructions, state); - break; - case 110: - generate_110_fs_variables(instructions, state); - break; - case 120: - generate_120_fs_variables(instructions, state); - break; - case 130: - generate_130_fs_variables(instructions, state); - break; - } -} - -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; - } -} +/*
+ * 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"
+
+static void generate_ARB_draw_buffers_variables(exec_list *,
+ struct _mesa_glsl_parse_state *,
+ bool, _mesa_glsl_parser_targets);
+
+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, mode);
+
+ switch (var->mode) {
+ case ir_var_auto:
+ case ir_var_in:
+ case ir_var_uniform:
+ var->read_only = true;
+ break;
+ case ir_var_inout:
+ case ir_var_out:
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ var->location = slot;
+ var->explicit_location = (slot >= 0);
+
+ /* 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);
+ return var;
+}
+
+static ir_variable *
+add_uniform(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state,
+ const char *name, const glsl_type *type)
+{
+ return add_variable(name, ir_var_uniform, -1, type, instructions,
+ state->symbols);
+}
+
+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
+add_builtin_constant(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state,
+ const char *name, int value)
+{
+ ir_variable *const var = add_variable(name, ir_var_auto,
+ -1, glsl_type::int_type,
+ instructions, state->symbols);
+ var->constant_value = new(var) ir_constant(value);
+}
+
+/* Several constants in GLSL ES have different names than normal desktop GLSL.
+ * Therefore, this function should only be called on the ES path.
+ */
+static void
+generate_100ES_uniforms(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ add_builtin_constant(instructions, state, "gl_MaxVertexAttribs",
+ state->Const.MaxVertexAttribs);
+ add_builtin_constant(instructions, state, "gl_MaxVertexUniformVectors",
+ state->Const.MaxVertexUniformComponents);
+ add_builtin_constant(instructions, state, "gl_MaxVaryingVectors",
+ state->Const.MaxVaryingFloats / 4);
+ add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits",
+ state->Const.MaxVertexTextureImageUnits);
+ add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits",
+ state->Const.MaxCombinedTextureImageUnits);
+ add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits",
+ state->Const.MaxTextureImageUnits);
+ add_builtin_constant(instructions, state, "gl_MaxFragmentUniformVectors",
+ state->Const.MaxFragmentUniformComponents);
+
+ add_uniform(instructions, state, "gl_DepthRange",
+ state->symbols->get_type("gl_DepthRangeParameters"));
+}
+
+static void
+generate_110_uniforms(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ for (unsigned i = 0
+ ; i < Elements(builtin_110_deprecated_uniforms)
+ ; i++) {
+ add_builtin_variable(& builtin_110_deprecated_uniforms[i],
+ instructions, state->symbols);
+ }
+
+ add_builtin_constant(instructions, state, "gl_MaxLights",
+ state->Const.MaxLights);
+ add_builtin_constant(instructions, state, "gl_MaxClipPlanes",
+ state->Const.MaxClipPlanes);
+ add_builtin_constant(instructions, state, "gl_MaxTextureUnits",
+ state->Const.MaxTextureUnits);
+ add_builtin_constant(instructions, state, "gl_MaxTextureCoords",
+ state->Const.MaxTextureCoords);
+ add_builtin_constant(instructions, state, "gl_MaxVertexAttribs",
+ state->Const.MaxVertexAttribs);
+ add_builtin_constant(instructions, state, "gl_MaxVertexUniformComponents",
+ state->Const.MaxVertexUniformComponents);
+ add_builtin_constant(instructions, state, "gl_MaxVaryingFloats",
+ state->Const.MaxVaryingFloats);
+ add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits",
+ state->Const.MaxVertexTextureImageUnits);
+ add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits",
+ state->Const.MaxCombinedTextureImageUnits);
+ add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits",
+ state->Const.MaxTextureImageUnits);
+ add_builtin_constant(instructions, state, "gl_MaxFragmentUniformComponents",
+ state->Const.MaxFragmentUniformComponents);
+
+ const glsl_type *const mat4_array_type =
+ glsl_type::get_array_instance(glsl_type::mat4_type,
+ state->Const.MaxTextureCoords);
+
+ add_uniform(instructions, state, "gl_TextureMatrix", mat4_array_type);
+ add_uniform(instructions, state, "gl_TextureMatrixInverse", mat4_array_type);
+ add_uniform(instructions, state, "gl_TextureMatrixTranspose", mat4_array_type);
+ add_uniform(instructions, state, "gl_TextureMatrixInverseTranspose", mat4_array_type);
+
+ add_uniform(instructions, state, "gl_DepthRange",
+ state->symbols->get_type("gl_DepthRangeParameters"));
+
+ add_uniform(instructions, state, "gl_ClipPlane",
+ glsl_type::get_array_instance(glsl_type::vec4_type,
+ state->Const.MaxClipPlanes));
+ add_uniform(instructions, state, "gl_Point",
+ state->symbols->get_type("gl_PointParameters"));
+
+ const glsl_type *const material_parameters_type =
+ state->symbols->get_type("gl_MaterialParameters");
+ add_uniform(instructions, state, "gl_FrontMaterial", material_parameters_type);
+ add_uniform(instructions, state, "gl_BackMaterial", material_parameters_type);
+
+ const glsl_type *const light_source_array_type =
+ glsl_type::get_array_instance(state->symbols->get_type("gl_LightSourceParameters"), state->Const.MaxLights);
+
+ add_uniform(instructions, state, "gl_LightSource", light_source_array_type);
+
+ const glsl_type *const light_model_products_type =
+ state->symbols->get_type("gl_LightModelProducts");
+ add_uniform(instructions, state, "gl_FrontLightModelProduct",
+ light_model_products_type);
+ add_uniform(instructions, state, "gl_BackLightModelProduct",
+ light_model_products_type);
+
+ const glsl_type *const light_products_type =
+ glsl_type::get_array_instance(state->symbols->get_type("gl_LightProducts"),
+ state->Const.MaxLights);
+ add_uniform(instructions, state, "gl_FrontLightProduct", light_products_type);
+ add_uniform(instructions, state, "gl_BackLightProduct", light_products_type);
+
+ add_uniform(instructions, state, "gl_TextureEnvColor",
+ glsl_type::get_array_instance(glsl_type::vec4_type,
+ state->Const.MaxTextureUnits));
+
+ const glsl_type *const texcoords_vec4 =
+ glsl_type::get_array_instance(glsl_type::vec4_type,
+ state->Const.MaxTextureCoords);
+ add_uniform(instructions, state, "gl_EyePlaneS", texcoords_vec4);
+ add_uniform(instructions, state, "gl_EyePlaneT", texcoords_vec4);
+ add_uniform(instructions, state, "gl_EyePlaneR", texcoords_vec4);
+ add_uniform(instructions, state, "gl_EyePlaneQ", texcoords_vec4);
+ add_uniform(instructions, state, "gl_ObjectPlaneS", texcoords_vec4);
+ add_uniform(instructions, state, "gl_ObjectPlaneT", texcoords_vec4);
+ add_uniform(instructions, state, "gl_ObjectPlaneR", texcoords_vec4);
+ add_uniform(instructions, state, "gl_ObjectPlaneQ", texcoords_vec4);
+
+ add_uniform(instructions, state, "gl_Fog",
+ state->symbols->get_type("gl_FogParameters"));
+}
+
+/* This function should only be called for ES, not desktop GL. */
+static void
+generate_100ES_vs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
+ add_builtin_variable(& builtin_core_vs_variables[i],
+ instructions, state->symbols);
+ }
+
+ generate_100ES_uniforms(instructions, state);
+
+ generate_ARB_draw_buffers_variables(instructions, state, false,
+ vertex_shader);
+}
+
+
+static void
+generate_110_vs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
+ add_builtin_variable(& builtin_core_vs_variables[i],
+ instructions, state->symbols);
+ }
+
+ for (unsigned i = 0
+ ; i < Elements(builtin_110_deprecated_vs_variables)
+ ; i++) {
+ add_builtin_variable(& builtin_110_deprecated_vs_variables[i],
+ instructions, state->symbols);
+ }
+ generate_110_uniforms(instructions, state);
+
+ /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "As with all arrays, indices used to subscript gl_TexCoord must
+ * either be an integral constant expressions, or this array must be
+ * re-declared by the shader with a size. The size can be at most
+ * gl_MaxTextureCoords. Using indexes close to 0 may aid the
+ * implementation in preserving varying resources."
+ */
+ const glsl_type *const vec4_array_type =
+ glsl_type::get_array_instance(glsl_type::vec4_type, 0);
+
+ add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type,
+ instructions, state->symbols);
+
+ generate_ARB_draw_buffers_variables(instructions, state, false,
+ vertex_shader);
+}
+
+
+static void
+generate_120_vs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ /* GLSL version 1.20 did not add any built-in variables in the vertex
+ * shader.
+ */
+ generate_110_vs_variables(instructions, state);
+}
+
+
+static void
+generate_130_vs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ generate_120_vs_variables(instructions, state);
+
+ for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) {
+ add_builtin_variable(& builtin_130_vs_variables[i],
+ instructions, state->symbols);
+ }
+
+ const glsl_type *const clip_distance_array_type =
+ glsl_type::get_array_instance(glsl_type::float_type,
+ state->Const.MaxClipPlanes);
+
+ /* FINISHME: gl_ClipDistance needs a real location assigned. */
+ add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type,
+ instructions, state->symbols);
+
+}
+
+
+static void
+initialize_vs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+
+ switch (state->language_version) {
+ case 100:
+ generate_100ES_vs_variables(instructions, state);
+ break;
+ case 110:
+ generate_110_vs_variables(instructions, state);
+ break;
+ case 120:
+ generate_120_vs_variables(instructions, state);
+ break;
+ case 130:
+ generate_130_vs_variables(instructions, state);
+ break;
+ }
+}
+
+/* This function should only be called for ES, not desktop GL. */
+static void
+generate_100ES_fs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
+ add_builtin_variable(& builtin_core_fs_variables[i],
+ instructions, state->symbols);
+ }
+
+ for (unsigned i = 0; i < Elements(builtin_100ES_fs_variables); i++) {
+ add_builtin_variable(& builtin_100ES_fs_variables[i],
+ instructions, state->symbols);
+ }
+
+ generate_100ES_uniforms(instructions, state);
+
+ generate_ARB_draw_buffers_variables(instructions, state, false,
+ fragment_shader);
+}
+
+static void
+generate_110_fs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
+ add_builtin_variable(& builtin_core_fs_variables[i],
+ instructions, state->symbols);
+ }
+
+ for (unsigned i = 0; i < Elements(builtin_110_fs_variables); i++) {
+ add_builtin_variable(& builtin_110_fs_variables[i],
+ instructions, state->symbols);
+ }
+
+ for (unsigned i = 0
+ ; i < Elements(builtin_110_deprecated_fs_variables)
+ ; i++) {
+ add_builtin_variable(& builtin_110_deprecated_fs_variables[i],
+ instructions, state->symbols);
+ }
+ generate_110_uniforms(instructions, state);
+
+ /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "As with all arrays, indices used to subscript gl_TexCoord must
+ * either be an integral constant expressions, or this array must be
+ * re-declared by the shader with a size. The size can be at most
+ * gl_MaxTextureCoords. Using indexes close to 0 may aid the
+ * implementation in preserving varying resources."
+ */
+ const glsl_type *const vec4_array_type =
+ glsl_type::get_array_instance(glsl_type::vec4_type, 0);
+
+ add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type,
+ instructions, state->symbols);
+
+ generate_ARB_draw_buffers_variables(instructions, state, false,
+ fragment_shader);
+}
+
+
+static void
+generate_ARB_draw_buffers_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state,
+ bool warn, _mesa_glsl_parser_targets target)
+{
+ /* gl_MaxDrawBuffers is available in all shader stages.
+ */
+ ir_variable *const mdb =
+ add_variable("gl_MaxDrawBuffers", ir_var_auto, -1,
+ glsl_type::int_type, instructions, state->symbols);
+
+ if (warn)
+ mdb->warn_extension = "GL_ARB_draw_buffers";
+
+ mdb->constant_value = new(mdb)
+ ir_constant(int(state->Const.MaxDrawBuffers));
+
+
+ /* gl_FragData is only available in the fragment shader.
+ */
+ if (target == fragment_shader) {
+ const glsl_type *const vec4_array_type =
+ glsl_type::get_array_instance(glsl_type::vec4_type,
+ state->Const.MaxDrawBuffers);
+
+ ir_variable *const fd =
+ add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0,
+ vec4_array_type, instructions, state->symbols);
+
+ if (warn)
+ fd->warn_extension = "GL_ARB_draw_buffers";
+ }
+}
+
+static void
+generate_ARB_shader_stencil_export_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state,
+ bool warn)
+{
+ /* gl_FragStencilRefARB is only available in the fragment shader.
+ */
+ ir_variable *const fd =
+ add_variable("gl_FragStencilRefARB", ir_var_out, FRAG_RESULT_STENCIL,
+ glsl_type::int_type, instructions, state->symbols);
+
+ if (warn)
+ fd->warn_extension = "GL_ARB_shader_stencil_export";
+}
+
+static void
+generate_120_fs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ generate_110_fs_variables(instructions, state);
+
+ for (unsigned i = 0
+ ; i < Elements(builtin_120_fs_variables)
+ ; i++) {
+ add_builtin_variable(& builtin_120_fs_variables[i],
+ instructions, state->symbols);
+ }
+}
+
+static void
+generate_130_fs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ generate_120_fs_variables(instructions, state);
+
+ const glsl_type *const clip_distance_array_type =
+ glsl_type::get_array_instance(glsl_type::float_type,
+ state->Const.MaxClipPlanes);
+
+ /* FINISHME: gl_ClipDistance needs a real location assigned. */
+ add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type,
+ instructions, state->symbols);
+}
+
+static void
+initialize_fs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+
+ switch (state->language_version) {
+ case 100:
+ generate_100ES_fs_variables(instructions, state);
+ break;
+ case 110:
+ generate_110_fs_variables(instructions, state);
+ break;
+ case 120:
+ generate_120_fs_variables(instructions, state);
+ break;
+ case 130:
+ generate_130_fs_variables(instructions, state);
+ break;
+ }
+
+ if (state->ARB_shader_stencil_export_enable)
+ generate_ARB_shader_stencil_export_variables(instructions, state,
+ state->ARB_shader_stencil_export_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;
+ }
+}
diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp index 78c8b48cf..98aa34a19 100644 --- a/mesalib/src/glsl/link_functions.cpp +++ b/mesalib/src/glsl/link_functions.cpp @@ -1,262 +1,262 @@ -/* - * 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 <cstdlib> -#include <cstdio> -#include <cstdarg> - -extern "C" { -#include <talloc.h> -} - -#include "main/core.h" -#include "glsl_symbol_table.h" -#include "glsl_parser_extras.h" -#include "ir.h" -#include "program.h" -#include "program/hash_table.h" -#include "linker.h" - -static ir_function_signature * -find_matching_signature(const char *name, const exec_list *actual_parameters, - gl_shader **shader_list, unsigned num_shaders); - -class call_link_visitor : public ir_hierarchical_visitor { -public: - call_link_visitor(gl_shader_program *prog, gl_shader *linked, - gl_shader **shader_list, unsigned num_shaders) - { - this->prog = prog; - this->shader_list = shader_list; - this->num_shaders = num_shaders; - this->success = true; - this->linked = linked; - - this->locals = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); - } - - ~call_link_visitor() - { - hash_table_dtor(this->locals); - } - - virtual ir_visitor_status visit(ir_variable *ir) - { - hash_table_insert(locals, ir, ir); - return visit_continue; - } - - virtual ir_visitor_status visit_enter(ir_call *ir) - { - /* If ir is an ir_call from a function that was imported from another - * shader callee will point to an ir_function_signature in the original - * shader. In this case the function signature MUST NOT BE MODIFIED. - * Doing so will modify the original shader. This may prevent that - * shader from being linkable in other programs. - */ - const ir_function_signature *const callee = ir->get_callee(); - assert(callee != NULL); - const char *const name = callee->function_name(); - - /* Determine if the requested function signature already exists in the - * final linked shader. If it does, use it as the target of the call. - */ - ir_function_signature *sig = - find_matching_signature(name, &callee->parameters, &linked, 1); - if (sig != NULL) { - ir->set_callee(sig); - return visit_continue; - } - - /* Try to find the signature in one of the other shaders that is being - * linked. If it's not found there, return an error. - */ - sig = find_matching_signature(name, &ir->actual_parameters, shader_list, - num_shaders); - if (sig == NULL) { - /* FINISHME: Log the full signature of unresolved function. - */ - linker_error_printf(this->prog, "unresolved reference to function " - "`%s'\n", name); - this->success = false; - return visit_stop; - } - - /* Find the prototype information in the linked shader. Generate any - * details that may be missing. - */ - ir_function *f = linked->symbols->get_function(name); - if (f == NULL) - f = new(linked) ir_function(name); - - ir_function_signature *linked_sig = - f->exact_matching_signature(&callee->parameters); - if (linked_sig == NULL) { - linked_sig = new(linked) ir_function_signature(callee->return_type); - f->add_signature(linked_sig); - } - - /* At this point linked_sig and called may be the same. If ir is an - * ir_call from linked then linked_sig and callee will be - * ir_function_signatures that have no definitions (is_defined is false). - */ - assert(!linked_sig->is_defined); - assert(linked_sig->body.is_empty()); - - /* Create an in-place clone of the function definition. This multistep - * process introduces some complexity here, but it has some advantages. - * The parameter list and the and function body are cloned separately. - * The clone of the parameter list is used to prime the hashtable used - * to replace variable references in the cloned body. - * - * The big advantage is that the ir_function_signature does not change. - * This means that we don't have to process the rest of the IR tree to - * patch ir_call nodes. In addition, there is no way to remove or - * replace signature stored in a function. One could easily be added, - * but this avoids the need. - */ - struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); - exec_list formal_parameters; - foreach_list_const(node, &sig->parameters) { - const ir_instruction *const original = (ir_instruction *) node; - assert(const_cast<ir_instruction *>(original)->as_variable()); - - ir_instruction *copy = original->clone(linked, ht); - formal_parameters.push_tail(copy); - } - - linked_sig->replace_parameters(&formal_parameters); - - foreach_list_const(node, &sig->body) { - const ir_instruction *const original = (ir_instruction *) node; - - ir_instruction *copy = original->clone(linked, ht); - linked_sig->body.push_tail(copy); - } - - linked_sig->is_defined = true; - hash_table_dtor(ht); - - /* Patch references inside the function to things outside the function - * (i.e., function calls and global variables). - */ - linked_sig->accept(this); - - ir->set_callee(linked_sig); - - return visit_continue; - } - - virtual ir_visitor_status visit(ir_dereference_variable *ir) - { - if (hash_table_find(locals, ir->var) == NULL) { - /* The non-function variable must be a global, so try to find the - * variable in the shader's symbol table. If the variable is not - * found, then it's a global that *MUST* be defined in the original - * shader. - */ - ir_variable *var = linked->symbols->get_variable(ir->var->name); - if (var == NULL) { - /* Clone the ir_variable that the dereference already has and add - * it to the linked shader. - */ - var = ir->var->clone(linked, NULL); - linked->symbols->add_variable(var->name, var); - linked->ir->push_head(var); - } - - ir->var = var; - } - - return visit_continue; - } - - /** Was function linking successful? */ - bool success; - -private: - /** - * Shader program being linked - * - * This is only used for logging error messages. - */ - gl_shader_program *prog; - - /** List of shaders available for linking. */ - gl_shader **shader_list; - - /** Number of shaders available for linking. */ - unsigned num_shaders; - - /** - * Final linked shader - * - * This is used two ways. It is used to find global variables in the - * linked shader that are accessed by the function. It is also used to add - * global variables from the shader where the function originated. - */ - gl_shader *linked; - - /** - * Table of variables local to the function. - */ - hash_table *locals; -}; - - -/** - * Searches a list of shaders for a particular function definition - */ -ir_function_signature * -find_matching_signature(const char *name, const exec_list *actual_parameters, - gl_shader **shader_list, unsigned num_shaders) -{ - for (unsigned i = 0; i < num_shaders; i++) { - ir_function *const f = shader_list[i]->symbols->get_function(name); - - if (f == NULL) - continue; - - ir_function_signature *sig = f->matching_signature(actual_parameters); - - if ((sig == NULL) || !sig->is_defined) - continue; - - return sig; - } - - return NULL; -} - - -bool -link_function_calls(gl_shader_program *prog, gl_shader *main, - gl_shader **shader_list, unsigned num_shaders) -{ - call_link_visitor v(prog, main, shader_list, num_shaders); - - v.run(main->ir); - return v.success; -} +/*
+ * 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 <cstdlib>
+#include <cstdio>
+#include <cstdarg>
+
+extern "C" {
+#include <talloc.h>
+}
+
+#include "main/core.h"
+#include "glsl_symbol_table.h"
+#include "glsl_parser_extras.h"
+#include "ir.h"
+#include "program.h"
+#include "program/hash_table.h"
+#include "linker.h"
+
+static ir_function_signature *
+find_matching_signature(const char *name, const exec_list *actual_parameters,
+ gl_shader **shader_list, unsigned num_shaders);
+
+class call_link_visitor : public ir_hierarchical_visitor {
+public:
+ call_link_visitor(gl_shader_program *prog, gl_shader *linked,
+ gl_shader **shader_list, unsigned num_shaders)
+ {
+ this->prog = prog;
+ this->shader_list = shader_list;
+ this->num_shaders = num_shaders;
+ this->success = true;
+ this->linked = linked;
+
+ this->locals = hash_table_ctor(0, hash_table_pointer_hash,
+ hash_table_pointer_compare);
+ }
+
+ ~call_link_visitor()
+ {
+ hash_table_dtor(this->locals);
+ }
+
+ virtual ir_visitor_status visit(ir_variable *ir)
+ {
+ hash_table_insert(locals, ir, ir);
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_call *ir)
+ {
+ /* If ir is an ir_call from a function that was imported from another
+ * shader callee will point to an ir_function_signature in the original
+ * shader. In this case the function signature MUST NOT BE MODIFIED.
+ * Doing so will modify the original shader. This may prevent that
+ * shader from being linkable in other programs.
+ */
+ const ir_function_signature *const callee = ir->get_callee();
+ assert(callee != NULL);
+ const char *const name = callee->function_name();
+
+ /* Determine if the requested function signature already exists in the
+ * final linked shader. If it does, use it as the target of the call.
+ */
+ ir_function_signature *sig =
+ find_matching_signature(name, &callee->parameters, &linked, 1);
+ if (sig != NULL) {
+ ir->set_callee(sig);
+ return visit_continue;
+ }
+
+ /* Try to find the signature in one of the other shaders that is being
+ * linked. If it's not found there, return an error.
+ */
+ sig = find_matching_signature(name, &ir->actual_parameters, shader_list,
+ num_shaders);
+ if (sig == NULL) {
+ /* FINISHME: Log the full signature of unresolved function.
+ */
+ linker_error_printf(this->prog, "unresolved reference to function "
+ "`%s'\n", name);
+ this->success = false;
+ return visit_stop;
+ }
+
+ /* Find the prototype information in the linked shader. Generate any
+ * details that may be missing.
+ */
+ ir_function *f = linked->symbols->get_function(name);
+ if (f == NULL)
+ f = new(linked) ir_function(name);
+
+ ir_function_signature *linked_sig =
+ f->exact_matching_signature(&callee->parameters);
+ if (linked_sig == NULL) {
+ linked_sig = new(linked) ir_function_signature(callee->return_type);
+ f->add_signature(linked_sig);
+ }
+
+ /* At this point linked_sig and called may be the same. If ir is an
+ * ir_call from linked then linked_sig and callee will be
+ * ir_function_signatures that have no definitions (is_defined is false).
+ */
+ assert(!linked_sig->is_defined);
+ assert(linked_sig->body.is_empty());
+
+ /* Create an in-place clone of the function definition. This multistep
+ * process introduces some complexity here, but it has some advantages.
+ * The parameter list and the and function body are cloned separately.
+ * The clone of the parameter list is used to prime the hashtable used
+ * to replace variable references in the cloned body.
+ *
+ * The big advantage is that the ir_function_signature does not change.
+ * This means that we don't have to process the rest of the IR tree to
+ * patch ir_call nodes. In addition, there is no way to remove or
+ * replace signature stored in a function. One could easily be added,
+ * but this avoids the need.
+ */
+ struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash,
+ hash_table_pointer_compare);
+ exec_list formal_parameters;
+ foreach_list_const(node, &sig->parameters) {
+ const ir_instruction *const original = (ir_instruction *) node;
+ assert(const_cast<ir_instruction *>(original)->as_variable());
+
+ ir_instruction *copy = original->clone(linked, ht);
+ formal_parameters.push_tail(copy);
+ }
+
+ linked_sig->replace_parameters(&formal_parameters);
+
+ foreach_list_const(node, &sig->body) {
+ const ir_instruction *const original = (ir_instruction *) node;
+
+ ir_instruction *copy = original->clone(linked, ht);
+ linked_sig->body.push_tail(copy);
+ }
+
+ linked_sig->is_defined = true;
+ hash_table_dtor(ht);
+
+ /* Patch references inside the function to things outside the function
+ * (i.e., function calls and global variables).
+ */
+ linked_sig->accept(this);
+
+ ir->set_callee(linked_sig);
+
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ if (hash_table_find(locals, ir->var) == NULL) {
+ /* The non-function variable must be a global, so try to find the
+ * variable in the shader's symbol table. If the variable is not
+ * found, then it's a global that *MUST* be defined in the original
+ * shader.
+ */
+ ir_variable *var = linked->symbols->get_variable(ir->var->name);
+ if (var == NULL) {
+ /* Clone the ir_variable that the dereference already has and add
+ * it to the linked shader.
+ */
+ var = ir->var->clone(linked, NULL);
+ linked->symbols->add_variable(var);
+ linked->ir->push_head(var);
+ }
+
+ ir->var = var;
+ }
+
+ return visit_continue;
+ }
+
+ /** Was function linking successful? */
+ bool success;
+
+private:
+ /**
+ * Shader program being linked
+ *
+ * This is only used for logging error messages.
+ */
+ gl_shader_program *prog;
+
+ /** List of shaders available for linking. */
+ gl_shader **shader_list;
+
+ /** Number of shaders available for linking. */
+ unsigned num_shaders;
+
+ /**
+ * Final linked shader
+ *
+ * This is used two ways. It is used to find global variables in the
+ * linked shader that are accessed by the function. It is also used to add
+ * global variables from the shader where the function originated.
+ */
+ gl_shader *linked;
+
+ /**
+ * Table of variables local to the function.
+ */
+ hash_table *locals;
+};
+
+
+/**
+ * Searches a list of shaders for a particular function definition
+ */
+ir_function_signature *
+find_matching_signature(const char *name, const exec_list *actual_parameters,
+ gl_shader **shader_list, unsigned num_shaders)
+{
+ for (unsigned i = 0; i < num_shaders; i++) {
+ ir_function *const f = shader_list[i]->symbols->get_function(name);
+
+ if (f == NULL)
+ continue;
+
+ ir_function_signature *sig = f->matching_signature(actual_parameters);
+
+ if ((sig == NULL) || !sig->is_defined)
+ continue;
+
+ return sig;
+ }
+
+ return NULL;
+}
+
+
+bool
+link_function_calls(gl_shader_program *prog, gl_shader *main,
+ gl_shader **shader_list, unsigned num_shaders)
+{
+ call_link_visitor v(prog, main, shader_list, num_shaders);
+
+ v.run(main->ir);
+ return v.success;
+}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 4bb4e2a99..0ef051965 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1,1505 +1,1674 @@ -/* - * 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> -#include <climits> - -extern "C" { -#include <talloc.h> -} - -#include "main/core.h" -#include "glsl_symbol_table.h" -#include "ir.h" -#include "program.h" -#include "program/hash_table.h" -#include "linker.h" -#include "ir_optimization.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; - } - - virtual ir_visitor_status visit_enter(ir_call *ir) - { - exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *sig_param = (ir_variable *)sig_iter.get(); - - if (sig_param->mode == ir_var_out || - sig_param->mode == ir_var_inout) { - ir_variable *var = param_rval->variable_referenced(); - if (var && strcmp(name, var->name) == 0) { - found = true; - return visit_stop; - } - } - sig_iter.next(); - } - - 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? */ -}; - - -/** - * Visitor that determines whether or not a variable is ever read. - */ -class find_deref_visitor : public ir_hierarchical_visitor { -public: - find_deref_visitor(const char *name) - : name(name), found(false) - { - /* empty */ - } - - virtual ir_visitor_status visit(ir_dereference_variable *ir) - { - if (strcmp(this->name, ir->var->name) == 0) { - this->found = true; - return visit_stop; - } - - return visit_continue; - } - - bool variable_found() const - { - return this->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(gl_shader_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(gl_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 gl_shader_program *prog, - struct gl_shader *shader) -{ - if (shader == NULL) - return true; - - 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 gl_shader_program *prog, - struct gl_shader *shader) -{ - if (shader == NULL) - return true; - - 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 writes to both " - "`gl_FragColor' and `gl_FragData'\n"); - return false; - } - - return true; -} - - -/** - * Generate a string describing the mode of a variable - */ -static const char * -mode_string(const ir_variable *var) -{ - switch (var->mode) { - case ir_var_auto: - return (var->read_only) ? "global constant" : "global variable"; - - case ir_var_uniform: return "uniform"; - case ir_var_in: return "shader input"; - case ir_var_out: return "shader output"; - case ir_var_inout: return "shader inout"; - - case ir_var_temporary: - default: - assert(!"Should not get here."); - return "invalid variable"; - } -} - - -/** - * Perform validation of global variables used across multiple shaders - */ -bool -cross_validate_globals(struct gl_shader_program *prog, - struct gl_shader **shader_list, - unsigned num_shaders, - bool uniforms_only) -{ - /* Examine all of the uniforms in all of the shaders and cross validate - * them. - */ - glsl_symbol_table variables; - for (unsigned i = 0; i < num_shaders; i++) { - foreach_list(node, shader_list[i]->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); - - if (var == NULL) - continue; - - if (uniforms_only && (var->mode != ir_var_uniform)) - continue; - - /* Don't cross validate temporaries that are at global scope. These - * will eventually get pulled into the shaders 'main'. - */ - if (var->mode == ir_var_temporary) - continue; - - /* If a global with this name has already been seen, verify that the - * new instance has the same type. In addition, if the globals have - * initializers, the values of the initializers must be the same. - */ - ir_variable *const existing = variables.get_variable(var->name); - if (existing != NULL) { - if (var->type != existing->type) { - /* Consider the types to be "the same" if both types are arrays - * of the same type and one of the arrays is implicitly sized. - * In addition, set the type of the linked variable to the - * explicitly sized array. - */ - if (var->type->is_array() - && existing->type->is_array() - && (var->type->fields.array == existing->type->fields.array) - && ((var->type->length == 0) - || (existing->type->length == 0))) { - if (existing->type->length == 0) - existing->type = var->type; - } else { - linker_error_printf(prog, "%s `%s' declared as type " - "`%s' and type `%s'\n", - mode_string(var), - var->name, var->type->name, - existing->type->name); - return false; - } - } - - /* FINISHME: Handle non-constant initializers. - */ - 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 %s " - "`%s' have differing values\n", - mode_string(var), 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. - */ - /* FINISHME: This is wrong. The constant_value field should - * FINISHME: not be modified! Imagine a case where a shader - * FINISHME: without an initializer is linked in two different - * FINISHME: programs with shaders that have differing - * FINISHME: initializers. Linking with the first will - * FINISHME: modify the shader, and linking with the second - * FINISHME: will fail. - */ - existing->constant_value = - var->constant_value->clone(talloc_parent(existing), NULL); - } - } else - variables.add_variable(var->name, var); - } - } - - return true; -} - - -/** - * Perform validation of uniforms used across multiple shader stages - */ -bool -cross_validate_uniforms(struct gl_shader_program *prog) -{ - return cross_validate_globals(prog, prog->_LinkedShaders, - prog->_NumLinkedShaders, true); -} - - -/** - * Validate that outputs from one stage match inputs of another - */ -bool -cross_validate_outputs_to_inputs(struct gl_shader_program *prog, - gl_shader *producer, gl_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' declared 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; -} - - -/** - * Populates a shaders symbol table with all global declarations - */ -static void -populate_symbol_table(gl_shader *sh) -{ - sh->symbols = new(sh) glsl_symbol_table; - - foreach_list(node, sh->ir) { - ir_instruction *const inst = (ir_instruction *) node; - ir_variable *var; - ir_function *func; - - if ((func = inst->as_function()) != NULL) { - sh->symbols->add_function(func->name, func); - } else if ((var = inst->as_variable()) != NULL) { - sh->symbols->add_variable(var->name, var); - } - } -} - - -/** - * Remap variables referenced in an instruction tree - * - * This is used when instruction trees are cloned from one shader and placed in - * another. These trees will contain references to \c ir_variable nodes that - * do not exist in the target shader. This function finds these \c ir_variable - * references and replaces the references with matching variables in the target - * shader. - * - * If there is no matching variable in the target shader, a clone of the - * \c ir_variable is made and added to the target shader. The new variable is - * added to \b both the instruction stream and the symbol table. - * - * \param inst IR tree that is to be processed. - * \param symbols Symbol table containing global scope symbols in the - * linked shader. - * \param instructions Instruction stream where new variable declarations - * should be added. - */ -void -remap_variables(ir_instruction *inst, struct gl_shader *target, - hash_table *temps) -{ - class remap_visitor : public ir_hierarchical_visitor { - public: - remap_visitor(struct gl_shader *target, - hash_table *temps) - { - this->target = target; - this->symbols = target->symbols; - this->instructions = target->ir; - this->temps = temps; - } - - virtual ir_visitor_status visit(ir_dereference_variable *ir) - { - if (ir->var->mode == ir_var_temporary) { - ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var); - - assert(var != NULL); - ir->var = var; - return visit_continue; - } - - ir_variable *const existing = - this->symbols->get_variable(ir->var->name); - if (existing != NULL) - ir->var = existing; - else { - ir_variable *copy = ir->var->clone(this->target, NULL); - - this->symbols->add_variable(copy->name, copy); - this->instructions->push_head(copy); - ir->var = copy; - } - - return visit_continue; - } - - private: - struct gl_shader *target; - glsl_symbol_table *symbols; - exec_list *instructions; - hash_table *temps; - }; - - remap_visitor v(target, temps); - - inst->accept(&v); -} - - -/** - * Move non-declarations from one instruction stream to another - * - * The intended usage pattern of this function is to pass the pointer to the - * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node - * pointer) for \c last and \c false for \c make_copies on the first - * call. Successive calls pass the return value of the previous call for - * \c last and \c true for \c make_copies. - * - * \param instructions Source instruction stream - * \param last Instruction after which new instructions should be - * inserted in the target instruction stream - * \param make_copies Flag selecting whether instructions in \c instructions - * should be copied (via \c ir_instruction::clone) into the - * target list or moved. - * - * \return - * The new "last" instruction in the target instruction stream. This pointer - * is suitable for use as the \c last parameter of a later call to this - * function. - */ -exec_node * -move_non_declarations(exec_list *instructions, exec_node *last, - bool make_copies, gl_shader *target) -{ - hash_table *temps = NULL; - - if (make_copies) - temps = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); - - foreach_list_safe(node, instructions) { - ir_instruction *inst = (ir_instruction *) node; - - if (inst->as_function()) - continue; - - ir_variable *var = inst->as_variable(); - if ((var != NULL) && (var->mode != ir_var_temporary)) - continue; - - assert(inst->as_assignment() - || ((var != NULL) && (var->mode == ir_var_temporary))); - - if (make_copies) { - inst = inst->clone(target, NULL); - - if (var != NULL) - hash_table_insert(temps, inst, var); - else - remap_variables(inst, target, temps); - } else { - inst->remove(); - } - - last->insert_after(inst); - last = inst; - } - - if (make_copies) - hash_table_dtor(temps); - - return last; -} - -/** - * Get the function signature for main from a shader - */ -static ir_function_signature * -get_main_function_signature(gl_shader *sh) -{ - ir_function *const f = sh->symbols->get_function("main"); - if (f != NULL) { - exec_list void_parameters; - - /* Look for the 'void main()' signature and ensure that it's defined. - * This keeps the linker from accidentally pick a shader that just - * contains a prototype for main. - * - * We don't have to check for multiple definitions of main (in multiple - * shaders) because that would have already been caught above. - */ - ir_function_signature *sig = f->matching_signature(&void_parameters); - if ((sig != NULL) && sig->is_defined) { - return sig; - } - } - - return NULL; -} - - -/** - * Combine a group of shaders for a single stage to generate a linked shader - * - * \note - * If this function is supplied a single shader, it is cloned, and the new - * shader is returned. - */ -static struct gl_shader * -link_intrastage_shaders(GLcontext *ctx, - struct gl_shader_program *prog, - struct gl_shader **shader_list, - unsigned num_shaders) -{ - /* Check that global variables defined in multiple shaders are consistent. - */ - if (!cross_validate_globals(prog, shader_list, num_shaders, false)) - return NULL; - - /* Check that there is only a single definition of each function signature - * across all shaders. - */ - for (unsigned i = 0; i < (num_shaders - 1); i++) { - foreach_list(node, shader_list[i]->ir) { - ir_function *const f = ((ir_instruction *) node)->as_function(); - - if (f == NULL) - continue; - - for (unsigned j = i + 1; j < num_shaders; j++) { - ir_function *const other = - shader_list[j]->symbols->get_function(f->name); - - /* If the other shader has no function (and therefore no function - * signatures) with the same name, skip to the next shader. - */ - if (other == NULL) - continue; - - foreach_iter (exec_list_iterator, iter, *f) { - ir_function_signature *sig = - (ir_function_signature *) iter.get(); - - if (!sig->is_defined || sig->is_builtin) - continue; - - ir_function_signature *other_sig = - other->exact_matching_signature(& sig->parameters); - - if ((other_sig != NULL) && other_sig->is_defined - && !other_sig->is_builtin) { - linker_error_printf(prog, - "function `%s' is multiply defined", - f->name); - return NULL; - } - } - } - } - } - - /* Find the shader that defines main, and make a clone of it. - * - * Starting with the clone, search for undefined references. If one is - * found, find the shader that defines it. Clone the reference and add - * it to the shader. Repeat until there are no undefined references or - * until a reference cannot be resolved. - */ - gl_shader *main = NULL; - for (unsigned i = 0; i < num_shaders; i++) { - if (get_main_function_signature(shader_list[i]) != NULL) { - main = shader_list[i]; - break; - } - } - - if (main == NULL) { - linker_error_printf(prog, "%s shader lacks `main'\n", - (shader_list[0]->Type == GL_VERTEX_SHADER) - ? "vertex" : "fragment"); - return NULL; - } - - gl_shader *const linked = ctx->Driver.NewShader(NULL, 0, main->Type); - linked->ir = new(linked) exec_list; - clone_ir_list(linked, linked->ir, main->ir); - - populate_symbol_table(linked); - - /* The a pointer to the main function in the final linked shader (i.e., the - * copy of the original shader that contained the main function). - */ - ir_function_signature *const main_sig = get_main_function_signature(linked); - - /* Move any instructions other than variable declarations or function - * declarations into main. - */ - exec_node *insertion_point = - move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false, - linked); - - for (unsigned i = 0; i < num_shaders; i++) { - if (shader_list[i] == main) - continue; - - insertion_point = move_non_declarations(shader_list[i]->ir, - insertion_point, true, linked); - } - - /* Resolve initializers for global variables in the linked shader. - */ - unsigned num_linking_shaders = num_shaders; - for (unsigned i = 0; i < num_shaders; i++) - num_linking_shaders += shader_list[i]->num_builtins_to_link; - - gl_shader **linking_shaders = - (gl_shader **) calloc(num_linking_shaders, sizeof(gl_shader *)); - - memcpy(linking_shaders, shader_list, - sizeof(linking_shaders[0]) * num_shaders); - - unsigned idx = num_shaders; - for (unsigned i = 0; i < num_shaders; i++) { - memcpy(&linking_shaders[idx], shader_list[i]->builtins_to_link, - sizeof(linking_shaders[0]) * shader_list[i]->num_builtins_to_link); - idx += shader_list[i]->num_builtins_to_link; - } - - assert(idx == num_linking_shaders); - - link_function_calls(prog, linked, linking_shaders, num_linking_shaders); - - free(linking_shaders); - - return linked; -} - - -struct uniform_node { - exec_node link; - struct gl_uniform *u; - unsigned slots; -}; - -/** - * Update the sizes of linked shader uniform arrays to the maximum - * array index used. - * - * From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec: - * - * If one or more elements of an array are active, - * GetActiveUniform will return the name of the array in name, - * subject to the restrictions listed above. The type of the array - * is returned in type. The size parameter contains the highest - * array element index used, plus one. The compiler or linker - * determines the highest index used. There will be only one - * active uniform reported by the GL per uniform array. - - */ -static void -update_array_sizes(struct gl_shader_program *prog) -{ - 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 && - var->mode != ir_var_in && - var->mode != ir_var_out) || - !var->type->is_array()) - continue; - - unsigned int size = var->max_array_access; - for (unsigned j = 0; j < prog->_NumLinkedShaders; j++) { - foreach_list(node2, prog->_LinkedShaders[j]->ir) { - ir_variable *other_var = ((ir_instruction *) node2)->as_variable(); - if (!other_var) - continue; - - if (strcmp(var->name, other_var->name) == 0 && - other_var->max_array_access > size) { - size = other_var->max_array_access; - } - } - } - - if (size + 1 != var->type->fields.array->length) { - var->type = glsl_type::get_array_instance(var->type->fields.array, - size + 1); - /* FINISHME: We should update the types of array - * dereferences of this variable now. - */ - } - } - } -} - -static void -add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht, - const char *name, const glsl_type *type, GLenum shader_type, - unsigned *next_shader_pos, unsigned *total_uniforms) -{ - if (type->is_record()) { - for (unsigned int i = 0; i < type->length; i++) { - const glsl_type *field_type = type->fields.structure[i].type; - char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name, - type->fields.structure[i].name); - - add_uniform(mem_ctx, uniforms, ht, field_name, field_type, - shader_type, next_shader_pos, total_uniforms); - } - } else { - uniform_node *n = (uniform_node *) hash_table_find(ht, name); - unsigned int vec4_slots; - const glsl_type *array_elem_type = NULL; - - if (type->is_array()) { - array_elem_type = type->fields.array; - /* Array of structures. */ - if (array_elem_type->is_record()) { - for (unsigned int i = 0; i < type->length; i++) { - char *elem_name = talloc_asprintf(mem_ctx, "%s[%d]", name, i); - add_uniform(mem_ctx, uniforms, ht, elem_name, array_elem_type, - shader_type, next_shader_pos, total_uniforms); - } - return; - } - } - - /* Fix the storage size of samplers at 1 vec4 each. Be sure to pad out - * vectors to vec4 slots. - */ - if (type->is_array()) { - if (array_elem_type->is_sampler()) - vec4_slots = type->length; - else - vec4_slots = type->length * array_elem_type->matrix_columns; - } else if (type->is_sampler()) { - vec4_slots = 1; - } else { - vec4_slots = type->matrix_columns; - } - - if (n == NULL) { - n = (uniform_node *) calloc(1, sizeof(struct uniform_node)); - n->u = (gl_uniform *) calloc(1, sizeof(struct gl_uniform)); - n->slots = vec4_slots; - - n->u->Name = strdup(name); - n->u->Type = type; - n->u->VertPos = -1; - n->u->FragPos = -1; - n->u->GeomPos = -1; - (*total_uniforms)++; - - hash_table_insert(ht, n, name); - uniforms->push_tail(& n->link); - } - - switch (shader_type) { - case GL_VERTEX_SHADER: - n->u->VertPos = *next_shader_pos; - break; - case GL_FRAGMENT_SHADER: - n->u->FragPos = *next_shader_pos; - break; - case GL_GEOMETRY_SHADER: - n->u->GeomPos = *next_shader_pos; - break; - } - - (*next_shader_pos) += vec4_slots; - } -} - -void -assign_uniform_locations(struct gl_shader_program *prog) -{ - /* */ - exec_list uniforms; - unsigned total_uniforms = 0; - hash_table *ht = hash_table_ctor(32, hash_table_string_hash, - hash_table_string_compare); - void *mem_ctx = talloc_new(NULL); - - 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; - - if (strncmp(var->name, "gl_", 3) == 0) { - /* At the moment, we don't allocate uniform locations for - * builtin uniforms. It's permitted by spec, and we'll - * likely switch to doing that at some point, but not yet. - */ - continue; - } - - var->location = next_position; - add_uniform(mem_ctx, &uniforms, ht, var->name, var->type, - prog->_LinkedShaders[i]->Type, - &next_position, &total_uniforms); - } - } - - talloc_free(mem_ctx); - - 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)); - idx++; - - 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(gl_shader_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); - - gl_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); - - /* VERT_ATTRIB_GENERIC0 is a psdueo-alias for VERT_ATTRIB_POS. It can only - * be explicitly assigned by via glBindAttribLocation. Mark it as reserved - * to prevent it from being automatically allocated below. - */ - find_deref_visitor find("gl_Vertex"); - find.run(sh->ir); - if (find.variable_found()) - used_locations |= (1 << 0); - - 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; -} - - -/** - * Demote shader outputs that are not read to being just plain global variables - */ -void -demote_unread_shader_outputs(gl_shader *sh) -{ - foreach_list(node, sh->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. - */ - if (var->location == -1) { - var->mode = ir_var_auto; - } - } -} - - -void -assign_varying_locations(struct gl_shader_program *prog, - gl_shader *producer, gl_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); - - output_var->location = output_index; - input_var->location = input_index; - - /* FINISHME: Support for "varying" records in GLSL 1.50. */ - assert(!output_var->type->is_record()); - - if (output_var->type->is_array()) { - const unsigned slots = output_var->type->length - * output_var->type->fields.array->matrix_columns; - - output_index += slots; - input_index += slots; - } else { - const unsigned slots = output_var->type->matrix_columns; - - output_index += slots; - input_index += slots; - } - } - - demote_unread_shader_outputs(producer); - - foreach_list(node, consumer->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); - - if ((var == NULL) || (var->mode != ir_var_in)) - continue; - - if (var->location == -1) { - if (prog->Version <= 120) { - /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec: - * - * Only those varying variables used (i.e. read) in - * the fragment shader executable must be written to - * by the vertex shader executable; declaring - * superfluous varying variables in a vertex shader is - * permissible. - * - * We interpret this text as meaning that the VS must - * write the variable for the FS to read it. See - * "glsl1-varying read but not written" in piglit. - */ - - linker_error_printf(prog, "fragment shader varying %s not written " - "by vertex shader\n.", var->name); - prog->LinkStatus = false; - } - - /* An 'in' variable is only really a shader input if its - * value is written by the previous stage. - */ - var->mode = ir_var_auto; - } - } -} - - -void -link_shaders(GLcontext *ctx, struct gl_shader_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 gl_shader **vert_shader_list; - unsigned num_vert_shaders = 0; - struct gl_shader **frag_shader_list; - unsigned num_frag_shaders = 0; - - vert_shader_list = (struct gl_shader **) - calloc(2 * prog->NumShaders, sizeof(struct gl_shader *)); - frag_shader_list = &vert_shader_list[prog->NumShaders]; - - unsigned min_version = UINT_MAX; - unsigned max_version = 0; - for (unsigned i = 0; i < prog->NumShaders; i++) { - min_version = MIN2(min_version, prog->Shaders[i]->Version); - max_version = MAX2(max_version, prog->Shaders[i]->Version); - - 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; - } - } - - /* Previous to GLSL version 1.30, different compilation units could mix and - * match shading language versions. With GLSL 1.30 and later, the versions - * of all shaders must match. - */ - assert(min_version >= 100); - assert(max_version <= 130); - if ((max_version >= 130 || min_version == 100) - && min_version != max_version) { - linker_error_printf(prog, "all shaders must use same shading " - "language version\n"); - goto done; - } - - prog->Version = max_version; - - for (unsigned int i = 0; i < prog->_NumLinkedShaders; i++) { - ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]); - } - - /* Link all shaders for a particular stage and validate the result. - */ - prog->_NumLinkedShaders = 0; - if (num_vert_shaders > 0) { - gl_shader *const sh = - link_intrastage_shaders(ctx, prog, vert_shader_list, num_vert_shaders); - - if (sh == NULL) - goto done; - - if (!validate_vertex_shader_executable(prog, sh)) - goto done; - - prog->_LinkedShaders[prog->_NumLinkedShaders] = sh; - prog->_NumLinkedShaders++; - } - - if (num_frag_shaders > 0) { - gl_shader *const sh = - link_intrastage_shaders(ctx, prog, frag_shader_list, num_frag_shaders); - - if (sh == NULL) - goto done; - - if (!validate_fragment_shader_executable(prog, sh)) - goto done; - - prog->_LinkedShaders[prog->_NumLinkedShaders] = sh; - 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; - } - - /* Do common optimization before assigning storage for attributes, - * uniforms, and varyings. Later optimization could possibly make - * some of that unused. - */ - for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { - while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32)) - ; - } - - update_array_sizes(prog); - - assign_uniform_locations(prog); - - if (prog->_NumLinkedShaders && 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; - - if (prog->_NumLinkedShaders == 1) - demote_unread_shader_outputs(prog->_LinkedShaders[0]); - } - - for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) - assign_varying_locations(prog, - prog->_LinkedShaders[i - 1], - prog->_LinkedShaders[i]); - - /* FINISHME: Assign fragment shader output locations. */ - -done: - free(vert_shader_list); -} +/*
+ * 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>
+#include <climits>
+
+extern "C" {
+#include <talloc.h>
+}
+
+#include "main/core.h"
+#include "glsl_symbol_table.h"
+#include "ir.h"
+#include "program.h"
+#include "program/hash_table.h"
+#include "linker.h"
+#include "ir_optimization.h"
+
+extern "C" {
+#include "main/shaderobj.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;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_call *ir)
+ {
+ exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_rvalue *param_rval = (ir_rvalue *)iter.get();
+ ir_variable *sig_param = (ir_variable *)sig_iter.get();
+
+ if (sig_param->mode == ir_var_out ||
+ sig_param->mode == ir_var_inout) {
+ ir_variable *var = param_rval->variable_referenced();
+ if (var && strcmp(name, var->name) == 0) {
+ found = true;
+ return visit_stop;
+ }
+ }
+ sig_iter.next();
+ }
+
+ 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? */
+};
+
+
+/**
+ * Visitor that determines whether or not a variable is ever read.
+ */
+class find_deref_visitor : public ir_hierarchical_visitor {
+public:
+ find_deref_visitor(const char *name)
+ : name(name), found(false)
+ {
+ /* empty */
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ if (strcmp(this->name, ir->var->name) == 0) {
+ this->found = true;
+ return visit_stop;
+ }
+
+ return visit_continue;
+ }
+
+ bool variable_found() const
+ {
+ return this->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(gl_shader_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(gl_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->explicit_location)
+ 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 gl_shader_program *prog,
+ struct gl_shader *shader)
+{
+ if (shader == NULL)
+ return true;
+
+ 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 gl_shader_program *prog,
+ struct gl_shader *shader)
+{
+ if (shader == NULL)
+ return true;
+
+ 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 writes to both "
+ "`gl_FragColor' and `gl_FragData'\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Generate a string describing the mode of a variable
+ */
+static const char *
+mode_string(const ir_variable *var)
+{
+ switch (var->mode) {
+ case ir_var_auto:
+ return (var->read_only) ? "global constant" : "global variable";
+
+ case ir_var_uniform: return "uniform";
+ case ir_var_in: return "shader input";
+ case ir_var_out: return "shader output";
+ case ir_var_inout: return "shader inout";
+
+ case ir_var_temporary:
+ default:
+ assert(!"Should not get here.");
+ return "invalid variable";
+ }
+}
+
+
+/**
+ * Perform validation of global variables used across multiple shaders
+ */
+bool
+cross_validate_globals(struct gl_shader_program *prog,
+ struct gl_shader **shader_list,
+ unsigned num_shaders,
+ bool uniforms_only)
+{
+ /* Examine all of the uniforms in all of the shaders and cross validate
+ * them.
+ */
+ glsl_symbol_table variables;
+ for (unsigned i = 0; i < num_shaders; i++) {
+ if (shader_list[i] == NULL)
+ continue;
+
+ foreach_list(node, shader_list[i]->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var == NULL)
+ continue;
+
+ if (uniforms_only && (var->mode != ir_var_uniform))
+ continue;
+
+ /* Don't cross validate temporaries that are at global scope. These
+ * will eventually get pulled into the shaders 'main'.
+ */
+ if (var->mode == ir_var_temporary)
+ continue;
+
+ /* If a global with this name has already been seen, verify that the
+ * new instance has the same type. In addition, if the globals have
+ * initializers, the values of the initializers must be the same.
+ */
+ ir_variable *const existing = variables.get_variable(var->name);
+ if (existing != NULL) {
+ if (var->type != existing->type) {
+ /* Consider the types to be "the same" if both types are arrays
+ * of the same type and one of the arrays is implicitly sized.
+ * In addition, set the type of the linked variable to the
+ * explicitly sized array.
+ */
+ if (var->type->is_array()
+ && existing->type->is_array()
+ && (var->type->fields.array == existing->type->fields.array)
+ && ((var->type->length == 0)
+ || (existing->type->length == 0))) {
+ if (existing->type->length == 0) {
+ existing->type = var->type;
+ existing->max_array_access =
+ MAX2(existing->max_array_access,
+ var->max_array_access);
+ }
+ } else {
+ linker_error_printf(prog, "%s `%s' declared as type "
+ "`%s' and type `%s'\n",
+ mode_string(var),
+ var->name, var->type->name,
+ existing->type->name);
+ return false;
+ }
+ }
+
+ if (var->explicit_location) {
+ if (existing->explicit_location
+ && (var->location != existing->location)) {
+ linker_error_printf(prog, "explicit locations for %s "
+ "`%s' have differing values\n",
+ mode_string(var), var->name);
+ return false;
+ }
+
+ existing->location = var->location;
+ existing->explicit_location = true;
+ }
+
+ /* FINISHME: Handle non-constant initializers.
+ */
+ 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 %s "
+ "`%s' have differing values\n",
+ mode_string(var), 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.
+ */
+ /* FINISHME: This is wrong. The constant_value field should
+ * FINISHME: not be modified! Imagine a case where a shader
+ * FINISHME: without an initializer is linked in two different
+ * FINISHME: programs with shaders that have differing
+ * FINISHME: initializers. Linking with the first will
+ * FINISHME: modify the shader, and linking with the second
+ * FINISHME: will fail.
+ */
+ existing->constant_value =
+ var->constant_value->clone(talloc_parent(existing), NULL);
+ }
+
+ if (existing->invariant != var->invariant) {
+ linker_error_printf(prog, "declarations for %s `%s' have "
+ "mismatching invariant qualifiers\n",
+ mode_string(var), var->name);
+ return false;
+ }
+ } else
+ variables.add_variable(var);
+ }
+ }
+
+ return true;
+}
+
+
+/**
+ * Perform validation of uniforms used across multiple shader stages
+ */
+bool
+cross_validate_uniforms(struct gl_shader_program *prog)
+{
+ return cross_validate_globals(prog, prog->_LinkedShaders,
+ MESA_SHADER_TYPES, true);
+}
+
+
+/**
+ * Validate that outputs from one stage match inputs of another
+ */
+bool
+cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
+ gl_shader *producer, gl_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);
+ }
+
+
+ /* 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) {
+ /* There is a bit of a special case for gl_TexCoord. This
+ * built-in is unsized by default. Appliations that variable
+ * access it must redeclare it with a size. There is some
+ * language in the GLSL spec that implies the fragment shader
+ * and vertex shader do not have to agree on this size. Other
+ * driver behave this way, and one or two applications seem to
+ * rely on it.
+ *
+ * Neither declaration needs to be modified here because the array
+ * sizes are fixed later when update_array_sizes is called.
+ *
+ * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "Unlike user-defined varying variables, the built-in
+ * varying variables don't have a strict one-to-one
+ * correspondence between the vertex language and the
+ * fragment language."
+ */
+ if (!output->type->is_array()
+ || (strncmp("gl_", output->name, 3) != 0)) {
+ linker_error_printf(prog,
+ "%s shader output `%s' declared 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;
+}
+
+
+/**
+ * Populates a shaders symbol table with all global declarations
+ */
+static void
+populate_symbol_table(gl_shader *sh)
+{
+ sh->symbols = new(sh) glsl_symbol_table;
+
+ foreach_list(node, sh->ir) {
+ ir_instruction *const inst = (ir_instruction *) node;
+ ir_variable *var;
+ ir_function *func;
+
+ if ((func = inst->as_function()) != NULL) {
+ sh->symbols->add_function(func);
+ } else if ((var = inst->as_variable()) != NULL) {
+ sh->symbols->add_variable(var);
+ }
+ }
+}
+
+
+/**
+ * Remap variables referenced in an instruction tree
+ *
+ * This is used when instruction trees are cloned from one shader and placed in
+ * another. These trees will contain references to \c ir_variable nodes that
+ * do not exist in the target shader. This function finds these \c ir_variable
+ * references and replaces the references with matching variables in the target
+ * shader.
+ *
+ * If there is no matching variable in the target shader, a clone of the
+ * \c ir_variable is made and added to the target shader. The new variable is
+ * added to \b both the instruction stream and the symbol table.
+ *
+ * \param inst IR tree that is to be processed.
+ * \param symbols Symbol table containing global scope symbols in the
+ * linked shader.
+ * \param instructions Instruction stream where new variable declarations
+ * should be added.
+ */
+void
+remap_variables(ir_instruction *inst, struct gl_shader *target,
+ hash_table *temps)
+{
+ class remap_visitor : public ir_hierarchical_visitor {
+ public:
+ remap_visitor(struct gl_shader *target,
+ hash_table *temps)
+ {
+ this->target = target;
+ this->symbols = target->symbols;
+ this->instructions = target->ir;
+ this->temps = temps;
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ if (ir->var->mode == ir_var_temporary) {
+ ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var);
+
+ assert(var != NULL);
+ ir->var = var;
+ return visit_continue;
+ }
+
+ ir_variable *const existing =
+ this->symbols->get_variable(ir->var->name);
+ if (existing != NULL)
+ ir->var = existing;
+ else {
+ ir_variable *copy = ir->var->clone(this->target, NULL);
+
+ this->symbols->add_variable(copy);
+ this->instructions->push_head(copy);
+ ir->var = copy;
+ }
+
+ return visit_continue;
+ }
+
+ private:
+ struct gl_shader *target;
+ glsl_symbol_table *symbols;
+ exec_list *instructions;
+ hash_table *temps;
+ };
+
+ remap_visitor v(target, temps);
+
+ inst->accept(&v);
+}
+
+
+/**
+ * Move non-declarations from one instruction stream to another
+ *
+ * The intended usage pattern of this function is to pass the pointer to the
+ * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node
+ * pointer) for \c last and \c false for \c make_copies on the first
+ * call. Successive calls pass the return value of the previous call for
+ * \c last and \c true for \c make_copies.
+ *
+ * \param instructions Source instruction stream
+ * \param last Instruction after which new instructions should be
+ * inserted in the target instruction stream
+ * \param make_copies Flag selecting whether instructions in \c instructions
+ * should be copied (via \c ir_instruction::clone) into the
+ * target list or moved.
+ *
+ * \return
+ * The new "last" instruction in the target instruction stream. This pointer
+ * is suitable for use as the \c last parameter of a later call to this
+ * function.
+ */
+exec_node *
+move_non_declarations(exec_list *instructions, exec_node *last,
+ bool make_copies, gl_shader *target)
+{
+ hash_table *temps = NULL;
+
+ if (make_copies)
+ temps = hash_table_ctor(0, hash_table_pointer_hash,
+ hash_table_pointer_compare);
+
+ foreach_list_safe(node, instructions) {
+ ir_instruction *inst = (ir_instruction *) node;
+
+ if (inst->as_function())
+ continue;
+
+ ir_variable *var = inst->as_variable();
+ if ((var != NULL) && (var->mode != ir_var_temporary))
+ continue;
+
+ assert(inst->as_assignment()
+ || ((var != NULL) && (var->mode == ir_var_temporary)));
+
+ if (make_copies) {
+ inst = inst->clone(target, NULL);
+
+ if (var != NULL)
+ hash_table_insert(temps, inst, var);
+ else
+ remap_variables(inst, target, temps);
+ } else {
+ inst->remove();
+ }
+
+ last->insert_after(inst);
+ last = inst;
+ }
+
+ if (make_copies)
+ hash_table_dtor(temps);
+
+ return last;
+}
+
+/**
+ * Get the function signature for main from a shader
+ */
+static ir_function_signature *
+get_main_function_signature(gl_shader *sh)
+{
+ ir_function *const f = sh->symbols->get_function("main");
+ if (f != NULL) {
+ exec_list void_parameters;
+
+ /* Look for the 'void main()' signature and ensure that it's defined.
+ * This keeps the linker from accidentally pick a shader that just
+ * contains a prototype for main.
+ *
+ * We don't have to check for multiple definitions of main (in multiple
+ * shaders) because that would have already been caught above.
+ */
+ ir_function_signature *sig = f->matching_signature(&void_parameters);
+ if ((sig != NULL) && sig->is_defined) {
+ return sig;
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ * Combine a group of shaders for a single stage to generate a linked shader
+ *
+ * \note
+ * If this function is supplied a single shader, it is cloned, and the new
+ * shader is returned.
+ */
+static struct gl_shader *
+link_intrastage_shaders(void *mem_ctx,
+ struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ struct gl_shader **shader_list,
+ unsigned num_shaders)
+{
+ /* Check that global variables defined in multiple shaders are consistent.
+ */
+ if (!cross_validate_globals(prog, shader_list, num_shaders, false))
+ return NULL;
+
+ /* Check that there is only a single definition of each function signature
+ * across all shaders.
+ */
+ for (unsigned i = 0; i < (num_shaders - 1); i++) {
+ foreach_list(node, shader_list[i]->ir) {
+ ir_function *const f = ((ir_instruction *) node)->as_function();
+
+ if (f == NULL)
+ continue;
+
+ for (unsigned j = i + 1; j < num_shaders; j++) {
+ ir_function *const other =
+ shader_list[j]->symbols->get_function(f->name);
+
+ /* If the other shader has no function (and therefore no function
+ * signatures) with the same name, skip to the next shader.
+ */
+ if (other == NULL)
+ continue;
+
+ foreach_iter (exec_list_iterator, iter, *f) {
+ ir_function_signature *sig =
+ (ir_function_signature *) iter.get();
+
+ if (!sig->is_defined || sig->is_builtin)
+ continue;
+
+ ir_function_signature *other_sig =
+ other->exact_matching_signature(& sig->parameters);
+
+ if ((other_sig != NULL) && other_sig->is_defined
+ && !other_sig->is_builtin) {
+ linker_error_printf(prog,
+ "function `%s' is multiply defined",
+ f->name);
+ return NULL;
+ }
+ }
+ }
+ }
+ }
+
+ /* Find the shader that defines main, and make a clone of it.
+ *
+ * Starting with the clone, search for undefined references. If one is
+ * found, find the shader that defines it. Clone the reference and add
+ * it to the shader. Repeat until there are no undefined references or
+ * until a reference cannot be resolved.
+ */
+ gl_shader *main = NULL;
+ for (unsigned i = 0; i < num_shaders; i++) {
+ if (get_main_function_signature(shader_list[i]) != NULL) {
+ main = shader_list[i];
+ break;
+ }
+ }
+
+ if (main == NULL) {
+ linker_error_printf(prog, "%s shader lacks `main'\n",
+ (shader_list[0]->Type == GL_VERTEX_SHADER)
+ ? "vertex" : "fragment");
+ return NULL;
+ }
+
+ gl_shader *linked = ctx->Driver.NewShader(NULL, 0, main->Type);
+ linked->ir = new(linked) exec_list;
+ clone_ir_list(mem_ctx, linked->ir, main->ir);
+
+ populate_symbol_table(linked);
+
+ /* The a pointer to the main function in the final linked shader (i.e., the
+ * copy of the original shader that contained the main function).
+ */
+ ir_function_signature *const main_sig = get_main_function_signature(linked);
+
+ /* Move any instructions other than variable declarations or function
+ * declarations into main.
+ */
+ exec_node *insertion_point =
+ move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false,
+ linked);
+
+ for (unsigned i = 0; i < num_shaders; i++) {
+ if (shader_list[i] == main)
+ continue;
+
+ insertion_point = move_non_declarations(shader_list[i]->ir,
+ insertion_point, true, linked);
+ }
+
+ /* Resolve initializers for global variables in the linked shader.
+ */
+ unsigned num_linking_shaders = num_shaders;
+ for (unsigned i = 0; i < num_shaders; i++)
+ num_linking_shaders += shader_list[i]->num_builtins_to_link;
+
+ gl_shader **linking_shaders =
+ (gl_shader **) calloc(num_linking_shaders, sizeof(gl_shader *));
+
+ memcpy(linking_shaders, shader_list,
+ sizeof(linking_shaders[0]) * num_shaders);
+
+ unsigned idx = num_shaders;
+ for (unsigned i = 0; i < num_shaders; i++) {
+ memcpy(&linking_shaders[idx], shader_list[i]->builtins_to_link,
+ sizeof(linking_shaders[0]) * shader_list[i]->num_builtins_to_link);
+ idx += shader_list[i]->num_builtins_to_link;
+ }
+
+ assert(idx == num_linking_shaders);
+
+ if (!link_function_calls(prog, linked, linking_shaders,
+ num_linking_shaders)) {
+ ctx->Driver.DeleteShader(ctx, linked);
+ linked = NULL;
+ }
+
+ free(linking_shaders);
+
+ /* Make a pass over all global variables to ensure that arrays with
+ * unspecified sizes have a size specified. The size is inferred from the
+ * max_array_access field.
+ */
+ if (linked != NULL) {
+ foreach_list(node, linked->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var == NULL)
+ continue;
+
+ if ((var->mode != ir_var_auto) && (var->mode != ir_var_temporary))
+ continue;
+
+ if (!var->type->is_array() || (var->type->length != 0))
+ continue;
+
+ const glsl_type *type =
+ glsl_type::get_array_instance(var->type->fields.array,
+ var->max_array_access);
+
+ assert(type != NULL);
+ var->type = type;
+ }
+ }
+
+ return linked;
+}
+
+
+struct uniform_node {
+ exec_node link;
+ struct gl_uniform *u;
+ unsigned slots;
+};
+
+/**
+ * Update the sizes of linked shader uniform arrays to the maximum
+ * array index used.
+ *
+ * From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec:
+ *
+ * If one or more elements of an array are active,
+ * GetActiveUniform will return the name of the array in name,
+ * subject to the restrictions listed above. The type of the array
+ * is returned in type. The size parameter contains the highest
+ * array element index used, plus one. The compiler or linker
+ * determines the highest index used. There will be only one
+ * active uniform reported by the GL per uniform array.
+
+ */
+static void
+update_array_sizes(struct gl_shader_program *prog)
+{
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ foreach_list(node, prog->_LinkedShaders[i]->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != ir_var_uniform &&
+ var->mode != ir_var_in &&
+ var->mode != ir_var_out) ||
+ !var->type->is_array())
+ continue;
+
+ unsigned int size = var->max_array_access;
+ for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) {
+ if (prog->_LinkedShaders[j] == NULL)
+ continue;
+
+ foreach_list(node2, prog->_LinkedShaders[j]->ir) {
+ ir_variable *other_var = ((ir_instruction *) node2)->as_variable();
+ if (!other_var)
+ continue;
+
+ if (strcmp(var->name, other_var->name) == 0 &&
+ other_var->max_array_access > size) {
+ size = other_var->max_array_access;
+ }
+ }
+ }
+
+ if (size + 1 != var->type->fields.array->length) {
+ var->type = glsl_type::get_array_instance(var->type->fields.array,
+ size + 1);
+ /* FINISHME: We should update the types of array
+ * dereferences of this variable now.
+ */
+ }
+ }
+ }
+}
+
+static void
+add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
+ const char *name, const glsl_type *type, GLenum shader_type,
+ unsigned *next_shader_pos, unsigned *total_uniforms)
+{
+ if (type->is_record()) {
+ for (unsigned int i = 0; i < type->length; i++) {
+ const glsl_type *field_type = type->fields.structure[i].type;
+ char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name,
+ type->fields.structure[i].name);
+
+ add_uniform(mem_ctx, uniforms, ht, field_name, field_type,
+ shader_type, next_shader_pos, total_uniforms);
+ }
+ } else {
+ uniform_node *n = (uniform_node *) hash_table_find(ht, name);
+ unsigned int vec4_slots;
+ const glsl_type *array_elem_type = NULL;
+
+ if (type->is_array()) {
+ array_elem_type = type->fields.array;
+ /* Array of structures. */
+ if (array_elem_type->is_record()) {
+ for (unsigned int i = 0; i < type->length; i++) {
+ char *elem_name = talloc_asprintf(mem_ctx, "%s[%d]", name, i);
+ add_uniform(mem_ctx, uniforms, ht, elem_name, array_elem_type,
+ shader_type, next_shader_pos, total_uniforms);
+ }
+ return;
+ }
+ }
+
+ /* Fix the storage size of samplers at 1 vec4 each. Be sure to pad out
+ * vectors to vec4 slots.
+ */
+ if (type->is_array()) {
+ if (array_elem_type->is_sampler())
+ vec4_slots = type->length;
+ else
+ vec4_slots = type->length * array_elem_type->matrix_columns;
+ } else if (type->is_sampler()) {
+ vec4_slots = 1;
+ } else {
+ vec4_slots = type->matrix_columns;
+ }
+
+ if (n == NULL) {
+ n = (uniform_node *) calloc(1, sizeof(struct uniform_node));
+ n->u = (gl_uniform *) calloc(1, sizeof(struct gl_uniform));
+ n->slots = vec4_slots;
+
+ n->u->Name = strdup(name);
+ n->u->Type = type;
+ n->u->VertPos = -1;
+ n->u->FragPos = -1;
+ n->u->GeomPos = -1;
+ (*total_uniforms)++;
+
+ hash_table_insert(ht, n, name);
+ uniforms->push_tail(& n->link);
+ }
+
+ switch (shader_type) {
+ case GL_VERTEX_SHADER:
+ n->u->VertPos = *next_shader_pos;
+ break;
+ case GL_FRAGMENT_SHADER:
+ n->u->FragPos = *next_shader_pos;
+ break;
+ case GL_GEOMETRY_SHADER:
+ n->u->GeomPos = *next_shader_pos;
+ break;
+ }
+
+ (*next_shader_pos) += vec4_slots;
+ }
+}
+
+void
+assign_uniform_locations(struct gl_shader_program *prog)
+{
+ /* */
+ exec_list uniforms;
+ unsigned total_uniforms = 0;
+ hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
+ hash_table_string_compare);
+ void *mem_ctx = talloc_new(NULL);
+
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ 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;
+
+ if (strncmp(var->name, "gl_", 3) == 0) {
+ /* At the moment, we don't allocate uniform locations for
+ * builtin uniforms. It's permitted by spec, and we'll
+ * likely switch to doing that at some point, but not yet.
+ */
+ continue;
+ }
+
+ var->location = next_position;
+ add_uniform(mem_ctx, &uniforms, ht, var->name, var->type,
+ prog->_LinkedShaders[i]->Type,
+ &next_position, &total_uniforms);
+ }
+ }
+
+ talloc_free(mem_ctx);
+
+ 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));
+ idx++;
+
+ 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(gl_shader_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);
+
+ gl_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;
+
+ if (var->explicit_location) {
+ const unsigned slots = count_attribute_slots(var->type);
+ const unsigned use_mask = (1 << slots) - 1;
+ const int attr = var->location - VERT_ATTRIB_GENERIC0;
+
+ if ((var->location >= (int)(max_attribute_index + VERT_ATTRIB_GENERIC0))
+ || (var->location < 0)) {
+ linker_error_printf(prog,
+ "invalid explicit location %d specified for "
+ "`%s'\n",
+ (var->location < 0) ? var->location : attr,
+ var->name);
+ return false;
+ } else if (var->location >= VERT_ATTRIB_GENERIC0) {
+ used_locations |= (use_mask << attr);
+ }
+ }
+
+ /* 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);
+
+ /* VERT_ATTRIB_GENERIC0 is a psdueo-alias for VERT_ATTRIB_POS. It can only
+ * be explicitly assigned by via glBindAttribLocation. Mark it as reserved
+ * to prevent it from being automatically allocated below.
+ */
+ find_deref_visitor find("gl_Vertex");
+ find.run(sh->ir);
+ if (find.variable_found())
+ used_locations |= (1 << 0);
+
+ 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;
+}
+
+
+/**
+ * Demote shader inputs and outputs that are not used in other stages
+ */
+void
+demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
+{
+ foreach_list(node, sh->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != int(mode)))
+ continue;
+
+ /* A shader 'in' or 'out' variable is only really an input or output if
+ * its value is used by other shader stages. This will cause the variable
+ * to have a location assigned.
+ */
+ if (var->location == -1) {
+ var->mode = ir_var_auto;
+ }
+ }
+}
+
+
+void
+assign_varying_locations(struct gl_shader_program *prog,
+ gl_shader *producer, gl_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);
+
+ output_var->location = output_index;
+ input_var->location = input_index;
+
+ /* FINISHME: Support for "varying" records in GLSL 1.50. */
+ assert(!output_var->type->is_record());
+
+ if (output_var->type->is_array()) {
+ const unsigned slots = output_var->type->length
+ * output_var->type->fields.array->matrix_columns;
+
+ output_index += slots;
+ input_index += slots;
+ } else {
+ const unsigned slots = output_var->type->matrix_columns;
+
+ output_index += slots;
+ input_index += slots;
+ }
+ }
+
+ foreach_list(node, consumer->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if ((var == NULL) || (var->mode != ir_var_in))
+ continue;
+
+ if (var->location == -1) {
+ if (prog->Version <= 120) {
+ /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
+ *
+ * Only those varying variables used (i.e. read) in
+ * the fragment shader executable must be written to
+ * by the vertex shader executable; declaring
+ * superfluous varying variables in a vertex shader is
+ * permissible.
+ *
+ * We interpret this text as meaning that the VS must
+ * write the variable for the FS to read it. See
+ * "glsl1-varying read but not written" in piglit.
+ */
+
+ linker_error_printf(prog, "fragment shader varying %s not written "
+ "by vertex shader\n.", var->name);
+ prog->LinkStatus = false;
+ }
+
+ /* An 'in' variable is only really a shader input if its
+ * value is written by the previous stage.
+ */
+ var->mode = ir_var_auto;
+ }
+ }
+}
+
+
+void
+link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+ void *mem_ctx = talloc_init("temporary linker context");
+
+ 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 gl_shader **vert_shader_list;
+ unsigned num_vert_shaders = 0;
+ struct gl_shader **frag_shader_list;
+ unsigned num_frag_shaders = 0;
+
+ vert_shader_list = (struct gl_shader **)
+ calloc(2 * prog->NumShaders, sizeof(struct gl_shader *));
+ frag_shader_list = &vert_shader_list[prog->NumShaders];
+
+ unsigned min_version = UINT_MAX;
+ unsigned max_version = 0;
+ for (unsigned i = 0; i < prog->NumShaders; i++) {
+ min_version = MIN2(min_version, prog->Shaders[i]->Version);
+ max_version = MAX2(max_version, prog->Shaders[i]->Version);
+
+ 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;
+ }
+ }
+
+ /* Previous to GLSL version 1.30, different compilation units could mix and
+ * match shading language versions. With GLSL 1.30 and later, the versions
+ * of all shaders must match.
+ */
+ assert(min_version >= 100);
+ assert(max_version <= 130);
+ if ((max_version >= 130 || min_version == 100)
+ && min_version != max_version) {
+ linker_error_printf(prog, "all shaders must use same shading "
+ "language version\n");
+ goto done;
+ }
+
+ prog->Version = max_version;
+
+ for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] != NULL)
+ ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]);
+
+ prog->_LinkedShaders[i] = NULL;
+ }
+
+ /* Link all shaders for a particular stage and validate the result.
+ */
+ if (num_vert_shaders > 0) {
+ gl_shader *const sh =
+ link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list,
+ num_vert_shaders);
+
+ if (sh == NULL)
+ goto done;
+
+ if (!validate_vertex_shader_executable(prog, sh))
+ goto done;
+
+ _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX],
+ sh);
+ }
+
+ if (num_frag_shaders > 0) {
+ gl_shader *const sh =
+ link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list,
+ num_frag_shaders);
+
+ if (sh == NULL)
+ goto done;
+
+ if (!validate_fragment_shader_executable(prog, sh))
+ goto done;
+
+ _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
+ sh);
+ }
+
+ /* 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)) {
+ unsigned prev;
+
+ for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
+ if (prog->_LinkedShaders[prev] != NULL)
+ break;
+ }
+
+ /* Validate the inputs of each stage with the output of the preceeding
+ * stage.
+ */
+ for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ if (!cross_validate_outputs_to_inputs(prog,
+ prog->_LinkedShaders[prev],
+ prog->_LinkedShaders[i]))
+ goto done;
+
+ prev = i;
+ }
+
+ prog->LinkStatus = true;
+ }
+
+ /* Do common optimization before assigning storage for attributes,
+ * uniforms, and varyings. Later optimization could possibly make
+ * some of that unused.
+ */
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
+ ;
+ }
+
+ update_array_sizes(prog);
+
+ assign_uniform_locations(prog);
+
+ if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
+ /* 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)) {
+ prog->LinkStatus = false;
+ goto done;
+ }
+ }
+
+ unsigned prev;
+ for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
+ if (prog->_LinkedShaders[prev] != NULL)
+ break;
+ }
+
+ for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ assign_varying_locations(prog,
+ prog->_LinkedShaders[prev],
+ prog->_LinkedShaders[i]);
+ prev = i;
+ }
+
+ if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
+ demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX],
+ ir_var_out);
+ }
+
+ if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
+ gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
+
+ demote_shader_inputs_and_outputs(sh, ir_var_in);
+ demote_shader_inputs_and_outputs(sh, ir_var_inout);
+ demote_shader_inputs_and_outputs(sh, ir_var_out);
+ }
+
+ if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
+ gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+
+ demote_shader_inputs_and_outputs(sh, ir_var_in);
+ }
+
+ /* FINISHME: Assign fragment shader output locations. */
+
+done:
+ free(vert_shader_list);
+
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
+
+ /* Retain any live IR, but trash the rest. */
+ reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);
+ }
+
+ talloc_free(mem_ctx);
+}
diff --git a/mesalib/src/glsl/loop_analysis.cpp b/mesalib/src/glsl/loop_analysis.cpp index 91e34da0e..f32b91ce8 100644 --- a/mesalib/src/glsl/loop_analysis.cpp +++ b/mesalib/src/glsl/loop_analysis.cpp @@ -1,496 +1,497 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "glsl_types.h" -#include "loop_analysis.h" -#include "ir_hierarchical_visitor.h" - -static bool is_loop_terminator(ir_if *ir); - -static bool all_expression_operands_are_loop_constant(ir_rvalue *, - hash_table *); - -static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table *); - - -loop_state::loop_state() -{ - this->ht = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); - this->mem_ctx = talloc_init("loop state"); -} - - -loop_state::~loop_state() -{ - hash_table_dtor(this->ht); -} - - -loop_variable_state * -loop_state::insert(ir_loop *ir) -{ - loop_variable_state *ls = new(this->mem_ctx) loop_variable_state; - hash_table_insert(this->ht, ls, ir); - - return ls; -} - - -loop_variable_state * -loop_state::get(const ir_loop *ir) -{ - return (loop_variable_state *) hash_table_find(this->ht, ir); -} - - -loop_variable * -loop_variable_state::get(const ir_variable *ir) -{ - return (loop_variable *) hash_table_find(this->var_hash, ir); -} - - -loop_variable * -loop_variable_state::insert(ir_variable *var) -{ - void *mem_ctx = talloc_parent(this); - loop_variable *lv = talloc_zero(mem_ctx, loop_variable); - - lv->var = var; - - hash_table_insert(this->var_hash, lv, lv->var); - this->variables.push_tail(lv); - - return lv; -} - - -loop_terminator * -loop_variable_state::insert(ir_if *if_stmt) -{ - void *mem_ctx = talloc_parent(this); - loop_terminator *t = talloc_zero(mem_ctx, loop_terminator); - - t->ir = if_stmt; - this->terminators.push_tail(t); - - return t; -} - - -class loop_analysis : public ir_hierarchical_visitor { -public: - loop_analysis(); - - virtual ir_visitor_status visit(ir_loop_jump *); - virtual ir_visitor_status visit(ir_dereference_variable *); - - virtual ir_visitor_status visit_enter(ir_loop *); - virtual ir_visitor_status visit_leave(ir_loop *); - virtual ir_visitor_status visit_enter(ir_assignment *); - virtual ir_visitor_status visit_leave(ir_assignment *); - virtual ir_visitor_status visit_enter(ir_if *); - virtual ir_visitor_status visit_leave(ir_if *); - - loop_state *loops; - - int if_statement_depth; - - ir_assignment *current_assignment; - - exec_list state; -}; - - -loop_analysis::loop_analysis() -{ - this->loops = new loop_state; - - this->if_statement_depth = 0; - this->current_assignment = NULL; -} - - -ir_visitor_status -loop_analysis::visit(ir_loop_jump *ir) -{ - (void) ir; - - assert(!this->state.is_empty()); - - loop_variable_state *const ls = - (loop_variable_state *) this->state.get_head(); - - ls->num_loop_jumps++; - - return visit_continue; -} - - -ir_visitor_status -loop_analysis::visit(ir_dereference_variable *ir) -{ - /* If we're not somewhere inside a loop, there's nothing to do. - */ - if (this->state.is_empty()) - return visit_continue; - - loop_variable_state *const ls = - (loop_variable_state *) this->state.get_head(); - - ir_variable *var = ir->variable_referenced(); - loop_variable *lv = ls->get(var); - - if (lv == NULL) { - lv = ls->insert(var); - lv->read_before_write = !this->in_assignee; - } - - if (this->in_assignee) { - assert(this->current_assignment != NULL); - - lv->conditional_assignment = (this->if_statement_depth > 0) - || (this->current_assignment->condition != NULL); - - if (lv->first_assignment == NULL) { - assert(lv->num_assignments == 0); - - lv->first_assignment = this->current_assignment; - } - - lv->num_assignments++; - } else if (lv->first_assignment == this->current_assignment) { - /* This catches the case where the variable is used in the RHS of an - * assignment where it is also in the LHS. - */ - lv->read_before_write = true; - } - - return visit_continue; -} - -ir_visitor_status -loop_analysis::visit_enter(ir_loop *ir) -{ - loop_variable_state *ls = this->loops->insert(ir); - this->state.push_head(ls); - - return visit_continue; -} - -ir_visitor_status -loop_analysis::visit_leave(ir_loop *ir) -{ - loop_variable_state *const ls = - (loop_variable_state *) this->state.pop_head(); - - - foreach_list(node, &ir->body_instructions) { - /* Skip over declarations at the start of a loop. - */ - if (((ir_instruction *) node)->as_variable()) - continue; - - ir_if *if_stmt = ((ir_instruction *) node)->as_if(); - - if ((if_stmt != NULL) && is_loop_terminator(if_stmt)) - ls->insert(if_stmt); - else - break; - } - - - foreach_list_safe(node, &ls->variables) { - loop_variable *lv = (loop_variable *) node; - - /* Move variables that are already marked as being loop constant to - * a separate list. These trivially don't need to be tested. - */ - if (lv->is_loop_constant()) { - lv->remove(); - ls->constants.push_tail(lv); - } - } - - /* Each variable assigned in the loop that isn't already marked as being loop - * constant might still be loop constant. The requirements at this point - * are: - * - * - Variable is written before it is read. - * - * - Only one assignment to the variable. - * - * - All operands on the RHS of the assignment are also loop constants. - * - * The last requirement is the reason for the progress loop. A variable - * marked as a loop constant on one pass may allow other variables to be - * marked as loop constant on following passes. - */ - bool progress; - do { - progress = false; - - foreach_list_safe(node, &ls->variables) { - loop_variable *lv = (loop_variable *) node; - - if (lv->conditional_assignment || (lv->num_assignments > 1)) - continue; - - /* Process the RHS of the assignment. If all of the variables - * accessed there are loop constants, then add this - */ - ir_rvalue *const rhs = lv->first_assignment->rhs; - if (all_expression_operands_are_loop_constant(rhs, ls->var_hash)) { - lv->rhs_clean = true; - - if (lv->is_loop_constant()) { - progress = true; - - lv->remove(); - ls->constants.push_tail(lv); - } - } - } - } while (progress); - - /* The remaining variables that are not loop invariant might be loop - * induction variables. - */ - foreach_list_safe(node, &ls->variables) { - loop_variable *lv = (loop_variable *) node; - - /* If there is more than one assignment to a variable, it cannot be a - * loop induction variable. This isn't strictly true, but this is a - * very simple induction variable detector, and it can't handle more - * complex cases. - */ - if (lv->num_assignments > 1) - continue; - - /* All of the variables with zero assignments in the loop are loop - * invariant, and they should have already been filtered out. - */ - assert(lv->num_assignments == 1); - assert(lv->first_assignment != NULL); - - /* The assignmnet to the variable in the loop must be unconditional. - */ - if (lv->conditional_assignment) - continue; - - /* Basic loop induction variables have a single assignment in the loop - * that has the form 'VAR = VAR + i' or 'VAR = VAR - i' where i is a - * loop invariant. - */ - ir_rvalue *const inc = - get_basic_induction_increment(lv->first_assignment, ls->var_hash); - if (inc != NULL) { - lv->iv_scale = NULL; - lv->biv = lv->var; - lv->increment = inc; - - lv->remove(); - ls->induction_variables.push_tail(lv); - } - } - - return visit_continue; -} - -ir_visitor_status -loop_analysis::visit_enter(ir_if *ir) -{ - (void) ir; - - if (!this->state.is_empty()) - this->if_statement_depth++; - - return visit_continue; -} - -ir_visitor_status -loop_analysis::visit_leave(ir_if *ir) -{ - (void) ir; - - if (!this->state.is_empty()) - this->if_statement_depth--; - - return visit_continue; -} - -ir_visitor_status -loop_analysis::visit_enter(ir_assignment *ir) -{ - /* If we're not somewhere inside a loop, there's nothing to do. - */ - if (this->state.is_empty()) - return visit_continue_with_parent; - - this->current_assignment = ir; - - return visit_continue; -} - -ir_visitor_status -loop_analysis::visit_leave(ir_assignment *ir) -{ - /* Since the visit_enter exits with visit_continue_with_parent for this - * case, the loop state stack should never be empty here. - */ - assert(!this->state.is_empty()); - - assert(this->current_assignment == ir); - this->current_assignment = NULL; - - return visit_continue; -} - - -class examine_rhs : public ir_hierarchical_visitor { -public: - examine_rhs(hash_table *loop_variables) - { - this->only_uses_loop_constants = true; - this->loop_variables = loop_variables; - } - - virtual ir_visitor_status visit(ir_dereference_variable *ir) - { - loop_variable *lv = - (loop_variable *) hash_table_find(this->loop_variables, ir->var); - - assert(lv != NULL); - - if (lv->is_loop_constant()) { - return visit_continue; - } else { - this->only_uses_loop_constants = false; - return visit_stop; - } - } - - hash_table *loop_variables; - bool only_uses_loop_constants; -}; - - -bool -all_expression_operands_are_loop_constant(ir_rvalue *ir, hash_table *variables) -{ - examine_rhs v(variables); - - ir->accept(&v); - - return v.only_uses_loop_constants; -} - - -ir_rvalue * -get_basic_induction_increment(ir_assignment *ir, hash_table *var_hash) -{ - /* The RHS must be a binary expression. - */ - ir_expression *const rhs = ir->rhs->as_expression(); - if ((rhs == NULL) - || ((rhs->operation != ir_binop_add) - && (rhs->operation != ir_binop_sub))) - return NULL; - - /* One of the of operands of the expression must be the variable assigned. - * If the operation is subtraction, the variable in question must be the - * "left" operand. - */ - ir_variable *const var = ir->lhs->variable_referenced(); - - ir_variable *const op0 = rhs->operands[0]->variable_referenced(); - ir_variable *const op1 = rhs->operands[1]->variable_referenced(); - - if (((op0 != var) && (op1 != var)) - || ((op1 == var) && (rhs->operation == ir_binop_sub))) - return NULL; - - ir_rvalue *inc = (op0 == var) ? rhs->operands[1] : rhs->operands[0]; - - if (inc->as_constant() == NULL) { - ir_variable *const inc_var = inc->variable_referenced(); - if (inc_var != NULL) { - loop_variable *lv = - (loop_variable *) hash_table_find(var_hash, inc_var); - - if (!lv->is_loop_constant()) - inc = NULL; - } else - inc = NULL; - } - - if ((inc != NULL) && (rhs->operation == ir_binop_sub)) { - void *mem_ctx = talloc_parent(ir); - - inc = new(mem_ctx) ir_expression(ir_unop_neg, - inc->type, - inc->clone(mem_ctx, NULL), - NULL); - } - - return inc; -} - - -/** - * Detect whether an if-statement is a loop terminating condition - * - * Detects if-statements of the form - * - * (if (expression bool ...) (break)) - */ -bool -is_loop_terminator(ir_if *ir) -{ - if (!ir->else_instructions.is_empty()) - return false; - - ir_instruction *const inst = - (ir_instruction *) ir->then_instructions.get_head(); - assert(inst != NULL); - - if (inst->ir_type != ir_type_loop_jump) - return false; - - ir_loop_jump *const jump = (ir_loop_jump *) inst; - if (jump->mode != ir_loop_jump::jump_break) - return false; - - return true; -} - - -loop_state * -analyze_loop_variables(exec_list *instructions) -{ - loop_analysis v; - - v.run(instructions); - return v.loops; -} +/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glsl_types.h"
+#include "loop_analysis.h"
+#include "ir_hierarchical_visitor.h"
+
+static bool is_loop_terminator(ir_if *ir);
+
+static bool all_expression_operands_are_loop_constant(ir_rvalue *,
+ hash_table *);
+
+static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table *);
+
+
+loop_state::loop_state()
+{
+ this->ht = hash_table_ctor(0, hash_table_pointer_hash,
+ hash_table_pointer_compare);
+ this->mem_ctx = talloc_init("loop state");
+}
+
+
+loop_state::~loop_state()
+{
+ hash_table_dtor(this->ht);
+ talloc_free(this->mem_ctx);
+}
+
+
+loop_variable_state *
+loop_state::insert(ir_loop *ir)
+{
+ loop_variable_state *ls = new(this->mem_ctx) loop_variable_state;
+ hash_table_insert(this->ht, ls, ir);
+
+ return ls;
+}
+
+
+loop_variable_state *
+loop_state::get(const ir_loop *ir)
+{
+ return (loop_variable_state *) hash_table_find(this->ht, ir);
+}
+
+
+loop_variable *
+loop_variable_state::get(const ir_variable *ir)
+{
+ return (loop_variable *) hash_table_find(this->var_hash, ir);
+}
+
+
+loop_variable *
+loop_variable_state::insert(ir_variable *var)
+{
+ void *mem_ctx = talloc_parent(this);
+ loop_variable *lv = talloc_zero(mem_ctx, loop_variable);
+
+ lv->var = var;
+
+ hash_table_insert(this->var_hash, lv, lv->var);
+ this->variables.push_tail(lv);
+
+ return lv;
+}
+
+
+loop_terminator *
+loop_variable_state::insert(ir_if *if_stmt)
+{
+ void *mem_ctx = talloc_parent(this);
+ loop_terminator *t = talloc_zero(mem_ctx, loop_terminator);
+
+ t->ir = if_stmt;
+ this->terminators.push_tail(t);
+
+ return t;
+}
+
+
+class loop_analysis : public ir_hierarchical_visitor {
+public:
+ loop_analysis();
+
+ virtual ir_visitor_status visit(ir_loop_jump *);
+ virtual ir_visitor_status visit(ir_dereference_variable *);
+
+ virtual ir_visitor_status visit_enter(ir_loop *);
+ virtual ir_visitor_status visit_leave(ir_loop *);
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+ virtual ir_visitor_status visit_leave(ir_assignment *);
+ virtual ir_visitor_status visit_enter(ir_if *);
+ virtual ir_visitor_status visit_leave(ir_if *);
+
+ loop_state *loops;
+
+ int if_statement_depth;
+
+ ir_assignment *current_assignment;
+
+ exec_list state;
+};
+
+
+loop_analysis::loop_analysis()
+{
+ this->loops = new loop_state;
+
+ this->if_statement_depth = 0;
+ this->current_assignment = NULL;
+}
+
+
+ir_visitor_status
+loop_analysis::visit(ir_loop_jump *ir)
+{
+ (void) ir;
+
+ assert(!this->state.is_empty());
+
+ loop_variable_state *const ls =
+ (loop_variable_state *) this->state.get_head();
+
+ ls->num_loop_jumps++;
+
+ return visit_continue;
+}
+
+
+ir_visitor_status
+loop_analysis::visit(ir_dereference_variable *ir)
+{
+ /* If we're not somewhere inside a loop, there's nothing to do.
+ */
+ if (this->state.is_empty())
+ return visit_continue;
+
+ loop_variable_state *const ls =
+ (loop_variable_state *) this->state.get_head();
+
+ ir_variable *var = ir->variable_referenced();
+ loop_variable *lv = ls->get(var);
+
+ if (lv == NULL) {
+ lv = ls->insert(var);
+ lv->read_before_write = !this->in_assignee;
+ }
+
+ if (this->in_assignee) {
+ assert(this->current_assignment != NULL);
+
+ lv->conditional_assignment = (this->if_statement_depth > 0)
+ || (this->current_assignment->condition != NULL);
+
+ if (lv->first_assignment == NULL) {
+ assert(lv->num_assignments == 0);
+
+ lv->first_assignment = this->current_assignment;
+ }
+
+ lv->num_assignments++;
+ } else if (lv->first_assignment == this->current_assignment) {
+ /* This catches the case where the variable is used in the RHS of an
+ * assignment where it is also in the LHS.
+ */
+ lv->read_before_write = true;
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+loop_analysis::visit_enter(ir_loop *ir)
+{
+ loop_variable_state *ls = this->loops->insert(ir);
+ this->state.push_head(ls);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+loop_analysis::visit_leave(ir_loop *ir)
+{
+ loop_variable_state *const ls =
+ (loop_variable_state *) this->state.pop_head();
+
+
+ foreach_list(node, &ir->body_instructions) {
+ /* Skip over declarations at the start of a loop.
+ */
+ if (((ir_instruction *) node)->as_variable())
+ continue;
+
+ ir_if *if_stmt = ((ir_instruction *) node)->as_if();
+
+ if ((if_stmt != NULL) && is_loop_terminator(if_stmt))
+ ls->insert(if_stmt);
+ else
+ break;
+ }
+
+
+ foreach_list_safe(node, &ls->variables) {
+ loop_variable *lv = (loop_variable *) node;
+
+ /* Move variables that are already marked as being loop constant to
+ * a separate list. These trivially don't need to be tested.
+ */
+ if (lv->is_loop_constant()) {
+ lv->remove();
+ ls->constants.push_tail(lv);
+ }
+ }
+
+ /* Each variable assigned in the loop that isn't already marked as being loop
+ * constant might still be loop constant. The requirements at this point
+ * are:
+ *
+ * - Variable is written before it is read.
+ *
+ * - Only one assignment to the variable.
+ *
+ * - All operands on the RHS of the assignment are also loop constants.
+ *
+ * The last requirement is the reason for the progress loop. A variable
+ * marked as a loop constant on one pass may allow other variables to be
+ * marked as loop constant on following passes.
+ */
+ bool progress;
+ do {
+ progress = false;
+
+ foreach_list_safe(node, &ls->variables) {
+ loop_variable *lv = (loop_variable *) node;
+
+ if (lv->conditional_assignment || (lv->num_assignments > 1))
+ continue;
+
+ /* Process the RHS of the assignment. If all of the variables
+ * accessed there are loop constants, then add this
+ */
+ ir_rvalue *const rhs = lv->first_assignment->rhs;
+ if (all_expression_operands_are_loop_constant(rhs, ls->var_hash)) {
+ lv->rhs_clean = true;
+
+ if (lv->is_loop_constant()) {
+ progress = true;
+
+ lv->remove();
+ ls->constants.push_tail(lv);
+ }
+ }
+ }
+ } while (progress);
+
+ /* The remaining variables that are not loop invariant might be loop
+ * induction variables.
+ */
+ foreach_list_safe(node, &ls->variables) {
+ loop_variable *lv = (loop_variable *) node;
+
+ /* If there is more than one assignment to a variable, it cannot be a
+ * loop induction variable. This isn't strictly true, but this is a
+ * very simple induction variable detector, and it can't handle more
+ * complex cases.
+ */
+ if (lv->num_assignments > 1)
+ continue;
+
+ /* All of the variables with zero assignments in the loop are loop
+ * invariant, and they should have already been filtered out.
+ */
+ assert(lv->num_assignments == 1);
+ assert(lv->first_assignment != NULL);
+
+ /* The assignmnet to the variable in the loop must be unconditional.
+ */
+ if (lv->conditional_assignment)
+ continue;
+
+ /* Basic loop induction variables have a single assignment in the loop
+ * that has the form 'VAR = VAR + i' or 'VAR = VAR - i' where i is a
+ * loop invariant.
+ */
+ ir_rvalue *const inc =
+ get_basic_induction_increment(lv->first_assignment, ls->var_hash);
+ if (inc != NULL) {
+ lv->iv_scale = NULL;
+ lv->biv = lv->var;
+ lv->increment = inc;
+
+ lv->remove();
+ ls->induction_variables.push_tail(lv);
+ }
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+loop_analysis::visit_enter(ir_if *ir)
+{
+ (void) ir;
+
+ if (!this->state.is_empty())
+ this->if_statement_depth++;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+loop_analysis::visit_leave(ir_if *ir)
+{
+ (void) ir;
+
+ if (!this->state.is_empty())
+ this->if_statement_depth--;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+loop_analysis::visit_enter(ir_assignment *ir)
+{
+ /* If we're not somewhere inside a loop, there's nothing to do.
+ */
+ if (this->state.is_empty())
+ return visit_continue_with_parent;
+
+ this->current_assignment = ir;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+loop_analysis::visit_leave(ir_assignment *ir)
+{
+ /* Since the visit_enter exits with visit_continue_with_parent for this
+ * case, the loop state stack should never be empty here.
+ */
+ assert(!this->state.is_empty());
+
+ assert(this->current_assignment == ir);
+ this->current_assignment = NULL;
+
+ return visit_continue;
+}
+
+
+class examine_rhs : public ir_hierarchical_visitor {
+public:
+ examine_rhs(hash_table *loop_variables)
+ {
+ this->only_uses_loop_constants = true;
+ this->loop_variables = loop_variables;
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ loop_variable *lv =
+ (loop_variable *) hash_table_find(this->loop_variables, ir->var);
+
+ assert(lv != NULL);
+
+ if (lv->is_loop_constant()) {
+ return visit_continue;
+ } else {
+ this->only_uses_loop_constants = false;
+ return visit_stop;
+ }
+ }
+
+ hash_table *loop_variables;
+ bool only_uses_loop_constants;
+};
+
+
+bool
+all_expression_operands_are_loop_constant(ir_rvalue *ir, hash_table *variables)
+{
+ examine_rhs v(variables);
+
+ ir->accept(&v);
+
+ return v.only_uses_loop_constants;
+}
+
+
+ir_rvalue *
+get_basic_induction_increment(ir_assignment *ir, hash_table *var_hash)
+{
+ /* The RHS must be a binary expression.
+ */
+ ir_expression *const rhs = ir->rhs->as_expression();
+ if ((rhs == NULL)
+ || ((rhs->operation != ir_binop_add)
+ && (rhs->operation != ir_binop_sub)))
+ return NULL;
+
+ /* One of the of operands of the expression must be the variable assigned.
+ * If the operation is subtraction, the variable in question must be the
+ * "left" operand.
+ */
+ ir_variable *const var = ir->lhs->variable_referenced();
+
+ ir_variable *const op0 = rhs->operands[0]->variable_referenced();
+ ir_variable *const op1 = rhs->operands[1]->variable_referenced();
+
+ if (((op0 != var) && (op1 != var))
+ || ((op1 == var) && (rhs->operation == ir_binop_sub)))
+ return NULL;
+
+ ir_rvalue *inc = (op0 == var) ? rhs->operands[1] : rhs->operands[0];
+
+ if (inc->as_constant() == NULL) {
+ ir_variable *const inc_var = inc->variable_referenced();
+ if (inc_var != NULL) {
+ loop_variable *lv =
+ (loop_variable *) hash_table_find(var_hash, inc_var);
+
+ if (!lv->is_loop_constant())
+ inc = NULL;
+ } else
+ inc = NULL;
+ }
+
+ if ((inc != NULL) && (rhs->operation == ir_binop_sub)) {
+ void *mem_ctx = talloc_parent(ir);
+
+ inc = new(mem_ctx) ir_expression(ir_unop_neg,
+ inc->type,
+ inc->clone(mem_ctx, NULL),
+ NULL);
+ }
+
+ return inc;
+}
+
+
+/**
+ * Detect whether an if-statement is a loop terminating condition
+ *
+ * Detects if-statements of the form
+ *
+ * (if (expression bool ...) (break))
+ */
+bool
+is_loop_terminator(ir_if *ir)
+{
+ if (!ir->else_instructions.is_empty())
+ return false;
+
+ ir_instruction *const inst =
+ (ir_instruction *) ir->then_instructions.get_head();
+ assert(inst != NULL);
+
+ if (inst->ir_type != ir_type_loop_jump)
+ return false;
+
+ ir_loop_jump *const jump = (ir_loop_jump *) inst;
+ if (jump->mode != ir_loop_jump::jump_break)
+ return false;
+
+ return true;
+}
+
+
+loop_state *
+analyze_loop_variables(exec_list *instructions)
+{
+ loop_analysis v;
+
+ v.run(instructions);
+ return v.loops;
+}
diff --git a/mesalib/src/glsl/loop_controls.cpp b/mesalib/src/glsl/loop_controls.cpp index 2ef3d3052..fb13439a1 100644 --- a/mesalib/src/glsl/loop_controls.cpp +++ b/mesalib/src/glsl/loop_controls.cpp @@ -1,301 +1,304 @@ -/* - * 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 <climits> -#include "main/compiler.h" -#include "glsl_types.h" -#include "loop_analysis.h" -#include "ir_hierarchical_visitor.h" - -/** - * Find an initializer of a variable outside a loop - * - * Works backwards from the loop to find the pre-loop value of the variable. - * This is used, for example, to find the initial value of loop induction - * variables. - * - * \param loop Loop where \c var is an induction variable - * \param var Variable whose initializer is to be found - * - * \return - * The \c ir_rvalue assigned to the variable outside the loop. May return - * \c NULL if no initializer can be found. - */ -ir_rvalue * -find_initial_value(ir_loop *loop, ir_variable *var) -{ - for (exec_node *node = loop->prev; - !node->is_head_sentinel(); - node = node->prev) { - ir_instruction *ir = (ir_instruction *) node; - - switch (ir->ir_type) { - case ir_type_call: - case ir_type_loop: - case ir_type_loop_jump: - case ir_type_return: - case ir_type_if: - return NULL; - - case ir_type_function: - case ir_type_function_signature: - assert(!"Should not get here."); - return NULL; - - case ir_type_assignment: { - ir_assignment *assign = ir->as_assignment(); - ir_variable *assignee = assign->lhs->whole_variable_referenced(); - - if (assignee == var) - return (assign->condition != NULL) ? NULL : assign->rhs; - - break; - } - - default: - break; - } - } - - return NULL; -} - - -int -calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment, - enum ir_expression_operation op) -{ - void *mem_ctx = talloc_init("%s", __func__); - - ir_expression *const sub = - new(mem_ctx) ir_expression(ir_binop_sub, from->type, to, from); - - ir_expression *const div = - new(mem_ctx) ir_expression(ir_binop_div, sub->type, sub, increment); - - ir_constant *iter = div->constant_expression_value(); - - if (iter == NULL) - return -1; - - if (!iter->type->is_integer()) { - ir_rvalue *cast = - new(mem_ctx) ir_expression(ir_unop_f2i, glsl_type::int_type, iter, - NULL); - - iter = cast->constant_expression_value(); - } - - int iter_value = iter->get_int_component(0); - - /* Make sure that the calculated number of iterations satisfies the exit - * condition. This is needed to catch off-by-one errors and some types of - * ill-formed loops. For example, we need to detect that the following - * loop does not have a maximum iteration count. - * - * for (float x = 0.0; x != 0.9; x += 0.2) - * ; - */ - const int bias[] = { -1, 0, 1 }; - bool valid_loop = false; - - for (unsigned i = 0; i < Elements(bias); i++) { - iter = (increment->type->is_integer()) - ? new(mem_ctx) ir_constant(iter_value + bias[i]) - : new(mem_ctx) ir_constant(float(iter_value + bias[i])); - - ir_expression *const mul = - new(mem_ctx) ir_expression(ir_binop_mul, increment->type, iter, - increment); - - ir_expression *const add = - new(mem_ctx) ir_expression(ir_binop_add, mul->type, mul, from); - - ir_expression *const cmp = - new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to); - - ir_constant *const cmp_result = cmp->constant_expression_value(); - - assert(cmp_result != NULL); - if (cmp_result->get_bool_component(0)) { - iter_value += bias[i]; - valid_loop = true; - break; - } - } - - talloc_free(mem_ctx); - return (valid_loop) ? iter_value : -1; -} - - -class loop_control_visitor : public ir_hierarchical_visitor { -public: - loop_control_visitor(loop_state *state) - { - this->state = state; - this->progress = false; - } - - virtual ir_visitor_status visit_leave(ir_loop *ir); - - loop_state *state; - - bool progress; -}; - - -ir_visitor_status -loop_control_visitor::visit_leave(ir_loop *ir) -{ - loop_variable_state *const ls = this->state->get(ir); - - /* If we've entered a loop that hasn't been analyzed, something really, - * really bad has happened. - */ - if (ls == NULL) { - assert(ls != NULL); - return visit_continue; - } - - /* Search the loop terminating conditions for one of the form 'i < c' where - * i is a loop induction variable, c is a constant, and < is any relative - * operator. - */ - int max_iterations = ls->max_iterations; - - if(ir->from && ir->to && ir->increment) - max_iterations = calculate_iterations(ir->from, ir->to, ir->increment, (ir_expression_operation)ir->cmp); - - if(max_iterations < 0) - max_iterations = INT_MAX; - - foreach_list(node, &ls->terminators) { - loop_terminator *t = (loop_terminator *) node; - ir_if *if_stmt = t->ir; - - /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care - * about the former here. - */ - ir_expression *cond = if_stmt->condition->as_expression(); - if (cond == NULL) - continue; - - switch (cond->operation) { - case ir_binop_less: - case ir_binop_greater: - case ir_binop_lequal: - case ir_binop_gequal: { - /* The expressions that we care about will either be of the form - * 'counter < limit' or 'limit < counter'. Figure out which is - * which. - */ - ir_rvalue *counter = cond->operands[0]->as_dereference_variable(); - ir_constant *limit = cond->operands[1]->as_constant(); - enum ir_expression_operation cmp = cond->operation; - - if (limit == NULL) { - counter = cond->operands[1]->as_dereference_variable(); - limit = cond->operands[0]->as_constant(); - - switch (cmp) { - case ir_binop_less: cmp = ir_binop_gequal; break; - case ir_binop_greater: cmp = ir_binop_lequal; break; - case ir_binop_lequal: cmp = ir_binop_greater; break; - case ir_binop_gequal: cmp = ir_binop_less; break; - default: assert(!"Should not get here."); - } - } - - if ((counter == NULL) || (limit == NULL)) - break; - - ir_variable *var = counter->variable_referenced(); - - ir_rvalue *init = find_initial_value(ir, var); - - foreach_list(iv_node, &ls->induction_variables) { - loop_variable *lv = (loop_variable *) iv_node; - - if (lv->var == var) { - const int iterations = calculate_iterations(init, limit, - lv->increment, - cmp); - if (iterations >= 0) { - /* If the new iteration count is lower than the previously - * believed iteration count, update the loop control values. - */ - if (iterations < max_iterations) { - ir->from = init->clone(ir, NULL); - ir->to = limit->clone(ir, NULL); - ir->increment = lv->increment->clone(ir, NULL); - ir->counter = lv->var; - ir->cmp = cmp; - - max_iterations = iterations; - } - - /* Remove the conditional break statement. The loop - * controls are now set such that the exit condition will be - * satisfied. - */ - if_stmt->remove(); - - assert(ls->num_loop_jumps > 0); - ls->num_loop_jumps--; - - this->progress = true; - } - - break; - } - } - break; - } - - default: - break; - } - } - - /* If we have proven the one of the loop exit conditions is satisifed before - * running the loop once, remove the loop. - */ - if (max_iterations == 0) - ir->remove(); - else - ls->max_iterations = max_iterations; - - return visit_continue; -} - - -bool -set_loop_controls(exec_list *instructions, loop_state *ls) -{ - loop_control_visitor v(ls); - - v.run(instructions); - - return v.progress; -} +/*
+ * 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 <climits>
+#include "main/compiler.h"
+#include "glsl_types.h"
+#include "loop_analysis.h"
+#include "ir_hierarchical_visitor.h"
+
+/**
+ * Find an initializer of a variable outside a loop
+ *
+ * Works backwards from the loop to find the pre-loop value of the variable.
+ * This is used, for example, to find the initial value of loop induction
+ * variables.
+ *
+ * \param loop Loop where \c var is an induction variable
+ * \param var Variable whose initializer is to be found
+ *
+ * \return
+ * The \c ir_rvalue assigned to the variable outside the loop. May return
+ * \c NULL if no initializer can be found.
+ */
+ir_rvalue *
+find_initial_value(ir_loop *loop, ir_variable *var)
+{
+ for (exec_node *node = loop->prev;
+ !node->is_head_sentinel();
+ node = node->prev) {
+ ir_instruction *ir = (ir_instruction *) node;
+
+ switch (ir->ir_type) {
+ case ir_type_call:
+ case ir_type_loop:
+ case ir_type_loop_jump:
+ case ir_type_return:
+ case ir_type_if:
+ return NULL;
+
+ case ir_type_function:
+ case ir_type_function_signature:
+ assert(!"Should not get here.");
+ return NULL;
+
+ case ir_type_assignment: {
+ ir_assignment *assign = ir->as_assignment();
+ ir_variable *assignee = assign->lhs->whole_variable_referenced();
+
+ if (assignee == var)
+ return (assign->condition != NULL) ? NULL : assign->rhs;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+
+int
+calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
+ enum ir_expression_operation op)
+{
+ if (from == NULL || to == NULL || increment == NULL)
+ return -1;
+
+ void *mem_ctx = talloc_init("%s", __func__);
+
+ ir_expression *const sub =
+ new(mem_ctx) ir_expression(ir_binop_sub, from->type, to, from);
+
+ ir_expression *const div =
+ new(mem_ctx) ir_expression(ir_binop_div, sub->type, sub, increment);
+
+ ir_constant *iter = div->constant_expression_value();
+
+ if (iter == NULL)
+ return -1;
+
+ if (!iter->type->is_integer()) {
+ ir_rvalue *cast =
+ new(mem_ctx) ir_expression(ir_unop_f2i, glsl_type::int_type, iter,
+ NULL);
+
+ iter = cast->constant_expression_value();
+ }
+
+ int iter_value = iter->get_int_component(0);
+
+ /* Make sure that the calculated number of iterations satisfies the exit
+ * condition. This is needed to catch off-by-one errors and some types of
+ * ill-formed loops. For example, we need to detect that the following
+ * loop does not have a maximum iteration count.
+ *
+ * for (float x = 0.0; x != 0.9; x += 0.2)
+ * ;
+ */
+ const int bias[] = { -1, 0, 1 };
+ bool valid_loop = false;
+
+ for (unsigned i = 0; i < Elements(bias); i++) {
+ iter = (increment->type->is_integer())
+ ? new(mem_ctx) ir_constant(iter_value + bias[i])
+ : new(mem_ctx) ir_constant(float(iter_value + bias[i]));
+
+ ir_expression *const mul =
+ new(mem_ctx) ir_expression(ir_binop_mul, increment->type, iter,
+ increment);
+
+ ir_expression *const add =
+ new(mem_ctx) ir_expression(ir_binop_add, mul->type, mul, from);
+
+ ir_expression *const cmp =
+ new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to);
+
+ ir_constant *const cmp_result = cmp->constant_expression_value();
+
+ assert(cmp_result != NULL);
+ if (cmp_result->get_bool_component(0)) {
+ iter_value += bias[i];
+ valid_loop = true;
+ break;
+ }
+ }
+
+ talloc_free(mem_ctx);
+ return (valid_loop) ? iter_value : -1;
+}
+
+
+class loop_control_visitor : public ir_hierarchical_visitor {
+public:
+ loop_control_visitor(loop_state *state)
+ {
+ this->state = state;
+ this->progress = false;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_loop *ir);
+
+ loop_state *state;
+
+ bool progress;
+};
+
+
+ir_visitor_status
+loop_control_visitor::visit_leave(ir_loop *ir)
+{
+ loop_variable_state *const ls = this->state->get(ir);
+
+ /* If we've entered a loop that hasn't been analyzed, something really,
+ * really bad has happened.
+ */
+ if (ls == NULL) {
+ assert(ls != NULL);
+ return visit_continue;
+ }
+
+ /* Search the loop terminating conditions for one of the form 'i < c' where
+ * i is a loop induction variable, c is a constant, and < is any relative
+ * operator.
+ */
+ int max_iterations = ls->max_iterations;
+
+ if(ir->from && ir->to && ir->increment)
+ max_iterations = calculate_iterations(ir->from, ir->to, ir->increment, (ir_expression_operation)ir->cmp);
+
+ if(max_iterations < 0)
+ max_iterations = INT_MAX;
+
+ foreach_list(node, &ls->terminators) {
+ loop_terminator *t = (loop_terminator *) node;
+ ir_if *if_stmt = t->ir;
+
+ /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care
+ * about the former here.
+ */
+ ir_expression *cond = if_stmt->condition->as_expression();
+ if (cond == NULL)
+ continue;
+
+ switch (cond->operation) {
+ case ir_binop_less:
+ case ir_binop_greater:
+ case ir_binop_lequal:
+ case ir_binop_gequal: {
+ /* The expressions that we care about will either be of the form
+ * 'counter < limit' or 'limit < counter'. Figure out which is
+ * which.
+ */
+ ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
+ ir_constant *limit = cond->operands[1]->as_constant();
+ enum ir_expression_operation cmp = cond->operation;
+
+ if (limit == NULL) {
+ counter = cond->operands[1]->as_dereference_variable();
+ limit = cond->operands[0]->as_constant();
+
+ switch (cmp) {
+ case ir_binop_less: cmp = ir_binop_gequal; break;
+ case ir_binop_greater: cmp = ir_binop_lequal; break;
+ case ir_binop_lequal: cmp = ir_binop_greater; break;
+ case ir_binop_gequal: cmp = ir_binop_less; break;
+ default: assert(!"Should not get here.");
+ }
+ }
+
+ if ((counter == NULL) || (limit == NULL))
+ break;
+
+ ir_variable *var = counter->variable_referenced();
+
+ ir_rvalue *init = find_initial_value(ir, var);
+
+ foreach_list(iv_node, &ls->induction_variables) {
+ loop_variable *lv = (loop_variable *) iv_node;
+
+ if (lv->var == var) {
+ const int iterations = calculate_iterations(init, limit,
+ lv->increment,
+ cmp);
+ if (iterations >= 0) {
+ /* If the new iteration count is lower than the previously
+ * believed iteration count, update the loop control values.
+ */
+ if (iterations < max_iterations) {
+ ir->from = init->clone(ir, NULL);
+ ir->to = limit->clone(ir, NULL);
+ ir->increment = lv->increment->clone(ir, NULL);
+ ir->counter = lv->var;
+ ir->cmp = cmp;
+
+ max_iterations = iterations;
+ }
+
+ /* Remove the conditional break statement. The loop
+ * controls are now set such that the exit condition will be
+ * satisfied.
+ */
+ if_stmt->remove();
+
+ assert(ls->num_loop_jumps > 0);
+ ls->num_loop_jumps--;
+
+ this->progress = true;
+ }
+
+ break;
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ /* If we have proven the one of the loop exit conditions is satisifed before
+ * running the loop once, remove the loop.
+ */
+ if (max_iterations == 0)
+ ir->remove();
+ else
+ ls->max_iterations = max_iterations;
+
+ return visit_continue;
+}
+
+
+bool
+set_loop_controls(exec_list *instructions, loop_state *ls)
+{
+ loop_control_visitor v(ls);
+
+ v.run(instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/loop_unroll.cpp b/mesalib/src/glsl/loop_unroll.cpp index 90797bde3..c54f2ca3d 100644 --- a/mesalib/src/glsl/loop_unroll.cpp +++ b/mesalib/src/glsl/loop_unroll.cpp @@ -1,187 +1,214 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "glsl_types.h" -#include "loop_analysis.h" -#include "ir_hierarchical_visitor.h" - -class loop_unroll_visitor : public ir_hierarchical_visitor { -public: - loop_unroll_visitor(loop_state *state, unsigned max_iterations) - { - this->state = state; - this->progress = false; - this->max_iterations = max_iterations; - } - - virtual ir_visitor_status visit_leave(ir_loop *ir); - - loop_state *state; - - bool progress; - unsigned max_iterations; -}; - - -ir_visitor_status -loop_unroll_visitor::visit_leave(ir_loop *ir) -{ - loop_variable_state *const ls = this->state->get(ir); - int iterations; - - /* If we've entered a loop that hasn't been analyzed, something really, - * really bad has happened. - */ - if (ls == NULL) { - assert(ls != NULL); - return visit_continue; - } - - iterations = ls->max_iterations; - - /* Don't try to unroll loops where the number of iterations is not known - * at compile-time. - */ - if (iterations < 0) - return visit_continue; - - /* Don't try to unroll loops that have zillions of iterations either. - */ - if (iterations > max_iterations) - return visit_continue; - - if (ls->num_loop_jumps > 1) - return visit_continue; - else if (ls->num_loop_jumps) { - /* recognize loops in the form produced by ir_lower_jumps */ - ir_instruction *last_ir = - ((ir_instruction*)ir->body_instructions.get_tail()); - - assert(last_ir != NULL); - - ir_if *last_if = last_ir->as_if(); - if (last_if) { - bool continue_from_then_branch; - - /* Determine which if-statement branch, if any, ends with a break. - * The branch that did *not* have the break will get a temporary - * continue inserted in each iteration of the loop unroll. - * - * Note that since ls->num_loop_jumps is <= 1, it is impossible for - * both branches to end with a break. - */ - ir_instruction *last = - (ir_instruction *) last_if->then_instructions.get_tail(); - - if (last && last->ir_type == ir_type_loop_jump - && ((ir_loop_jump*) last)->is_break()) { - continue_from_then_branch = false; - } else { - last = (ir_instruction *) last_if->then_instructions.get_tail(); - - if (last && last->ir_type == ir_type_loop_jump - && ((ir_loop_jump*) last)->is_break()) - continue_from_then_branch = true; - else - /* Bail out if neither if-statement branch ends with a break. - */ - return visit_continue; - } - - /* Remove the break from the if-statement. - */ - last->remove(); - - void *const mem_ctx = talloc_parent(ir); - ir_instruction *ir_to_replace = ir; - - for (int i = 0; i < iterations; i++) { - exec_list copy_list; - - copy_list.make_empty(); - clone_ir_list(mem_ctx, ©_list, &ir->body_instructions); - - last_if = ((ir_instruction*)copy_list.get_tail())->as_if(); - assert(last_if); - - ir_to_replace->insert_before(©_list); - ir_to_replace->remove(); - - /* placeholder that will be removed in the next iteration */ - ir_to_replace = - new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue); - - exec_list *const list = (continue_from_then_branch) - ? &last_if->then_instructions : &last_if->else_instructions; - - list->push_tail(ir_to_replace); - } - - ir_to_replace->remove(); - - this->progress = true; - return visit_continue; - } else if (last_ir->ir_type == ir_type_loop_jump - && ((ir_loop_jump *)last_ir)->is_break()) { - /* If the only loop-jump is a break at the end of the loop, the loop - * will execute exactly once. Remove the break, set the iteration - * count, and fall through to the normal unroller. - */ - last_ir->remove(); - iterations = 1; - - this->progress = true; - } else - return visit_continue; - } - - void *const mem_ctx = talloc_parent(ir); - - for (int i = 0; i < iterations; i++) { - exec_list copy_list; - - copy_list.make_empty(); - clone_ir_list(mem_ctx, ©_list, &ir->body_instructions); - - ir->insert_before(©_list); - } - - /* The loop has been replaced by the unrolled copies. Remove the original - * loop from the IR sequence. - */ - ir->remove(); - - this->progress = true; - return visit_continue; -} - - -bool -unroll_loops(exec_list *instructions, loop_state *ls, unsigned max_iterations) -{ - loop_unroll_visitor v(ls, max_iterations); - - v.run(instructions); - - return v.progress; -} +/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glsl_types.h"
+#include "loop_analysis.h"
+#include "ir_hierarchical_visitor.h"
+
+class loop_unroll_visitor : public ir_hierarchical_visitor {
+public:
+ loop_unroll_visitor(loop_state *state, unsigned max_iterations)
+ {
+ this->state = state;
+ this->progress = false;
+ this->max_iterations = max_iterations;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_loop *ir);
+
+ loop_state *state;
+
+ bool progress;
+ unsigned max_iterations;
+};
+
+
+static bool
+is_break(ir_instruction *ir)
+{
+ return ir != NULL && ir->ir_type == ir_type_loop_jump
+ && ((ir_loop_jump *) ir)->is_break();
+}
+
+
+ir_visitor_status
+loop_unroll_visitor::visit_leave(ir_loop *ir)
+{
+ loop_variable_state *const ls = this->state->get(ir);
+ int iterations;
+
+ /* If we've entered a loop that hasn't been analyzed, something really,
+ * really bad has happened.
+ */
+ if (ls == NULL) {
+ assert(ls != NULL);
+ return visit_continue;
+ }
+
+ iterations = ls->max_iterations;
+
+ /* Don't try to unroll loops where the number of iterations is not known
+ * at compile-time.
+ */
+ if (iterations < 0)
+ return visit_continue;
+
+ /* Don't try to unroll loops that have zillions of iterations either.
+ */
+ if (iterations > (int) max_iterations)
+ return visit_continue;
+
+ if (ls->num_loop_jumps > 1)
+ return visit_continue;
+ else if (ls->num_loop_jumps) {
+ ir_instruction *last_ir = (ir_instruction *) ir->body_instructions.get_tail();
+ assert(last_ir != NULL);
+
+ if (is_break(last_ir)) {
+ /* If the only loop-jump is a break at the end of the loop, the loop
+ * will execute exactly once. Remove the break, set the iteration
+ * count, and fall through to the normal unroller.
+ */
+ last_ir->remove();
+ iterations = 1;
+
+ this->progress = true;
+ } else {
+ ir_if *ir_if = NULL;
+ ir_instruction *break_ir = NULL;
+ bool continue_from_then_branch = false;
+
+ foreach_list(node, &ir->body_instructions) {
+ /* recognize loops in the form produced by ir_lower_jumps */
+ ir_instruction *cur_ir = (ir_instruction *) node;
+
+ ir_if = cur_ir->as_if();
+ if (ir_if != NULL) {
+ /* Determine which if-statement branch, if any, ends with a
+ * break. The branch that did *not* have the break will get a
+ * temporary continue inserted in each iteration of the loop
+ * unroll.
+ *
+ * Note that since ls->num_loop_jumps is <= 1, it is impossible
+ * for both branches to end with a break.
+ */
+ ir_instruction *ir_if_last =
+ (ir_instruction *) ir_if->then_instructions.get_tail();
+
+ if (is_break(ir_if_last)) {
+ continue_from_then_branch = false;
+ break_ir = ir_if_last;
+ break;
+ } else {
+ ir_if_last =
+ (ir_instruction *) ir_if->else_instructions.get_tail();
+
+ if (is_break(ir_if_last)) {
+ break_ir = ir_if_last;
+ continue_from_then_branch = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (break_ir == NULL)
+ return visit_continue;
+
+ /* move instructions after then if in the continue branch */
+ while (!ir_if->get_next()->is_tail_sentinel()) {
+ ir_instruction *move_ir = (ir_instruction *) ir_if->get_next();
+
+ move_ir->remove();
+ if (continue_from_then_branch)
+ ir_if->then_instructions.push_tail(move_ir);
+ else
+ ir_if->else_instructions.push_tail(move_ir);
+ }
+
+ /* Remove the break from the if-statement.
+ */
+ break_ir->remove();
+
+ void *const mem_ctx = talloc_parent(ir);
+ ir_instruction *ir_to_replace = ir;
+
+ for (int i = 0; i < iterations; i++) {
+ exec_list copy_list;
+
+ copy_list.make_empty();
+ clone_ir_list(mem_ctx, ©_list, &ir->body_instructions);
+
+ ir_if = ((ir_instruction *) copy_list.get_tail())->as_if();
+ assert(ir_if != NULL);
+
+ ir_to_replace->insert_before(©_list);
+ ir_to_replace->remove();
+
+ /* placeholder that will be removed in the next iteration */
+ ir_to_replace =
+ new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+
+ exec_list *const list = (continue_from_then_branch)
+ ? &ir_if->then_instructions : &ir_if->else_instructions;
+
+ list->push_tail(ir_to_replace);
+ }
+
+ ir_to_replace->remove();
+
+ this->progress = true;
+ return visit_continue;
+ }
+ }
+
+ void *const mem_ctx = talloc_parent(ir);
+
+ for (int i = 0; i < iterations; i++) {
+ exec_list copy_list;
+
+ copy_list.make_empty();
+ clone_ir_list(mem_ctx, ©_list, &ir->body_instructions);
+
+ ir->insert_before(©_list);
+ }
+
+ /* The loop has been replaced by the unrolled copies. Remove the original
+ * loop from the IR sequence.
+ */
+ ir->remove();
+
+ this->progress = true;
+ return visit_continue;
+}
+
+
+bool
+unroll_loops(exec_list *instructions, loop_state *ls, unsigned max_iterations)
+{
+ loop_unroll_visitor v(ls, max_iterations);
+
+ v.run(instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/lower_discard.cpp b/mesalib/src/glsl/lower_discard.cpp new file mode 100644 index 000000000..5c3603ed7 --- /dev/null +++ b/mesalib/src/glsl/lower_discard.cpp @@ -0,0 +1,198 @@ +/*
+ * 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 lower_discard.cpp
+ *
+ * This pass moves discards out of if-statements.
+ *
+ * Case 1: The "then" branch contains a conditional discard:
+ * ---------------------------------------------------------
+ *
+ * if (cond1) {
+ * s1;
+ * discard cond2;
+ * s2;
+ * } else {
+ * s3;
+ * }
+ *
+ * becomes:
+ *
+ * temp = false;
+ * if (cond1) {
+ * s1;
+ * temp = cond2;
+ * s2;
+ * } else {
+ * s3;
+ * }
+ * discard temp;
+ *
+ * Case 2: The "else" branch contains a conditional discard:
+ * ---------------------------------------------------------
+ *
+ * if (cond1) {
+ * s1;
+ * } else {
+ * s2;
+ * discard cond2;
+ * s3;
+ * }
+ *
+ * becomes:
+ *
+ * temp = false;
+ * if (cond1) {
+ * s1;
+ * } else {
+ * s2;
+ * temp = cond2;
+ * s3;
+ * }
+ * discard temp;
+ *
+ * Case 3: Both branches contain a conditional discard:
+ * ----------------------------------------------------
+ *
+ * if (cond1) {
+ * s1;
+ * discard cond2;
+ * s2;
+ * } else {
+ * s3;
+ * discard cond3;
+ * s4;
+ * }
+ *
+ * becomes:
+ *
+ * temp = false;
+ * if (cond1) {
+ * s1;
+ * temp = cond2;
+ * s2;
+ * } else {
+ * s3;
+ * temp = cond3;
+ * s4;
+ * }
+ * discard temp;
+ *
+ * If there are multiple conditional discards, we need only deal with one of
+ * them. Repeatedly applying this pass will take care of the others.
+ *
+ * Unconditional discards are treated as having a condition of "true".
+ */
+
+#include "glsl_types.h"
+#include "ir.h"
+
+class lower_discard_visitor : public ir_hierarchical_visitor {
+public:
+ lower_discard_visitor()
+ {
+ this->progress = false;
+ }
+
+ ir_visitor_status visit_leave(ir_if *);
+
+ bool progress;
+};
+
+
+bool
+lower_discard(exec_list *instructions)
+{
+ lower_discard_visitor v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
+
+
+static ir_discard *
+find_discard(exec_list &instructions)
+{
+ foreach_list(n, &instructions) {
+ ir_discard *ir = ((ir_instruction *) n)->as_discard();
+ if (ir != NULL)
+ return ir;
+ }
+ return NULL;
+}
+
+
+static void
+replace_discard(void *mem_ctx, ir_variable *var, ir_discard *ir)
+{
+ ir_rvalue *condition = ir->condition;
+
+ /* For unconditional discards, use "true" as the condition. */
+ if (condition == NULL)
+ condition = new(mem_ctx) ir_constant(true);
+
+ ir_assignment *assignment =
+ new(mem_ctx) ir_assignment(new(mem_ctx) ir_dereference_variable(var),
+ condition, NULL);
+
+ ir->replace_with(assignment);
+}
+
+
+ir_visitor_status
+lower_discard_visitor::visit_leave(ir_if *ir)
+{
+ ir_discard *then_discard = find_discard(ir->then_instructions);
+ ir_discard *else_discard = find_discard(ir->else_instructions);
+
+ if (then_discard == NULL && else_discard == NULL)
+ return visit_continue;
+
+ void *mem_ctx = talloc_parent(ir);
+
+ ir_variable *temp = new(mem_ctx) ir_variable(glsl_type::bool_type,
+ "discard_cond_temp",
+ ir_var_temporary);
+ ir_assignment *temp_initializer =
+ new(mem_ctx) ir_assignment(new(mem_ctx) ir_dereference_variable(temp),
+ new(mem_ctx) ir_constant(false), NULL);
+
+ ir->insert_before(temp);
+ ir->insert_before(temp_initializer);
+
+ if (then_discard != NULL)
+ replace_discard(mem_ctx, temp, then_discard);
+
+ if (else_discard != NULL)
+ replace_discard(mem_ctx, temp, else_discard);
+
+ ir_discard *discard = then_discard != NULL ? then_discard : else_discard;
+ discard->condition = new(mem_ctx) ir_dereference_variable(temp);
+ ir->insert_after(discard);
+
+ this->progress = true;
+
+ return visit_continue;
+}
diff --git a/mesalib/src/glsl/ir_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp index 0b8741394..9212ae21e 100644 --- a/mesalib/src/glsl/ir_if_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp @@ -1,168 +1,200 @@ -/* - * 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_if_to_cond_assign.cpp - * - * This attempts to flatten all if statements to conditional - * assignments for GPUs that don't do control flow. - * - * It can't handle other control flow being inside of its block, such - * as calls or loops. Hopefully loop unrolling and inlining will take - * care of those. - */ - -#include "glsl_types.h" -#include "ir.h" - -class ir_if_to_cond_assign_visitor : public ir_hierarchical_visitor { -public: - ir_if_to_cond_assign_visitor() - { - this->progress = false; - } - - ir_visitor_status visit_leave(ir_if *); - - bool progress; -}; - -bool -do_if_to_cond_assign(exec_list *instructions) -{ - ir_if_to_cond_assign_visitor v; - - visit_list_elements(&v, instructions); - - return v.progress; -} - -void -check_control_flow(ir_instruction *ir, void *data) -{ - bool *found_control_flow = (bool *)data; - switch (ir->ir_type) { - case ir_type_call: - case ir_type_discard: - case ir_type_loop: - case ir_type_loop_jump: - case ir_type_return: - *found_control_flow = true; - break; - default: - break; - } -} - -void -move_block_to_cond_assign(void *mem_ctx, - ir_if *if_ir, ir_variable *cond_var, bool then) -{ - exec_list *instructions; - - if (then) { - instructions = &if_ir->then_instructions; - } else { - instructions = &if_ir->else_instructions; - } - - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - - if (ir->ir_type == ir_type_assignment) { - ir_assignment *assign = (ir_assignment *)ir; - ir_rvalue *cond_expr; - ir_dereference *deref = new(mem_ctx) ir_dereference_variable(cond_var); - - if (then) { - cond_expr = deref; - } else { - cond_expr = new(mem_ctx) ir_expression(ir_unop_logic_not, - glsl_type::bool_type, - deref, - NULL); - } - - if (!assign->condition) { - assign->condition = cond_expr; - } else { - assign->condition = new(mem_ctx) ir_expression(ir_binop_logic_and, - glsl_type::bool_type, - cond_expr, - assign->condition); - } - } - - /* Now, move from the if block to the block surrounding it. */ - ir->remove(); - if_ir->insert_before(ir); - } -} - -ir_visitor_status -ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) -{ - bool found_control_flow = false; - ir_variable *cond_var; - ir_assignment *assign; - ir_dereference_variable *deref; - - /* Check that both blocks don't contain anything we can't support. */ - foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) { - ir_instruction *then_ir = (ir_instruction *)then_iter.get(); - visit_tree(then_ir, check_control_flow, &found_control_flow); - } - foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) { - ir_instruction *else_ir = (ir_instruction *)else_iter.get(); - visit_tree(else_ir, check_control_flow, &found_control_flow); - } - if (found_control_flow) - return visit_continue; - - void *mem_ctx = talloc_parent(ir); - - /* Store the condition to a variable so the assignment conditions are - * simpler. - */ - cond_var = new(mem_ctx) ir_variable(glsl_type::bool_type, - "if_to_cond_assign_condition", - ir_var_temporary); - ir->insert_before(cond_var); - - deref = new(mem_ctx) ir_dereference_variable(cond_var); - assign = new(mem_ctx) ir_assignment(deref, - ir->condition, NULL); - ir->insert_before(assign); - - /* Now, move all of the instructions out of the if blocks, putting - * conditions on assignments. - */ - move_block_to_cond_assign(mem_ctx, ir, cond_var, true); - move_block_to_cond_assign(mem_ctx, ir, cond_var, false); - - ir->remove(); - - this->progress = true; - - return visit_continue; -} +/*
+ * 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 lower_if_to_cond_assign.cpp
+ *
+ * This attempts to flatten if-statements to conditional assignments for
+ * GPUs with limited or no flow control support.
+ *
+ * It can't handle other control flow being inside of its block, such
+ * as calls or loops. Hopefully loop unrolling and inlining will take
+ * care of those.
+ *
+ * Drivers for GPUs with no control flow support should simply call
+ *
+ * lower_if_to_cond_assign(instructions)
+ *
+ * to attempt to flatten all if-statements.
+ *
+ * Some GPUs (such as i965 prior to gen6) do support control flow, but have a
+ * maximum nesting depth N. Drivers for such hardware can call
+ *
+ * lower_if_to_cond_assign(instructions, N)
+ *
+ * to attempt to flatten any if-statements appearing at depth > N.
+ */
+
+#include "glsl_types.h"
+#include "ir.h"
+
+class ir_if_to_cond_assign_visitor : public ir_hierarchical_visitor {
+public:
+ ir_if_to_cond_assign_visitor(unsigned max_depth)
+ {
+ this->progress = false;
+ this->max_depth = max_depth;
+ this->depth = 0;
+ }
+
+ ir_visitor_status visit_enter(ir_if *);
+ ir_visitor_status visit_leave(ir_if *);
+
+ bool progress;
+ unsigned max_depth;
+ unsigned depth;
+};
+
+bool
+lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth)
+{
+ ir_if_to_cond_assign_visitor v(max_depth);
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
+
+void
+check_control_flow(ir_instruction *ir, void *data)
+{
+ bool *found_control_flow = (bool *)data;
+ switch (ir->ir_type) {
+ case ir_type_call:
+ case ir_type_discard:
+ case ir_type_loop:
+ case ir_type_loop_jump:
+ case ir_type_return:
+ *found_control_flow = true;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+move_block_to_cond_assign(void *mem_ctx,
+ ir_if *if_ir, ir_variable *cond_var, bool then)
+{
+ exec_list *instructions;
+
+ if (then) {
+ instructions = &if_ir->then_instructions;
+ } else {
+ instructions = &if_ir->else_instructions;
+ }
+
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+
+ if (ir->ir_type == ir_type_assignment) {
+ ir_assignment *assign = (ir_assignment *)ir;
+ ir_rvalue *cond_expr;
+ ir_dereference *deref = new(mem_ctx) ir_dereference_variable(cond_var);
+
+ if (then) {
+ cond_expr = deref;
+ } else {
+ cond_expr = new(mem_ctx) ir_expression(ir_unop_logic_not,
+ glsl_type::bool_type,
+ deref,
+ NULL);
+ }
+
+ if (!assign->condition) {
+ assign->condition = cond_expr;
+ } else {
+ assign->condition = new(mem_ctx) ir_expression(ir_binop_logic_and,
+ glsl_type::bool_type,
+ cond_expr,
+ assign->condition);
+ }
+ }
+
+ /* Now, move from the if block to the block surrounding it. */
+ ir->remove();
+ if_ir->insert_before(ir);
+ }
+}
+
+ir_visitor_status
+ir_if_to_cond_assign_visitor::visit_enter(ir_if *ir)
+{
+ (void) ir;
+ this->depth++;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
+{
+ /* Only flatten when beyond the GPU's maximum supported nesting depth. */
+ if (this->depth <= this->max_depth)
+ return visit_continue;
+
+ this->depth--;
+
+ bool found_control_flow = false;
+ ir_variable *cond_var;
+ ir_assignment *assign;
+ ir_dereference_variable *deref;
+
+ /* Check that both blocks don't contain anything we can't support. */
+ foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
+ ir_instruction *then_ir = (ir_instruction *)then_iter.get();
+ visit_tree(then_ir, check_control_flow, &found_control_flow);
+ }
+ foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
+ ir_instruction *else_ir = (ir_instruction *)else_iter.get();
+ visit_tree(else_ir, check_control_flow, &found_control_flow);
+ }
+ if (found_control_flow)
+ return visit_continue;
+
+ void *mem_ctx = talloc_parent(ir);
+
+ /* Store the condition to a variable so the assignment conditions are
+ * simpler.
+ */
+ cond_var = new(mem_ctx) ir_variable(glsl_type::bool_type,
+ "if_to_cond_assign_condition",
+ ir_var_temporary);
+ ir->insert_before(cond_var);
+
+ deref = new(mem_ctx) ir_dereference_variable(cond_var);
+ assign = new(mem_ctx) ir_assignment(deref,
+ ir->condition, NULL);
+ ir->insert_before(assign);
+
+ /* Now, move all of the instructions out of the if blocks, putting
+ * conditions on assignments.
+ */
+ move_block_to_cond_assign(mem_ctx, ir, cond_var, true);
+ move_block_to_cond_assign(mem_ctx, ir, cond_var, false);
+
+ ir->remove();
+
+ this->progress = true;
+
+ return visit_continue;
+}
diff --git a/mesalib/src/glsl/lower_instructions.cpp b/mesalib/src/glsl/lower_instructions.cpp new file mode 100644 index 000000000..6e44d1319 --- /dev/null +++ b/mesalib/src/glsl/lower_instructions.cpp @@ -0,0 +1,288 @@ +/*
+ * 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 lower_instructions.cpp
+ *
+ * Many GPUs lack native instructions for certain expression operations, and
+ * must replace them with some other expression tree. This pass lowers some
+ * of the most common cases, allowing the lowering code to be implemented once
+ * rather than in each driver backend.
+ *
+ * Currently supported transformations:
+ * - SUB_TO_ADD_NEG
+ * - DIV_TO_MUL_RCP
+ * - EXP_TO_EXP2
+ * - POW_TO_EXP2
+ * - LOG_TO_LOG2
+ * - MOD_TO_FRACT
+ *
+ * SUB_TO_ADD_NEG:
+ * ---------------
+ * Breaks an ir_binop_sub expression down to add(op0, neg(op1))
+ *
+ * This simplifies expression reassociation, and for many backends
+ * there is no subtract operation separate from adding the negation.
+ * For backends with native subtract operations, they will probably
+ * want to recognize add(op0, neg(op1)) or the other way around to
+ * produce a subtract anyway.
+ *
+ * DIV_TO_MUL_RCP:
+ * ---------------
+ * Breaks an ir_unop_div expression down to op0 * (rcp(op1)).
+ *
+ * Many GPUs don't have a divide instruction (945 and 965 included),
+ * but they do have an RCP instruction to compute an approximate
+ * reciprocal. By breaking the operation down, constant reciprocals
+ * can get constant folded.
+ *
+ * EXP_TO_EXP2 and LOG_TO_LOG2:
+ * ----------------------------
+ * Many GPUs don't have a base e log or exponent instruction, but they
+ * do have base 2 versions, so this pass converts exp and log to exp2
+ * and log2 operations.
+ *
+ * POW_TO_EXP2:
+ * -----------
+ * Many older GPUs don't have an x**y instruction. For these GPUs, convert
+ * x**y to 2**(y * log2(x)).
+ *
+ * MOD_TO_FRACT:
+ * -------------
+ * Breaks an ir_unop_mod expression down to (op1 * fract(op0 / op1))
+ *
+ * Many GPUs don't have a MOD instruction (945 and 965 included), and
+ * if we have to break it down like this anyway, it gives an
+ * opportunity to do things like constant fold the (1.0 / op1) easily.
+ */
+
+#include "main/core.h" /* for M_LOG2E */
+#include "glsl_types.h"
+#include "ir.h"
+#include "ir_optimization.h"
+
+class lower_instructions_visitor : public ir_hierarchical_visitor {
+public:
+ lower_instructions_visitor(unsigned lower)
+ : progress(false), lower(lower) { }
+
+ ir_visitor_status visit_leave(ir_expression *);
+
+ bool progress;
+
+private:
+ unsigned lower; /** Bitfield of which operations to lower */
+
+ void sub_to_add_neg(ir_expression *);
+ void div_to_mul_rcp(ir_expression *);
+ void mod_to_fract(ir_expression *);
+ void exp_to_exp2(ir_expression *);
+ void pow_to_exp2(ir_expression *);
+ void log_to_log2(ir_expression *);
+};
+
+/**
+ * Determine if a particular type of lowering should occur
+ */
+#define lowering(x) (this->lower & x)
+
+bool
+lower_instructions(exec_list *instructions, unsigned what_to_lower)
+{
+ lower_instructions_visitor v(what_to_lower);
+
+ visit_list_elements(&v, instructions);
+ return v.progress;
+}
+
+void
+lower_instructions_visitor::sub_to_add_neg(ir_expression *ir)
+{
+ ir->operation = ir_binop_add;
+ ir->operands[1] = new(ir) ir_expression(ir_unop_neg, ir->operands[1]->type,
+ ir->operands[1], NULL);
+ this->progress = true;
+}
+
+void
+lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir)
+{
+ if (!ir->operands[1]->type->is_integer()) {
+ /* New expression for the 1.0 / op1 */
+ ir_rvalue *expr;
+ expr = new(ir) ir_expression(ir_unop_rcp,
+ ir->operands[1]->type,
+ ir->operands[1],
+ NULL);
+
+ /* op0 / op1 -> op0 * (1.0 / op1) */
+ ir->operation = ir_binop_mul;
+ ir->operands[1] = expr;
+ } else {
+ /* Be careful with integer division -- we need to do it as a
+ * float and re-truncate, since rcp(n > 1) of an integer would
+ * just be 0.
+ */
+ ir_rvalue *op0, *op1;
+ const struct glsl_type *vec_type;
+
+ vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT,
+ ir->operands[1]->type->vector_elements,
+ ir->operands[1]->type->matrix_columns);
+
+ if (ir->operands[1]->type->base_type == GLSL_TYPE_INT)
+ op1 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[1], NULL);
+ else
+ op1 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[1], NULL);
+
+ op1 = new(ir) ir_expression(ir_unop_rcp, op1->type, op1, NULL);
+
+ vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT,
+ ir->operands[0]->type->vector_elements,
+ ir->operands[0]->type->matrix_columns);
+
+ if (ir->operands[0]->type->base_type == GLSL_TYPE_INT)
+ op0 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[0], NULL);
+ else
+ op0 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[0], NULL);
+
+ op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1);
+
+ ir->operation = ir_unop_f2i;
+ ir->operands[0] = op0;
+ ir->operands[1] = NULL;
+ }
+
+ this->progress = true;
+}
+
+void
+lower_instructions_visitor::exp_to_exp2(ir_expression *ir)
+{
+ ir_constant *log2_e = new(ir) ir_constant(float(M_LOG2E));
+
+ ir->operation = ir_unop_exp2;
+ ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[0]->type,
+ ir->operands[0], log2_e);
+ this->progress = true;
+}
+
+void
+lower_instructions_visitor::pow_to_exp2(ir_expression *ir)
+{
+ ir_expression *const log2_x =
+ new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
+ ir->operands[0]);
+
+ ir->operation = ir_unop_exp2;
+ ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[1]->type,
+ ir->operands[1], log2_x);
+ ir->operands[1] = NULL;
+ this->progress = true;
+}
+
+void
+lower_instructions_visitor::log_to_log2(ir_expression *ir)
+{
+ ir->operation = ir_binop_mul;
+ ir->operands[0] = new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
+ ir->operands[0], NULL);
+ ir->operands[1] = new(ir) ir_constant(float(1.0 / M_LOG2E));
+ this->progress = true;
+}
+
+void
+lower_instructions_visitor::mod_to_fract(ir_expression *ir)
+{
+ ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b",
+ ir_var_temporary);
+ this->base_ir->insert_before(temp);
+
+ ir_assignment *const assign =
+ new(ir) ir_assignment(new(ir) ir_dereference_variable(temp),
+ ir->operands[1], NULL);
+
+ this->base_ir->insert_before(assign);
+
+ ir_expression *const div_expr =
+ new(ir) ir_expression(ir_binop_div, ir->operands[0]->type,
+ ir->operands[0],
+ new(ir) ir_dereference_variable(temp));
+
+ /* Don't generate new IR that would need to be lowered in an additional
+ * pass.
+ */
+ if (lowering(DIV_TO_MUL_RCP))
+ div_to_mul_rcp(div_expr);
+
+ ir_rvalue *expr = new(ir) ir_expression(ir_unop_fract,
+ ir->operands[0]->type,
+ div_expr,
+ NULL);
+
+ ir->operation = ir_binop_mul;
+ ir->operands[0] = new(ir) ir_dereference_variable(temp);
+ ir->operands[1] = expr;
+ this->progress = true;
+}
+
+ir_visitor_status
+lower_instructions_visitor::visit_leave(ir_expression *ir)
+{
+ switch (ir->operation) {
+ case ir_binop_sub:
+ if (lowering(SUB_TO_ADD_NEG))
+ sub_to_add_neg(ir);
+ break;
+
+ case ir_binop_div:
+ if (lowering(DIV_TO_MUL_RCP))
+ div_to_mul_rcp(ir);
+ break;
+
+ case ir_unop_exp:
+ if (lowering(EXP_TO_EXP2))
+ exp_to_exp2(ir);
+ break;
+
+ case ir_unop_log:
+ if (lowering(LOG_TO_LOG2))
+ log_to_log2(ir);
+ break;
+
+ case ir_binop_mod:
+ if (lowering(MOD_TO_FRACT))
+ mod_to_fract(ir);
+ break;
+
+ case ir_binop_pow:
+ if (lowering(POW_TO_EXP2))
+ pow_to_exp2(ir);
+ break;
+
+ default:
+ return visit_continue;
+ }
+
+ return visit_continue;
+}
diff --git a/mesalib/src/glsl/ir_lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp index b69cc1ec3..7c3463e58 100644 --- a/mesalib/src/glsl/ir_lower_jumps.cpp +++ b/mesalib/src/glsl/lower_jumps.cpp @@ -1,544 +1,570 @@ -/* - * Copyright © 2010 Luca Barbieri - * - * 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_lower_jumps.cpp - */ - -#include "glsl_types.h" -#include <string.h> -#include "ir.h" - -enum jump_strength -{ - strength_none, - strength_always_clears_execute_flag, - strength_continue, - strength_break, - strength_return, - strength_discard -}; - -struct block_record -{ - /* minimum jump strength (of lowered IR, not pre-lowering IR) - * - * If the block ends with a jump, must be the strength of the jump. - * Otherwise, the jump would be dead and have been deleted before) - * - * If the block doesn't end with a jump, it can be different than strength_none if all paths before it lead to some jump - * (e.g. an if with a return in one branch, and a break in the other, while not lowering them) - * Note that identical jumps are usually unified though. - */ - jump_strength min_strength; - - /* can anything clear the execute flag? */ - bool may_clear_execute_flag; - - block_record() - { - this->min_strength = strength_none; - this->may_clear_execute_flag = false; - } -}; - -struct loop_record -{ - ir_function_signature* signature; - ir_loop* loop; - - /* used to avoid lowering the break used to represent lowered breaks */ - unsigned nesting_depth; - bool in_if_at_the_end_of_the_loop; - - bool may_set_return_flag; - - ir_variable* break_flag; - ir_variable* execute_flag; /* cleared to emulate continue */ - - loop_record(ir_function_signature* p_signature = 0, ir_loop* p_loop = 0) - { - this->signature = p_signature; - this->loop = p_loop; - this->nesting_depth = 0; - this->in_if_at_the_end_of_the_loop = false; - this->may_set_return_flag = false; - this->break_flag = 0; - this->execute_flag = 0; - } - - ir_variable* get_execute_flag() - { - /* also supported for the "function loop" */ - if(!this->execute_flag) { - exec_list& list = this->loop ? this->loop->body_instructions : signature->body; - this->execute_flag = new(this->signature) ir_variable(glsl_type::bool_type, "execute_flag", ir_var_temporary); - list.push_head(new(this->signature) ir_assignment(new(this->signature) ir_dereference_variable(execute_flag), new(this->signature) ir_constant(true), 0)); - list.push_head(this->execute_flag); - } - return this->execute_flag; - } - - ir_variable* get_break_flag() - { - assert(this->loop); - if(!this->break_flag) { - this->break_flag = new(this->signature) ir_variable(glsl_type::bool_type, "break_flag", ir_var_temporary); - this->loop->insert_before(this->break_flag); - this->loop->insert_before(new(this->signature) ir_assignment(new(this->signature) ir_dereference_variable(break_flag), new(this->signature) ir_constant(false), 0)); - } - return this->break_flag; - } -}; - -struct function_record -{ - ir_function_signature* signature; - ir_variable* return_flag; /* used to break out of all loops and then jump to the return instruction */ - ir_variable* return_value; - bool is_main; - unsigned nesting_depth; - - function_record(ir_function_signature* p_signature = 0) - { - this->signature = p_signature; - this->return_flag = 0; - this->return_value = 0; - this->nesting_depth = 0; - this->is_main = this->signature && (strcmp(this->signature->function_name(), "main") == 0); - } - - ir_variable* get_return_flag() - { - if(!this->return_flag) { - this->return_flag = new(this->signature) ir_variable(glsl_type::bool_type, "return_flag", ir_var_temporary); - this->signature->body.push_head(new(this->signature) ir_assignment(new(this->signature) ir_dereference_variable(return_flag), new(this->signature) ir_constant(false), 0)); - this->signature->body.push_head(this->return_flag); - } - return this->return_flag; - } - - ir_variable* get_return_value() - { - if(!this->return_value) { - assert(!this->signature->return_type->is_void()); - return_value = new(this->signature) ir_variable(this->signature->return_type, "return_value", ir_var_temporary); - this->signature->body.push_head(this->return_value); - } - return this->return_value; - } -}; - -struct ir_lower_jumps_visitor : public ir_control_flow_visitor { - bool progress; - - struct function_record function; - struct loop_record loop; - struct block_record block; - - bool pull_out_jumps; - bool lower_continue; - bool lower_break; - bool lower_sub_return; - bool lower_main_return; - - ir_lower_jumps_visitor() - { - this->progress = false; - } - - void truncate_after_instruction(exec_node *ir) - { - if (!ir) - return; - - while (!ir->get_next()->is_tail_sentinel()) { - ((ir_instruction *)ir->get_next())->remove(); - this->progress = true; - } - } - - void move_outer_block_inside(ir_instruction *ir, exec_list *inner_block) - { - while (!ir->get_next()->is_tail_sentinel()) { - ir_instruction *move_ir = (ir_instruction *)ir->get_next(); - - move_ir->remove(); - inner_block->push_tail(move_ir); - } - } - - virtual void visit(class ir_loop_jump * ir) - { - truncate_after_instruction(ir); - this->block.min_strength = ir->is_break() ? strength_break : strength_continue; - } - - virtual void visit(class ir_return * ir) - { - truncate_after_instruction(ir); - this->block.min_strength = strength_return; - } - - virtual void visit(class ir_discard * ir) - { - truncate_after_instruction(ir); - this->block.min_strength = strength_discard; - } - - enum jump_strength get_jump_strength(ir_instruction* ir) - { - if(!ir) - return strength_none; - else if(ir->ir_type == ir_type_loop_jump) { - if(((ir_loop_jump*)ir)->is_break()) - return strength_break; - else - return strength_continue; - } else if(ir->ir_type == ir_type_return) - return strength_return; - else if(ir->ir_type == ir_type_discard) - return strength_discard; - else - return strength_none; - } - - bool should_lower_jump(ir_jump* ir) - { - unsigned strength = get_jump_strength(ir); - bool lower; - switch(strength) - { - case strength_none: - lower = false; /* don't change this, code relies on it */ - break; - case strength_continue: - lower = lower_continue; - break; - case strength_break: - assert(this->loop.loop); - /* never lower "canonical break" */ - if(ir->get_next()->is_tail_sentinel() && (this->loop.nesting_depth == 0 - || (this->loop.nesting_depth == 1 && this->loop.in_if_at_the_end_of_the_loop))) - lower = false; - else - lower = lower_break; - break; - case strength_return: - /* never lower return at the end of a this->function */ - if(this->function.nesting_depth == 0 && ir->get_next()->is_tail_sentinel()) - lower = false; - else if (this->function.is_main) - lower = lower_main_return; - else - lower = lower_sub_return; - break; - case strength_discard: - lower = false; /* probably nothing needs this lowered */ - break; - } - return lower; - } - - block_record visit_block(exec_list* list) - { - block_record saved_block = this->block; - this->block = block_record(); - visit_exec_list(list, this); - block_record ret = this->block; - this->block = saved_block; - return ret; - } - - virtual void visit(ir_if *ir) - { - if(this->loop.nesting_depth == 0 && ir->get_next()->is_tail_sentinel()) - this->loop.in_if_at_the_end_of_the_loop = true; - - ++this->function.nesting_depth; - ++this->loop.nesting_depth; - - block_record block_records[2]; - ir_jump* jumps[2]; - - block_records[0] = visit_block(&ir->then_instructions); - block_records[1] = visit_block(&ir->else_instructions); - -retry: /* we get here if we put code after the if inside a branch */ - for(unsigned i = 0; i < 2; ++i) { - exec_list& list = i ? ir->else_instructions : ir->then_instructions; - jumps[i] = 0; - if(!list.is_empty() && get_jump_strength((ir_instruction*)list.get_tail())) - jumps[i] = (ir_jump*)list.get_tail(); - } - - for(;;) { - jump_strength jump_strengths[2]; - - for(unsigned i = 0; i < 2; ++i) { - if(jumps[i]) { - jump_strengths[i] = block_records[i].min_strength; - assert(jump_strengths[i] == get_jump_strength(jumps[i])); - } else - jump_strengths[i] = strength_none; - } - - /* move both jumps out if possible */ - if(pull_out_jumps && jump_strengths[0] == jump_strengths[1]) { - bool unify = true; - if(jump_strengths[0] == strength_continue) - ir->insert_after(new(ir) ir_loop_jump(ir_loop_jump::jump_continue)); - else if(jump_strengths[0] == strength_break) - ir->insert_after(new(ir) ir_loop_jump(ir_loop_jump::jump_break)); - /* FINISHME: unify returns with identical expressions */ - else if(jump_strengths[0] == strength_return && this->function.signature->return_type->is_void()) - ir->insert_after(new(ir) ir_return(NULL)); - /* FINISHME: unify discards */ - else - unify = false; - - if(unify) { - jumps[0]->remove(); - jumps[1]->remove(); - this->progress = true; - - jumps[0] = 0; - jumps[1] = 0; - block_records[0].min_strength = strength_none; - block_records[1].min_strength = strength_none; - break; - } - } - - /* lower a jump: if both need to lowered, start with the strongest one, so that - * we might later unify the lowered version with the other one - */ - bool should_lower[2]; - for(unsigned i = 0; i < 2; ++i) - should_lower[i] = should_lower_jump(jumps[i]); - - int lower; - if(should_lower[1] && should_lower[0]) - lower = jump_strengths[1] > jump_strengths[0]; - else if(should_lower[0]) - lower = 0; - else if(should_lower[1]) - lower = 1; - else - break; - - if(jump_strengths[lower] == strength_return) { - ir_variable* return_flag = this->function.get_return_flag(); - if(!this->function.signature->return_type->is_void()) { - ir_variable* return_value = this->function.get_return_value(); - jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(return_value), ((ir_return*)jumps[lower])->value, NULL)); - } - jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(return_flag), new (ir) ir_constant(true), NULL)); - this->loop.may_set_return_flag = true; - if(this->loop.loop) { - ir_loop_jump* lowered = 0; - lowered = new(ir) ir_loop_jump(ir_loop_jump::jump_break); - block_records[lower].min_strength = strength_break; - jumps[lower]->replace_with(lowered); - jumps[lower] = lowered; - } else - goto lower_continue; - this->progress = true; - } else if(jump_strengths[lower] == strength_break) { - /* We can't lower to an actual continue because that would execute the increment. - * - * In the lowered code, we instead put the break check between the this->loop body and the increment, - * which is impossible with a real continue as defined by the GLSL IR currently. - * - * Smarter options (such as undoing the increment) are possible but it's not worth implementing them, - * because if break is lowered, continue is almost surely lowered too. - */ - jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(this->loop.get_break_flag()), new (ir) ir_constant(true), 0)); - goto lower_continue; - } else if(jump_strengths[lower] == strength_continue) { -lower_continue: - ir_variable* execute_flag = this->loop.get_execute_flag(); - jumps[lower]->replace_with(new(ir) ir_assignment(new (ir) ir_dereference_variable(execute_flag), new (ir) ir_constant(false), 0)); - jumps[lower] = 0; - block_records[lower].min_strength = strength_always_clears_execute_flag; - block_records[lower].may_clear_execute_flag = true; - this->progress = true; - break; - } - } - - /* move out a jump out if possible */ - if(pull_out_jumps) { - int move_out = -1; - if(jumps[0] && block_records[1].min_strength >= strength_continue) - move_out = 0; - else if(jumps[1] && block_records[0].min_strength >= strength_continue) - move_out = 1; - - if(move_out >= 0) - { - jumps[move_out]->remove(); - ir->insert_after(jumps[move_out]); - jumps[move_out] = 0; - block_records[move_out].min_strength = strength_none; - this->progress = true; - } - } - - if(block_records[0].min_strength < block_records[1].min_strength) - this->block.min_strength = block_records[0].min_strength; - else - this->block.min_strength = block_records[1].min_strength; - this->block.may_clear_execute_flag = this->block.may_clear_execute_flag || block_records[0].may_clear_execute_flag || block_records[1].may_clear_execute_flag; - - if(this->block.min_strength) - truncate_after_instruction(ir); - else if(this->block.may_clear_execute_flag) - { - int move_into = -1; - if(block_records[0].min_strength && !block_records[1].may_clear_execute_flag) - move_into = 1; - else if(block_records[1].min_strength && !block_records[0].may_clear_execute_flag) - move_into = 0; - - if(move_into >= 0) { - assert(!block_records[move_into].min_strength && !block_records[move_into].may_clear_execute_flag); /* otherwise, we just truncated */ - - exec_list* list = move_into ? &ir->else_instructions : &ir->then_instructions; - exec_node* next = ir->get_next(); - if(!next->is_tail_sentinel()) { - move_outer_block_inside(ir, list); - - exec_list list; - list.head = next; - block_records[move_into] = visit_block(&list); - - this->progress = true; - goto retry; - } - } else { - ir_instruction* ir_after; - for(ir_after = (ir_instruction*)ir->get_next(); !ir_after->is_tail_sentinel();) - { - ir_if* ir_if = ir_after->as_if(); - if(ir_if && ir_if->else_instructions.is_empty()) { - ir_dereference_variable* ir_if_cond_deref = ir_if->condition->as_dereference_variable(); - if(ir_if_cond_deref && ir_if_cond_deref->var == this->loop.execute_flag) { - ir_instruction* ir_next = (ir_instruction*)ir_after->get_next(); - ir_after->insert_before(&ir_if->then_instructions); - ir_after->remove(); - ir_after = ir_next; - continue; - } - } - ir_after = (ir_instruction*)ir_after->get_next(); - - /* only set this if we find any unprotected instruction */ - this->progress = true; - } - - if(!ir->get_next()->is_tail_sentinel()) { - assert(this->loop.execute_flag); - ir_if* if_execute = new(ir) ir_if(new(ir) ir_dereference_variable(this->loop.execute_flag)); - move_outer_block_inside(ir, &if_execute->then_instructions); - ir->insert_after(if_execute); - } - } - } - --this->loop.nesting_depth; - --this->function.nesting_depth; - } - - virtual void visit(ir_loop *ir) - { - ++this->function.nesting_depth; - loop_record saved_loop = this->loop; - this->loop = loop_record(this->function.signature, ir); - - block_record body = visit_block(&ir->body_instructions); - - if(body.min_strength >= strength_break) { - /* FINISHME: turn the this->loop into an if, or replace it with its body */ - } - - if(this->loop.break_flag) { - ir_if* break_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->loop.break_flag)); - break_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break)); - ir->body_instructions.push_tail(break_if); - } - - if(this->loop.may_set_return_flag) { - assert(this->function.return_flag); - ir_if* return_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->function.return_flag)); - return_if->then_instructions.push_tail(new(ir) ir_loop_jump(saved_loop.loop ? ir_loop_jump::jump_break : ir_loop_jump::jump_continue)); - ir->insert_after(return_if); - } - - this->loop = saved_loop; - --this->function.nesting_depth; - } - - virtual void visit(ir_function_signature *ir) - { - /* these are not strictly necessary */ - assert(!this->function.signature); - assert(!this->loop.loop); - - function_record saved_function = this->function; - loop_record saved_loop = this->loop; - this->function = function_record(ir); - this->loop = loop_record(ir); - - assert(!this->loop.loop); - visit_block(&ir->body); - - if(this->function.return_value) - ir->body.push_tail(new(ir) ir_return(new (ir) ir_dereference_variable(this->function.return_value))); - - this->loop = saved_loop; - this->function = saved_function; - } - - virtual void visit(class ir_function * ir) - { - visit_block(&ir->signatures); - } -}; - -bool -do_lower_jumps(exec_list *instructions, bool pull_out_jumps, bool lower_sub_return, bool lower_main_return, bool lower_continue, bool lower_break) -{ - ir_lower_jumps_visitor v; - v.pull_out_jumps = pull_out_jumps; - v.lower_continue = lower_continue; - v.lower_break = lower_break; - v.lower_sub_return = lower_sub_return; - v.lower_main_return = lower_main_return; - - do { - v.progress = false; - visit_exec_list(instructions, &v); - } while (v.progress); - - return v.progress; -} +/*
+ * Copyright © 2010 Luca Barbieri
+ *
+ * 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 lower_jumps.cpp
+ *
+ * This pass lowers jumps (break, continue, and return) to if/else structures.
+ *
+ * It can be asked to:
+ * 1. Pull jumps out of ifs where possible
+ * 2. Remove all "continue"s, replacing them with an "execute flag"
+ * 3. Replace all "break" with a single conditional one at the end of the loop
+ * 4. Replace all "return"s with a single return at the end of the function,
+ * for the main function and/or other functions
+ *
+ * Applying this pass gives several benefits:
+ * 1. All functions can be inlined.
+ * 2. nv40 and other pre-DX10 chips without "continue" can be supported
+ * 3. nv30 and other pre-DX10 chips with no control flow at all are better
+ * supported
+ *
+ * Continues are lowered by adding a per-loop "execute flag", initialized to
+ * true, that when cleared inhibits all execution until the end of the loop.
+ *
+ * Breaks are lowered to continues, plus setting a "break flag" that is checked
+ * at the end of the loop, and trigger the unique "break".
+ *
+ * Returns are lowered to breaks/continues, plus adding a "return flag" that
+ * causes loops to break again out of their enclosing loops until all the
+ * loops are exited: then the "execute flag" logic will ignore everything
+ * until the end of the function.
+ *
+ * Note that "continue" and "return" can also be implemented by adding
+ * a dummy loop and using break.
+ * However, this is bad for hardware with limited nesting depth, and
+ * prevents further optimization, and thus is not currently performed.
+ */
+
+#include "glsl_types.h"
+#include <string.h>
+#include "ir.h"
+
+enum jump_strength
+{
+ strength_none,
+ strength_always_clears_execute_flag,
+ strength_continue,
+ strength_break,
+ strength_return,
+};
+
+struct block_record
+{
+ /* minimum jump strength (of lowered IR, not pre-lowering IR)
+ *
+ * If the block ends with a jump, must be the strength of the jump.
+ * Otherwise, the jump would be dead and have been deleted before)
+ *
+ * If the block doesn't end with a jump, it can be different than strength_none if all paths before it lead to some jump
+ * (e.g. an if with a return in one branch, and a break in the other, while not lowering them)
+ * Note that identical jumps are usually unified though.
+ */
+ jump_strength min_strength;
+
+ /* can anything clear the execute flag? */
+ bool may_clear_execute_flag;
+
+ block_record()
+ {
+ this->min_strength = strength_none;
+ this->may_clear_execute_flag = false;
+ }
+};
+
+struct loop_record
+{
+ ir_function_signature* signature;
+ ir_loop* loop;
+
+ /* used to avoid lowering the break used to represent lowered breaks */
+ unsigned nesting_depth;
+ bool in_if_at_the_end_of_the_loop;
+
+ bool may_set_return_flag;
+
+ ir_variable* break_flag;
+ ir_variable* execute_flag; /* cleared to emulate continue */
+
+ loop_record(ir_function_signature* p_signature = 0, ir_loop* p_loop = 0)
+ {
+ this->signature = p_signature;
+ this->loop = p_loop;
+ this->nesting_depth = 0;
+ this->in_if_at_the_end_of_the_loop = false;
+ this->may_set_return_flag = false;
+ this->break_flag = 0;
+ this->execute_flag = 0;
+ }
+
+ ir_variable* get_execute_flag()
+ {
+ /* also supported for the "function loop" */
+ if(!this->execute_flag) {
+ exec_list& list = this->loop ? this->loop->body_instructions : signature->body;
+ this->execute_flag = new(this->signature) ir_variable(glsl_type::bool_type, "execute_flag", ir_var_temporary);
+ list.push_head(new(this->signature) ir_assignment(new(this->signature) ir_dereference_variable(execute_flag), new(this->signature) ir_constant(true), 0));
+ list.push_head(this->execute_flag);
+ }
+ return this->execute_flag;
+ }
+
+ ir_variable* get_break_flag()
+ {
+ assert(this->loop);
+ if(!this->break_flag) {
+ this->break_flag = new(this->signature) ir_variable(glsl_type::bool_type, "break_flag", ir_var_temporary);
+ this->loop->insert_before(this->break_flag);
+ this->loop->insert_before(new(this->signature) ir_assignment(new(this->signature) ir_dereference_variable(break_flag), new(this->signature) ir_constant(false), 0));
+ }
+ return this->break_flag;
+ }
+};
+
+struct function_record
+{
+ ir_function_signature* signature;
+ ir_variable* return_flag; /* used to break out of all loops and then jump to the return instruction */
+ ir_variable* return_value;
+ bool is_main;
+ unsigned nesting_depth;
+
+ function_record(ir_function_signature* p_signature = 0)
+ {
+ this->signature = p_signature;
+ this->return_flag = 0;
+ this->return_value = 0;
+ this->nesting_depth = 0;
+ this->is_main = this->signature && (strcmp(this->signature->function_name(), "main") == 0);
+ }
+
+ ir_variable* get_return_flag()
+ {
+ if(!this->return_flag) {
+ this->return_flag = new(this->signature) ir_variable(glsl_type::bool_type, "return_flag", ir_var_temporary);
+ this->signature->body.push_head(new(this->signature) ir_assignment(new(this->signature) ir_dereference_variable(return_flag), new(this->signature) ir_constant(false), 0));
+ this->signature->body.push_head(this->return_flag);
+ }
+ return this->return_flag;
+ }
+
+ ir_variable* get_return_value()
+ {
+ if(!this->return_value) {
+ assert(!this->signature->return_type->is_void());
+ return_value = new(this->signature) ir_variable(this->signature->return_type, "return_value", ir_var_temporary);
+ this->signature->body.push_head(this->return_value);
+ }
+ return this->return_value;
+ }
+};
+
+struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
+ bool progress;
+
+ struct function_record function;
+ struct loop_record loop;
+ struct block_record block;
+
+ bool pull_out_jumps;
+ bool lower_continue;
+ bool lower_break;
+ bool lower_sub_return;
+ bool lower_main_return;
+
+ ir_lower_jumps_visitor()
+ {
+ this->progress = false;
+ }
+
+ void truncate_after_instruction(exec_node *ir)
+ {
+ if (!ir)
+ return;
+
+ while (!ir->get_next()->is_tail_sentinel()) {
+ ((ir_instruction *)ir->get_next())->remove();
+ this->progress = true;
+ }
+ }
+
+ void move_outer_block_inside(ir_instruction *ir, exec_list *inner_block)
+ {
+ while (!ir->get_next()->is_tail_sentinel()) {
+ ir_instruction *move_ir = (ir_instruction *)ir->get_next();
+
+ move_ir->remove();
+ inner_block->push_tail(move_ir);
+ }
+ }
+
+ virtual void visit(class ir_loop_jump * ir)
+ {
+ truncate_after_instruction(ir);
+ this->block.min_strength = ir->is_break() ? strength_break : strength_continue;
+ }
+
+ virtual void visit(class ir_return * ir)
+ {
+ truncate_after_instruction(ir);
+ this->block.min_strength = strength_return;
+ }
+
+ virtual void visit(class ir_discard * ir)
+ {
+ }
+
+ enum jump_strength get_jump_strength(ir_instruction* ir)
+ {
+ if(!ir)
+ return strength_none;
+ else if(ir->ir_type == ir_type_loop_jump) {
+ if(((ir_loop_jump*)ir)->is_break())
+ return strength_break;
+ else
+ return strength_continue;
+ } else if(ir->ir_type == ir_type_return)
+ return strength_return;
+ else
+ return strength_none;
+ }
+
+ bool should_lower_jump(ir_jump* ir)
+ {
+ unsigned strength = get_jump_strength(ir);
+ bool lower;
+ switch(strength)
+ {
+ case strength_none:
+ lower = false; /* don't change this, code relies on it */
+ break;
+ case strength_continue:
+ lower = lower_continue;
+ break;
+ case strength_break:
+ assert(this->loop.loop);
+ /* never lower "canonical break" */
+ if(ir->get_next()->is_tail_sentinel() && (this->loop.nesting_depth == 0
+ || (this->loop.nesting_depth == 1 && this->loop.in_if_at_the_end_of_the_loop)))
+ lower = false;
+ else
+ lower = lower_break;
+ break;
+ case strength_return:
+ /* never lower return at the end of a this->function */
+ if(this->function.nesting_depth == 0 && ir->get_next()->is_tail_sentinel())
+ lower = false;
+ else if (this->function.is_main)
+ lower = lower_main_return;
+ else
+ lower = lower_sub_return;
+ break;
+ }
+ return lower;
+ }
+
+ block_record visit_block(exec_list* list)
+ {
+ block_record saved_block = this->block;
+ this->block = block_record();
+ visit_exec_list(list, this);
+ block_record ret = this->block;
+ this->block = saved_block;
+ return ret;
+ }
+
+ virtual void visit(ir_if *ir)
+ {
+ if(this->loop.nesting_depth == 0 && ir->get_next()->is_tail_sentinel())
+ this->loop.in_if_at_the_end_of_the_loop = true;
+
+ ++this->function.nesting_depth;
+ ++this->loop.nesting_depth;
+
+ block_record block_records[2];
+ ir_jump* jumps[2];
+
+ block_records[0] = visit_block(&ir->then_instructions);
+ block_records[1] = visit_block(&ir->else_instructions);
+
+retry: /* we get here if we put code after the if inside a branch */
+ for(unsigned i = 0; i < 2; ++i) {
+ exec_list& list = i ? ir->else_instructions : ir->then_instructions;
+ jumps[i] = 0;
+ if(!list.is_empty() && get_jump_strength((ir_instruction*)list.get_tail()))
+ jumps[i] = (ir_jump*)list.get_tail();
+ }
+
+ for(;;) {
+ jump_strength jump_strengths[2];
+
+ for(unsigned i = 0; i < 2; ++i) {
+ if(jumps[i]) {
+ jump_strengths[i] = block_records[i].min_strength;
+ assert(jump_strengths[i] == get_jump_strength(jumps[i]));
+ } else
+ jump_strengths[i] = strength_none;
+ }
+
+ /* move both jumps out if possible */
+ if(pull_out_jumps && jump_strengths[0] == jump_strengths[1]) {
+ bool unify = true;
+ if(jump_strengths[0] == strength_continue)
+ ir->insert_after(new(ir) ir_loop_jump(ir_loop_jump::jump_continue));
+ else if(jump_strengths[0] == strength_break)
+ ir->insert_after(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
+ /* FINISHME: unify returns with identical expressions */
+ else if(jump_strengths[0] == strength_return && this->function.signature->return_type->is_void())
+ ir->insert_after(new(ir) ir_return(NULL));
+ else
+ unify = false;
+
+ if(unify) {
+ jumps[0]->remove();
+ jumps[1]->remove();
+ this->progress = true;
+
+ jumps[0] = 0;
+ jumps[1] = 0;
+ block_records[0].min_strength = strength_none;
+ block_records[1].min_strength = strength_none;
+ break;
+ }
+ }
+
+ /* lower a jump: if both need to lowered, start with the strongest one, so that
+ * we might later unify the lowered version with the other one
+ */
+ bool should_lower[2];
+ for(unsigned i = 0; i < 2; ++i)
+ should_lower[i] = should_lower_jump(jumps[i]);
+
+ int lower;
+ if(should_lower[1] && should_lower[0])
+ lower = jump_strengths[1] > jump_strengths[0];
+ else if(should_lower[0])
+ lower = 0;
+ else if(should_lower[1])
+ lower = 1;
+ else
+ break;
+
+ if(jump_strengths[lower] == strength_return) {
+ ir_variable* return_flag = this->function.get_return_flag();
+ if(!this->function.signature->return_type->is_void()) {
+ ir_variable* return_value = this->function.get_return_value();
+ jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(return_value), ((ir_return*)jumps[lower])->value, NULL));
+ }
+ jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(return_flag), new (ir) ir_constant(true), NULL));
+ this->loop.may_set_return_flag = true;
+ if(this->loop.loop) {
+ ir_loop_jump* lowered = 0;
+ lowered = new(ir) ir_loop_jump(ir_loop_jump::jump_break);
+ block_records[lower].min_strength = strength_break;
+ jumps[lower]->replace_with(lowered);
+ jumps[lower] = lowered;
+ } else
+ goto lower_continue;
+ this->progress = true;
+ } else if(jump_strengths[lower] == strength_break) {
+ /* We can't lower to an actual continue because that would execute the increment.
+ *
+ * In the lowered code, we instead put the break check between the this->loop body and the increment,
+ * which is impossible with a real continue as defined by the GLSL IR currently.
+ *
+ * Smarter options (such as undoing the increment) are possible but it's not worth implementing them,
+ * because if break is lowered, continue is almost surely lowered too.
+ */
+ jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(this->loop.get_break_flag()), new (ir) ir_constant(true), 0));
+ goto lower_continue;
+ } else if(jump_strengths[lower] == strength_continue) {
+lower_continue:
+ ir_variable* execute_flag = this->loop.get_execute_flag();
+ jumps[lower]->replace_with(new(ir) ir_assignment(new (ir) ir_dereference_variable(execute_flag), new (ir) ir_constant(false), 0));
+ jumps[lower] = 0;
+ block_records[lower].min_strength = strength_always_clears_execute_flag;
+ block_records[lower].may_clear_execute_flag = true;
+ this->progress = true;
+ break;
+ }
+ }
+
+ /* move out a jump out if possible */
+ if(pull_out_jumps) {
+ int move_out = -1;
+ if(jumps[0] && block_records[1].min_strength >= strength_continue)
+ move_out = 0;
+ else if(jumps[1] && block_records[0].min_strength >= strength_continue)
+ move_out = 1;
+
+ if(move_out >= 0)
+ {
+ jumps[move_out]->remove();
+ ir->insert_after(jumps[move_out]);
+ jumps[move_out] = 0;
+ block_records[move_out].min_strength = strength_none;
+ this->progress = true;
+ }
+ }
+
+ if(block_records[0].min_strength < block_records[1].min_strength)
+ this->block.min_strength = block_records[0].min_strength;
+ else
+ this->block.min_strength = block_records[1].min_strength;
+ this->block.may_clear_execute_flag = this->block.may_clear_execute_flag || block_records[0].may_clear_execute_flag || block_records[1].may_clear_execute_flag;
+
+ if(this->block.min_strength)
+ truncate_after_instruction(ir);
+ else if(this->block.may_clear_execute_flag)
+ {
+ int move_into = -1;
+ if(block_records[0].min_strength && !block_records[1].may_clear_execute_flag)
+ move_into = 1;
+ else if(block_records[1].min_strength && !block_records[0].may_clear_execute_flag)
+ move_into = 0;
+
+ if(move_into >= 0) {
+ assert(!block_records[move_into].min_strength && !block_records[move_into].may_clear_execute_flag); /* otherwise, we just truncated */
+
+ exec_list* list = move_into ? &ir->else_instructions : &ir->then_instructions;
+ exec_node* next = ir->get_next();
+ if(!next->is_tail_sentinel()) {
+ move_outer_block_inside(ir, list);
+
+ exec_list list;
+ list.head = next;
+ block_records[move_into] = visit_block(&list);
+
+ this->progress = true;
+ goto retry;
+ }
+ } else {
+ ir_instruction* ir_after;
+ for(ir_after = (ir_instruction*)ir->get_next(); !ir_after->is_tail_sentinel();)
+ {
+ ir_if* ir_if = ir_after->as_if();
+ if(ir_if && ir_if->else_instructions.is_empty()) {
+ ir_dereference_variable* ir_if_cond_deref = ir_if->condition->as_dereference_variable();
+ if(ir_if_cond_deref && ir_if_cond_deref->var == this->loop.execute_flag) {
+ ir_instruction* ir_next = (ir_instruction*)ir_after->get_next();
+ ir_after->insert_before(&ir_if->then_instructions);
+ ir_after->remove();
+ ir_after = ir_next;
+ continue;
+ }
+ }
+ ir_after = (ir_instruction*)ir_after->get_next();
+
+ /* only set this if we find any unprotected instruction */
+ this->progress = true;
+ }
+
+ if(!ir->get_next()->is_tail_sentinel()) {
+ assert(this->loop.execute_flag);
+ ir_if* if_execute = new(ir) ir_if(new(ir) ir_dereference_variable(this->loop.execute_flag));
+ move_outer_block_inside(ir, &if_execute->then_instructions);
+ ir->insert_after(if_execute);
+ }
+ }
+ }
+ --this->loop.nesting_depth;
+ --this->function.nesting_depth;
+ }
+
+ virtual void visit(ir_loop *ir)
+ {
+ ++this->function.nesting_depth;
+ loop_record saved_loop = this->loop;
+ this->loop = loop_record(this->function.signature, ir);
+
+ block_record body = visit_block(&ir->body_instructions);
+
+ if(body.min_strength >= strength_break) {
+ /* FINISHME: turn the this->loop into an if, or replace it with its body */
+ }
+
+ if(this->loop.break_flag) {
+ ir_if* break_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->loop.break_flag));
+ break_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
+ ir->body_instructions.push_tail(break_if);
+ }
+
+ if(this->loop.may_set_return_flag) {
+ assert(this->function.return_flag);
+ ir_if* return_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->function.return_flag));
+ saved_loop.may_set_return_flag = true;
+ if(saved_loop.loop)
+ return_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
+ else
+ move_outer_block_inside(ir, &return_if->else_instructions);
+ ir->insert_after(return_if);
+ }
+
+ this->loop = saved_loop;
+ --this->function.nesting_depth;
+ }
+
+ virtual void visit(ir_function_signature *ir)
+ {
+ /* these are not strictly necessary */
+ assert(!this->function.signature);
+ assert(!this->loop.loop);
+
+ function_record saved_function = this->function;
+ loop_record saved_loop = this->loop;
+ this->function = function_record(ir);
+ this->loop = loop_record(ir);
+
+ assert(!this->loop.loop);
+ visit_block(&ir->body);
+
+ if(this->function.return_value)
+ ir->body.push_tail(new(ir) ir_return(new (ir) ir_dereference_variable(this->function.return_value)));
+
+ this->loop = saved_loop;
+ this->function = saved_function;
+ }
+
+ virtual void visit(class ir_function * ir)
+ {
+ visit_block(&ir->signatures);
+ }
+};
+
+bool
+do_lower_jumps(exec_list *instructions, bool pull_out_jumps, bool lower_sub_return, bool lower_main_return, bool lower_continue, bool lower_break)
+{
+ ir_lower_jumps_visitor v;
+ v.pull_out_jumps = pull_out_jumps;
+ v.lower_continue = lower_continue;
+ v.lower_break = lower_break;
+ v.lower_sub_return = lower_sub_return;
+ v.lower_main_return = lower_main_return;
+
+ do {
+ v.progress = false;
+ visit_exec_list(instructions, &v);
+ } while (v.progress);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_mat_op_to_vec.cpp b/mesalib/src/glsl/lower_mat_op_to_vec.cpp index 244fe4892..d61d94443 100644 --- a/mesalib/src/glsl/ir_mat_op_to_vec.cpp +++ b/mesalib/src/glsl/lower_mat_op_to_vec.cpp @@ -1,488 +1,490 @@ -/* - * 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_mat_op_to_vec.cpp - * - * Breaks matrix operation expressions down to a series of vector operations. - * - * Generally this is how we have to codegen matrix operations for a - * GPU, so this gives us the chance to constant fold operations on a - * column or row. - */ - -#include "ir.h" -#include "ir_expression_flattening.h" -#include "glsl_types.h" - -class ir_mat_op_to_vec_visitor : public ir_hierarchical_visitor { -public: - ir_mat_op_to_vec_visitor() - { - this->made_progress = false; - this->mem_ctx = NULL; - } - - ir_visitor_status visit_leave(ir_assignment *); - - ir_dereference *get_column(ir_variable *var, int col); - ir_rvalue *get_element(ir_variable *var, int col, int row); - - void do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_equal_mat_mat(ir_variable *result_var, ir_variable *a_var, - ir_variable *b_var, bool test_equal); - - void *mem_ctx; - bool made_progress; -}; - -static bool -mat_op_to_vec_predicate(ir_instruction *ir) -{ - ir_expression *expr = ir->as_expression(); - unsigned int i; - - if (!expr) - return false; - - for (i = 0; i < expr->get_num_operands(); i++) { - if (expr->operands[i]->type->is_matrix()) - return true; - } - - return false; -} - -bool -do_mat_op_to_vec(exec_list *instructions) -{ - ir_mat_op_to_vec_visitor v; - - /* Pull out any matrix expression to a separate assignment to a - * temp. This will make our handling of the breakdown to - * operations on the matrix's vector components much easier. - */ - do_expression_flattening(instructions, mat_op_to_vec_predicate); - - visit_list_elements(&v, instructions); - - return v.made_progress; -} - -ir_rvalue * -ir_mat_op_to_vec_visitor::get_element(ir_variable *var, int col, int row) -{ - ir_dereference *deref; - - deref = new(mem_ctx) ir_dereference_variable(var); - - if (var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_array(var, - new(mem_ctx) ir_constant(col)); - } else { - assert(col == 0); - } - - return new(mem_ctx) ir_swizzle(deref, row, 0, 0, 0, 1); -} - -ir_dereference * -ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row) -{ - ir_dereference *deref; - - if (!var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_variable(var); - } else { - deref = new(mem_ctx) ir_dereference_variable(var); - deref = new(mem_ctx) ir_dereference_array(deref, - new(mem_ctx) ir_constant(row)); - } - - return deref; -} - -void -ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) -{ - int b_col, i; - ir_assignment *assign; - ir_expression *expr; - - for (b_col = 0; b_col < b_var->type->matrix_columns; b_col++) { - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, b_col, 0); - - /* first column */ - expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, - a, - b); - - /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { - ir_expression *mul_expr; - - a = get_column(a_var, i); - b = get_element(b_var, b_col, i); - - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, - a, - b); - expr = new(mem_ctx) ir_expression(ir_binop_add, - a->type, - expr, - mul_expr); - } - - ir_rvalue *result = get_column(result_var, b_col); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); - base_ir->insert_before(assign); - } -} - -void -ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) -{ - int i; - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, 0, 0); - ir_assignment *assign; - ir_expression *expr; - - /* first column */ - expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, - a, - b); - - /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { - ir_expression *mul_expr; - - a = get_column(a_var, i); - b = get_element(b_var, 0, i); - - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, - a, - b); - expr = new(mem_ctx) ir_expression(ir_binop_add, - result_var->type, - expr, - mul_expr); - } - - ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); - base_ir->insert_before(assign); -} - -void -ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) -{ - int i; - - for (i = 0; i < b_var->type->matrix_columns; i++) { - ir_rvalue *a = new(mem_ctx) ir_dereference_variable(a_var); - ir_rvalue *b = get_column(b_var, i); - ir_rvalue *result; - ir_expression *column_expr; - ir_assignment *column_assign; - - result = new(mem_ctx) ir_dereference_variable(result_var); - result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1); - - column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - result->type, - a, - b); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL); - base_ir->insert_before(column_assign); - } -} - -void -ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) -{ - int i; - - for (i = 0; i < a_var->type->matrix_columns; i++) { - ir_rvalue *a = get_column(a_var, i); - ir_rvalue *b = new(mem_ctx) ir_dereference_variable(b_var); - ir_rvalue *result = get_column(result_var, i); - ir_expression *column_expr; - ir_assignment *column_assign; - - column_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result->type, - a, - b); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL); - base_ir->insert_before(column_assign); - } -} - -void -ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var, - bool test_equal) -{ - /* This essentially implements the following GLSL: - * - * bool equal(mat4 a, mat4 b) - * { - * return !any(bvec4(a[0] != b[0], - * a[1] != b[1], - * a[2] != b[2], - * a[3] != b[3]); - * } - * - * bool nequal(mat4 a, mat4 b) - * { - * return any(bvec4(a[0] != b[0], - * a[1] != b[1], - * a[2] != b[2], - * a[3] != b[3]); - * } - */ - const unsigned columns = a_var->type->matrix_columns; - const glsl_type *const bvec_type = - glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1); - - ir_variable *const tmp_bvec = - new(this->mem_ctx) ir_variable(bvec_type, "mat_cmp_bvec", - ir_var_temporary); - this->base_ir->insert_before(tmp_bvec); - - for (unsigned i = 0; i < columns; i++) { - ir_dereference *const op0 = get_column(a_var, i); - ir_dereference *const op1 = get_column(b_var, i); - - ir_expression *const cmp = - new(this->mem_ctx) ir_expression(ir_binop_any_nequal, - glsl_type::bool_type, op0, op1); - - ir_dereference *const lhs = - new(this->mem_ctx) ir_dereference_variable(tmp_bvec); - - ir_assignment *const assign = - new(this->mem_ctx) ir_assignment(lhs, cmp, NULL, (1U << i)); - - this->base_ir->insert_before(assign); - } - - ir_rvalue *const val = - new(this->mem_ctx) ir_dereference_variable(tmp_bvec); - - ir_expression *any = - new(this->mem_ctx) ir_expression(ir_unop_any, glsl_type::bool_type, - val, NULL); - - if (test_equal) - any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, - glsl_type::bool_type, - any, NULL); - - ir_rvalue *const result = - new(this->mem_ctx) ir_dereference_variable(result_var); - - ir_assignment *const assign = - new(mem_ctx) ir_assignment(result, any, NULL); - base_ir->insert_before(assign); -} - -static bool -has_matrix_operand(const ir_expression *expr, unsigned &columns) -{ - for (unsigned i = 0; i < expr->get_num_operands(); i++) { - if (expr->operands[i]->type->is_matrix()) { - columns = expr->operands[i]->type->matrix_columns; - return true; - } - } - - return false; -} - - -ir_visitor_status -ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) -{ - ir_expression *orig_expr = orig_assign->rhs->as_expression(); - unsigned int i, matrix_columns = 1; - ir_variable *op_var[2]; - - if (!orig_expr) - return visit_continue; - - if (!has_matrix_operand(orig_expr, matrix_columns)) - return visit_continue; - - mem_ctx = talloc_parent(orig_assign); - - ir_dereference_variable *lhs_deref = - orig_assign->lhs->as_dereference_variable(); - assert(lhs_deref); - - ir_variable *result_var = lhs_deref->var; - - /* Store the expression operands in temps so we can use them - * multiple times. - */ - for (i = 0; i < orig_expr->get_num_operands(); i++) { - ir_assignment *assign; - - op_var[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, - "mat_op_to_vec", - ir_var_temporary); - base_ir->insert_before(op_var[i]); - - lhs_deref = new(mem_ctx) ir_dereference_variable(op_var[i]); - assign = new(mem_ctx) ir_assignment(lhs_deref, - orig_expr->operands[i], - NULL); - base_ir->insert_before(assign); - } - - /* OK, time to break down this matrix operation. */ - switch (orig_expr->operation) { - case ir_unop_neg: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; - - /* Apply the operation to each column.*/ - for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_dereference *result = get_column(result_var, i); - ir_expression *column_expr; - ir_assignment *column_assign; - - column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, - op0, - NULL); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL, - mask); - assert(column_assign->write_mask != 0); - base_ir->insert_before(column_assign); - } - break; - } - case ir_binop_add: - case ir_binop_sub: - case ir_binop_div: - case ir_binop_mod: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; - - /* For most operations, the matrix version is just going - * column-wise through and applying the operation to each column - * if available. - */ - for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_rvalue *op1 = get_column(op_var[1], i); - ir_dereference *result = get_column(result_var, i); - ir_expression *column_expr; - ir_assignment *column_assign; - - column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, - op0, - op1); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL, - mask); - assert(column_assign->write_mask != 0); - base_ir->insert_before(column_assign); - } - break; - } - case ir_binop_mul: - if (op_var[0]->type->is_matrix()) { - if (op_var[1]->type->is_matrix()) { - do_mul_mat_mat(result_var, op_var[0], op_var[1]); - } else if (op_var[1]->type->is_vector()) { - do_mul_mat_vec(result_var, op_var[0], op_var[1]); - } else { - assert(op_var[1]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[0], op_var[1]); - } - } else { - assert(op_var[1]->type->is_matrix()); - if (op_var[0]->type->is_vector()) { - do_mul_vec_mat(result_var, op_var[0], op_var[1]); - } else { - assert(op_var[0]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[1], op_var[0]); - } - } - break; - - case ir_binop_all_equal: - case ir_binop_any_nequal: - do_equal_mat_mat(result_var, op_var[1], op_var[0], - (orig_expr->operation == ir_binop_all_equal)); - break; - - default: - printf("FINISHME: Handle matrix operation for %s\n", - orig_expr->operator_string()); - abort(); - } - orig_assign->remove(); - this->made_progress = true; - - return visit_continue; -} +/*
+ * 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 lower_mat_op_to_vec.cpp
+ *
+ * Breaks matrix operation expressions down to a series of vector operations.
+ *
+ * Generally this is how we have to codegen matrix operations for a
+ * GPU, so this gives us the chance to constant fold operations on a
+ * column or row.
+ */
+
+#include "ir.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+
+class ir_mat_op_to_vec_visitor : public ir_hierarchical_visitor {
+public:
+ ir_mat_op_to_vec_visitor()
+ {
+ this->made_progress = false;
+ this->mem_ctx = NULL;
+ }
+
+ ir_visitor_status visit_leave(ir_assignment *);
+
+ ir_dereference *get_column(ir_variable *var, int col);
+ ir_rvalue *get_element(ir_variable *var, int col, int row);
+
+ void do_mul_mat_mat(ir_variable *result_var,
+ ir_variable *a_var, ir_variable *b_var);
+ void do_mul_mat_vec(ir_variable *result_var,
+ ir_variable *a_var, ir_variable *b_var);
+ void do_mul_vec_mat(ir_variable *result_var,
+ ir_variable *a_var, ir_variable *b_var);
+ void do_mul_mat_scalar(ir_variable *result_var,
+ ir_variable *a_var, ir_variable *b_var);
+ void do_equal_mat_mat(ir_variable *result_var, ir_variable *a_var,
+ ir_variable *b_var, bool test_equal);
+
+ void *mem_ctx;
+ bool made_progress;
+};
+
+static bool
+mat_op_to_vec_predicate(ir_instruction *ir)
+{
+ ir_expression *expr = ir->as_expression();
+ unsigned int i;
+
+ if (!expr)
+ return false;
+
+ for (i = 0; i < expr->get_num_operands(); i++) {
+ if (expr->operands[i]->type->is_matrix())
+ return true;
+ }
+
+ return false;
+}
+
+bool
+do_mat_op_to_vec(exec_list *instructions)
+{
+ ir_mat_op_to_vec_visitor v;
+
+ /* Pull out any matrix expression to a separate assignment to a
+ * temp. This will make our handling of the breakdown to
+ * operations on the matrix's vector components much easier.
+ */
+ do_expression_flattening(instructions, mat_op_to_vec_predicate);
+
+ visit_list_elements(&v, instructions);
+
+ return v.made_progress;
+}
+
+ir_rvalue *
+ir_mat_op_to_vec_visitor::get_element(ir_variable *var, int col, int row)
+{
+ ir_dereference *deref;
+
+ deref = new(mem_ctx) ir_dereference_variable(var);
+
+ if (var->type->is_matrix()) {
+ deref = new(mem_ctx) ir_dereference_array(var,
+ new(mem_ctx) ir_constant(col));
+ } else {
+ assert(col == 0);
+ }
+
+ return new(mem_ctx) ir_swizzle(deref, row, 0, 0, 0, 1);
+}
+
+ir_dereference *
+ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row)
+{
+ ir_dereference *deref;
+
+ if (!var->type->is_matrix()) {
+ deref = new(mem_ctx) ir_dereference_variable(var);
+ } else {
+ deref = new(mem_ctx) ir_dereference_variable(var);
+ deref = new(mem_ctx) ir_dereference_array(deref,
+ new(mem_ctx) ir_constant(row));
+ }
+
+ return deref;
+}
+
+void
+ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var,
+ ir_variable *a_var,
+ ir_variable *b_var)
+{
+ int b_col, i;
+ ir_assignment *assign;
+ ir_expression *expr;
+
+ for (b_col = 0; b_col < b_var->type->matrix_columns; b_col++) {
+ ir_rvalue *a = get_column(a_var, 0);
+ ir_rvalue *b = get_element(b_var, b_col, 0);
+
+ /* first column */
+ expr = new(mem_ctx) ir_expression(ir_binop_mul,
+ a->type,
+ a,
+ b);
+
+ /* following columns */
+ for (i = 1; i < a_var->type->matrix_columns; i++) {
+ ir_expression *mul_expr;
+
+ a = get_column(a_var, i);
+ b = get_element(b_var, b_col, i);
+
+ mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
+ a->type,
+ a,
+ b);
+ expr = new(mem_ctx) ir_expression(ir_binop_add,
+ a->type,
+ expr,
+ mul_expr);
+ }
+
+ ir_rvalue *result = get_column(result_var, b_col);
+ assign = new(mem_ctx) ir_assignment(result,
+ expr,
+ NULL);
+ base_ir->insert_before(assign);
+ }
+}
+
+void
+ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var,
+ ir_variable *a_var,
+ ir_variable *b_var)
+{
+ int i;
+ ir_rvalue *a = get_column(a_var, 0);
+ ir_rvalue *b = get_element(b_var, 0, 0);
+ ir_assignment *assign;
+ ir_expression *expr;
+
+ /* first column */
+ expr = new(mem_ctx) ir_expression(ir_binop_mul,
+ result_var->type,
+ a,
+ b);
+
+ /* following columns */
+ for (i = 1; i < a_var->type->matrix_columns; i++) {
+ ir_expression *mul_expr;
+
+ a = get_column(a_var, i);
+ b = get_element(b_var, 0, i);
+
+ mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
+ result_var->type,
+ a,
+ b);
+ expr = new(mem_ctx) ir_expression(ir_binop_add,
+ result_var->type,
+ expr,
+ mul_expr);
+ }
+
+ ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var);
+ assign = new(mem_ctx) ir_assignment(result,
+ expr,
+ NULL);
+ base_ir->insert_before(assign);
+}
+
+void
+ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var,
+ ir_variable *a_var,
+ ir_variable *b_var)
+{
+ int i;
+
+ for (i = 0; i < b_var->type->matrix_columns; i++) {
+ ir_rvalue *a = new(mem_ctx) ir_dereference_variable(a_var);
+ ir_rvalue *b = get_column(b_var, i);
+ ir_rvalue *result;
+ ir_expression *column_expr;
+ ir_assignment *column_assign;
+
+ result = new(mem_ctx) ir_dereference_variable(result_var);
+ result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1);
+
+ column_expr = new(mem_ctx) ir_expression(ir_binop_dot,
+ result->type,
+ a,
+ b);
+
+ column_assign = new(mem_ctx) ir_assignment(result,
+ column_expr,
+ NULL);
+ base_ir->insert_before(column_assign);
+ }
+}
+
+void
+ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var,
+ ir_variable *a_var,
+ ir_variable *b_var)
+{
+ int i;
+
+ for (i = 0; i < a_var->type->matrix_columns; i++) {
+ ir_rvalue *a = get_column(a_var, i);
+ ir_rvalue *b = new(mem_ctx) ir_dereference_variable(b_var);
+ ir_rvalue *result = get_column(result_var, i);
+ ir_expression *column_expr;
+ ir_assignment *column_assign;
+
+ column_expr = new(mem_ctx) ir_expression(ir_binop_mul,
+ result->type,
+ a,
+ b);
+
+ column_assign = new(mem_ctx) ir_assignment(result,
+ column_expr,
+ NULL);
+ base_ir->insert_before(column_assign);
+ }
+}
+
+void
+ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var,
+ ir_variable *a_var,
+ ir_variable *b_var,
+ bool test_equal)
+{
+ /* This essentially implements the following GLSL:
+ *
+ * bool equal(mat4 a, mat4 b)
+ * {
+ * return !any(bvec4(a[0] != b[0],
+ * a[1] != b[1],
+ * a[2] != b[2],
+ * a[3] != b[3]);
+ * }
+ *
+ * bool nequal(mat4 a, mat4 b)
+ * {
+ * return any(bvec4(a[0] != b[0],
+ * a[1] != b[1],
+ * a[2] != b[2],
+ * a[3] != b[3]);
+ * }
+ */
+ const unsigned columns = a_var->type->matrix_columns;
+ const glsl_type *const bvec_type =
+ glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1);
+
+ ir_variable *const tmp_bvec =
+ new(this->mem_ctx) ir_variable(bvec_type, "mat_cmp_bvec",
+ ir_var_temporary);
+ this->base_ir->insert_before(tmp_bvec);
+
+ for (unsigned i = 0; i < columns; i++) {
+ ir_dereference *const op0 = get_column(a_var, i);
+ ir_dereference *const op1 = get_column(b_var, i);
+
+ ir_expression *const cmp =
+ new(this->mem_ctx) ir_expression(ir_binop_any_nequal,
+ glsl_type::bool_type, op0, op1);
+
+ ir_dereference *const lhs =
+ new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
+
+ ir_assignment *const assign =
+ new(this->mem_ctx) ir_assignment(lhs, cmp, NULL, (1U << i));
+
+ this->base_ir->insert_before(assign);
+ }
+
+ ir_rvalue *const val =
+ new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
+
+ ir_expression *any =
+ new(this->mem_ctx) ir_expression(ir_unop_any, glsl_type::bool_type,
+ val, NULL);
+
+ if (test_equal)
+ any = new(this->mem_ctx) ir_expression(ir_unop_logic_not,
+ glsl_type::bool_type,
+ any, NULL);
+
+ ir_rvalue *const result =
+ new(this->mem_ctx) ir_dereference_variable(result_var);
+
+ ir_assignment *const assign =
+ new(mem_ctx) ir_assignment(result, any, NULL);
+ base_ir->insert_before(assign);
+}
+
+static bool
+has_matrix_operand(const ir_expression *expr, unsigned &columns)
+{
+ for (unsigned i = 0; i < expr->get_num_operands(); i++) {
+ if (expr->operands[i]->type->is_matrix()) {
+ columns = expr->operands[i]->type->matrix_columns;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+ir_visitor_status
+ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign)
+{
+ ir_expression *orig_expr = orig_assign->rhs->as_expression();
+ unsigned int i, matrix_columns = 1;
+ ir_variable *op_var[2];
+
+ if (!orig_expr)
+ return visit_continue;
+
+ if (!has_matrix_operand(orig_expr, matrix_columns))
+ return visit_continue;
+
+ assert(orig_expr->get_num_operands() <= 2);
+
+ mem_ctx = talloc_parent(orig_assign);
+
+ ir_dereference_variable *lhs_deref =
+ orig_assign->lhs->as_dereference_variable();
+ assert(lhs_deref);
+
+ ir_variable *result_var = lhs_deref->var;
+
+ /* Store the expression operands in temps so we can use them
+ * multiple times.
+ */
+ for (i = 0; i < orig_expr->get_num_operands(); i++) {
+ ir_assignment *assign;
+
+ op_var[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type,
+ "mat_op_to_vec",
+ ir_var_temporary);
+ base_ir->insert_before(op_var[i]);
+
+ lhs_deref = new(mem_ctx) ir_dereference_variable(op_var[i]);
+ assign = new(mem_ctx) ir_assignment(lhs_deref,
+ orig_expr->operands[i],
+ NULL);
+ base_ir->insert_before(assign);
+ }
+
+ /* OK, time to break down this matrix operation. */
+ switch (orig_expr->operation) {
+ case ir_unop_neg: {
+ const unsigned mask = (1U << result_var->type->vector_elements) - 1;
+
+ /* Apply the operation to each column.*/
+ for (i = 0; i < matrix_columns; i++) {
+ ir_rvalue *op0 = get_column(op_var[0], i);
+ ir_dereference *result = get_column(result_var, i);
+ ir_expression *column_expr;
+ ir_assignment *column_assign;
+
+ column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
+ result->type,
+ op0,
+ NULL);
+
+ column_assign = new(mem_ctx) ir_assignment(result,
+ column_expr,
+ NULL,
+ mask);
+ assert(column_assign->write_mask != 0);
+ base_ir->insert_before(column_assign);
+ }
+ break;
+ }
+ case ir_binop_add:
+ case ir_binop_sub:
+ case ir_binop_div:
+ case ir_binop_mod: {
+ const unsigned mask = (1U << result_var->type->vector_elements) - 1;
+
+ /* For most operations, the matrix version is just going
+ * column-wise through and applying the operation to each column
+ * if available.
+ */
+ for (i = 0; i < matrix_columns; i++) {
+ ir_rvalue *op0 = get_column(op_var[0], i);
+ ir_rvalue *op1 = get_column(op_var[1], i);
+ ir_dereference *result = get_column(result_var, i);
+ ir_expression *column_expr;
+ ir_assignment *column_assign;
+
+ column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
+ result->type,
+ op0,
+ op1);
+
+ column_assign = new(mem_ctx) ir_assignment(result,
+ column_expr,
+ NULL,
+ mask);
+ assert(column_assign->write_mask != 0);
+ base_ir->insert_before(column_assign);
+ }
+ break;
+ }
+ case ir_binop_mul:
+ if (op_var[0]->type->is_matrix()) {
+ if (op_var[1]->type->is_matrix()) {
+ do_mul_mat_mat(result_var, op_var[0], op_var[1]);
+ } else if (op_var[1]->type->is_vector()) {
+ do_mul_mat_vec(result_var, op_var[0], op_var[1]);
+ } else {
+ assert(op_var[1]->type->is_scalar());
+ do_mul_mat_scalar(result_var, op_var[0], op_var[1]);
+ }
+ } else {
+ assert(op_var[1]->type->is_matrix());
+ if (op_var[0]->type->is_vector()) {
+ do_mul_vec_mat(result_var, op_var[0], op_var[1]);
+ } else {
+ assert(op_var[0]->type->is_scalar());
+ do_mul_mat_scalar(result_var, op_var[1], op_var[0]);
+ }
+ }
+ break;
+
+ case ir_binop_all_equal:
+ case ir_binop_any_nequal:
+ do_equal_mat_mat(result_var, op_var[1], op_var[0],
+ (orig_expr->operation == ir_binop_all_equal));
+ break;
+
+ default:
+ printf("FINISHME: Handle matrix operation for %s\n",
+ orig_expr->operator_string());
+ abort();
+ }
+ orig_assign->remove();
+ this->made_progress = true;
+
+ return visit_continue;
+}
diff --git a/mesalib/src/glsl/lower_texture_projection.cpp b/mesalib/src/glsl/lower_texture_projection.cpp new file mode 100644 index 000000000..7d4f647e9 --- /dev/null +++ b/mesalib/src/glsl/lower_texture_projection.cpp @@ -0,0 +1,99 @@ +/*
+ * 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 lower_texture_projection.cpp
+ *
+ * IR lower pass to perform the division of texture coordinates by the texture
+ * projector if present.
+ *
+ * Many GPUs have a texture sampling opcode that takes the projector
+ * and does the divide internally, thus the presence of the projector
+ * in the IR. For GPUs that don't, this saves the driver needing the
+ * logic for handling the divide.
+ *
+ * \author Eric Anholt <eric@anholt.net>
+ */
+
+#include "ir.h"
+
+class lower_texture_projection_visitor : public ir_hierarchical_visitor {
+public:
+ lower_texture_projection_visitor()
+ {
+ progress = false;
+ }
+
+ ir_visitor_status visit_leave(ir_texture *ir);
+
+ bool progress;
+};
+
+ir_visitor_status
+lower_texture_projection_visitor::visit_leave(ir_texture *ir)
+{
+ if (!ir->projector)
+ return visit_continue;
+
+ void *mem_ctx = talloc_parent(ir);
+
+ ir_variable *var = new(mem_ctx) ir_variable(ir->projector->type,
+ "projector", ir_var_auto);
+ base_ir->insert_before(var);
+ ir_dereference *deref = new(mem_ctx) ir_dereference_variable(var);
+ ir_expression *expr = new(mem_ctx) ir_expression(ir_unop_rcp,
+ ir->projector->type,
+ ir->projector,
+ NULL);
+ ir_assignment *assign = new(mem_ctx) ir_assignment(deref, expr, NULL);
+ base_ir->insert_before(assign);
+
+ deref = new(mem_ctx) ir_dereference_variable(var);
+ ir->coordinate = new(mem_ctx) ir_expression(ir_binop_mul,
+ ir->coordinate->type,
+ ir->coordinate,
+ deref);
+
+ if (ir->shadow_comparitor) {
+ deref = new(mem_ctx) ir_dereference_variable(var);
+ ir->shadow_comparitor = new(mem_ctx) ir_expression(ir_binop_mul,
+ ir->shadow_comparitor->type,
+ ir->shadow_comparitor,
+ deref);
+ }
+
+ ir->projector = NULL;
+
+ progress = true;
+ return visit_continue;
+}
+
+bool
+do_lower_texture_projection(exec_list *instructions)
+{
+ lower_texture_projection_visitor v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_vec_index_to_cond_assign.cpp b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp index cd8dedf2f..2e196f9e1 100644 --- a/mesalib/src/glsl/ir_vec_index_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp @@ -1,258 +1,258 @@ -/* - * 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_cond_assign.cpp - * - * Turns indexing into vector types to a series of conditional moves - * of each channel's swizzle into a temporary. - * - * Most GPUs don't have a native way to do this operation, and this - * works around that. For drivers using both this pass and - * ir_vec_index_to_swizzle, there's a risk that this pass will happen - * before sufficient constant folding to find that the array index is - * constant. However, we hope that other optimization passes, - * particularly constant folding of assignment conditions and copy - * propagation, will result in the same code in the end. - */ - -#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_cond_assign_visitor : public ir_hierarchical_visitor { -public: - ir_vec_index_to_cond_assign_visitor() - { - progress = false; - } - - ir_rvalue *convert_vec_index_to_cond_assign(ir_rvalue *val); - - virtual ir_visitor_status visit_enter(ir_expression *); - virtual ir_visitor_status visit_enter(ir_swizzle *); - virtual ir_visitor_status visit_leave(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_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue *ir) -{ - ir_dereference_array *orig_deref = ir->as_dereference_array(); - ir_assignment *assign; - ir_variable *index, *var; - ir_dereference *deref; - ir_expression *condition; - ir_swizzle *swizzle; - int i; - - if (!orig_deref) - return ir; - - if (orig_deref->array->type->is_matrix() || - orig_deref->array->type->is_array()) - return ir; - - void *mem_ctx = talloc_parent(ir); - - assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); - - /* Store the index to a temporary to avoid reusing its tree. */ - index = new(base_ir) ir_variable(glsl_type::int_type, - "vec_index_tmp_i", - ir_var_temporary); - base_ir->insert_before(index); - deref = new(base_ir) ir_dereference_variable(index); - assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL); - base_ir->insert_before(assign); - - /* Temporary where we store whichever value we swizzle out. */ - var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v", - ir_var_temporary); - base_ir->insert_before(var); - - /* Generate a conditional move of each vector element to the temp. */ - for (i = 0; i < orig_deref->array->type->vector_elements; i++) { - deref = new(base_ir) ir_dereference_variable(index); - condition = new(base_ir) ir_expression(ir_binop_equal, - glsl_type::bool_type, - deref, - new(base_ir) ir_constant(i)); - - /* Just clone the rest of the deref chain when trying to get at the - * underlying variable. - */ - swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), - i, 0, 0, 0, 1); - - deref = new(base_ir) ir_dereference_variable(var); - assign = new(base_ir) ir_assignment(deref, swizzle, condition); - base_ir->insert_before(assign); - } - - this->progress = true; - return new(base_ir) ir_dereference_variable(var); -} - -ir_visitor_status -ir_vec_index_to_cond_assign_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_cond_assign(ir->operands[i]); - } - - return visit_continue; -} - -ir_visitor_status -ir_vec_index_to_cond_assign_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_cond_assign(ir->val); - - return visit_continue; -} - -ir_visitor_status -ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) -{ - ir_variable *index, *var; - ir_dereference_variable *deref; - ir_assignment *assign; - int i; - - ir->rhs = convert_vec_index_to_cond_assign(ir->rhs); - if (ir->condition) - ir->condition = convert_vec_index_to_cond_assign(ir->condition); - - /* Last, handle the LHS */ - ir_dereference_array *orig_deref = ir->lhs->as_dereference_array(); - - if (!orig_deref || - orig_deref->array->type->is_matrix() || - orig_deref->array->type->is_array()) - return visit_continue; - - void *mem_ctx = talloc_parent(ir); - - assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); - - /* Store the index to a temporary to avoid reusing its tree. */ - index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i", - ir_var_temporary); - ir->insert_before(index); - deref = new(ir) ir_dereference_variable(index); - assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL); - ir->insert_before(assign); - - /* Store the RHS to a temporary to avoid reusing its tree. */ - var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v", - ir_var_temporary); - ir->insert_before(var); - deref = new(ir) ir_dereference_variable(var); - assign = new(ir) ir_assignment(deref, ir->rhs, NULL); - ir->insert_before(assign); - - /* Generate a conditional move of each vector element to the temp. */ - for (i = 0; i < orig_deref->array->type->vector_elements; i++) { - ir_rvalue *condition, *swizzle; - - deref = new(ir) ir_dereference_variable(index); - condition = new(ir) ir_expression(ir_binop_equal, - glsl_type::bool_type, - deref, - new(ir) ir_constant(i)); - - /* Just clone the rest of the deref chain when trying to get at the - * underlying variable. - */ - swizzle = new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), - i, 0, 0, 0, 1); - - deref = new(ir) ir_dereference_variable(var); - assign = new(ir) ir_assignment(swizzle, deref, condition); - ir->insert_before(assign); - } - ir->remove(); - - this->progress = true; - - return visit_continue; -} - -ir_visitor_status -ir_vec_index_to_cond_assign_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_cond_assign(param); - - if (new_param != param) { - param->replace_with(new_param); - } - } - - return visit_continue; -} - -ir_visitor_status -ir_vec_index_to_cond_assign_visitor::visit_enter(ir_return *ir) -{ - if (ir->value) { - ir->value = convert_vec_index_to_cond_assign(ir->value); - } - - return visit_continue; -} - -ir_visitor_status -ir_vec_index_to_cond_assign_visitor::visit_enter(ir_if *ir) -{ - ir->condition = convert_vec_index_to_cond_assign(ir->condition); - - return visit_continue; -} - -bool -do_vec_index_to_cond_assign(exec_list *instructions) -{ - ir_vec_index_to_cond_assign_visitor v; - - visit_list_elements(&v, instructions); - - return v.progress; -} +/*
+ * 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 lower_vec_index_to_cond_assign.cpp
+ *
+ * Turns indexing into vector types to a series of conditional moves
+ * of each channel's swizzle into a temporary.
+ *
+ * Most GPUs don't have a native way to do this operation, and this
+ * works around that. For drivers using both this pass and
+ * ir_vec_index_to_swizzle, there's a risk that this pass will happen
+ * before sufficient constant folding to find that the array index is
+ * constant. However, we hope that other optimization passes,
+ * particularly constant folding of assignment conditions and copy
+ * propagation, will result in the same code in the end.
+ */
+
+#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_cond_assign_visitor : public ir_hierarchical_visitor {
+public:
+ ir_vec_index_to_cond_assign_visitor()
+ {
+ progress = false;
+ }
+
+ ir_rvalue *convert_vec_index_to_cond_assign(ir_rvalue *val);
+
+ virtual ir_visitor_status visit_enter(ir_expression *);
+ virtual ir_visitor_status visit_enter(ir_swizzle *);
+ virtual ir_visitor_status visit_leave(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_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue *ir)
+{
+ ir_dereference_array *orig_deref = ir->as_dereference_array();
+ ir_assignment *assign;
+ ir_variable *index, *var;
+ ir_dereference *deref;
+ ir_expression *condition;
+ ir_swizzle *swizzle;
+ int i;
+
+ if (!orig_deref)
+ return ir;
+
+ if (orig_deref->array->type->is_matrix() ||
+ orig_deref->array->type->is_array())
+ return ir;
+
+ void *mem_ctx = talloc_parent(ir);
+
+ assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
+
+ /* Store the index to a temporary to avoid reusing its tree. */
+ index = new(base_ir) ir_variable(glsl_type::int_type,
+ "vec_index_tmp_i",
+ ir_var_temporary);
+ base_ir->insert_before(index);
+ deref = new(base_ir) ir_dereference_variable(index);
+ assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL);
+ base_ir->insert_before(assign);
+
+ /* Temporary where we store whichever value we swizzle out. */
+ var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v",
+ ir_var_temporary);
+ base_ir->insert_before(var);
+
+ /* Generate a conditional move of each vector element to the temp. */
+ for (i = 0; i < orig_deref->array->type->vector_elements; i++) {
+ deref = new(base_ir) ir_dereference_variable(index);
+ condition = new(base_ir) ir_expression(ir_binop_equal,
+ glsl_type::bool_type,
+ deref,
+ new(base_ir) ir_constant(i));
+
+ /* Just clone the rest of the deref chain when trying to get at the
+ * underlying variable.
+ */
+ swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL),
+ i, 0, 0, 0, 1);
+
+ deref = new(base_ir) ir_dereference_variable(var);
+ assign = new(base_ir) ir_assignment(deref, swizzle, condition);
+ base_ir->insert_before(assign);
+ }
+
+ this->progress = true;
+ return new(base_ir) ir_dereference_variable(var);
+}
+
+ir_visitor_status
+ir_vec_index_to_cond_assign_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_cond_assign(ir->operands[i]);
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_cond_assign_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_cond_assign(ir->val);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
+{
+ ir_variable *index, *var;
+ ir_dereference_variable *deref;
+ ir_assignment *assign;
+ int i;
+
+ ir->rhs = convert_vec_index_to_cond_assign(ir->rhs);
+ if (ir->condition)
+ ir->condition = convert_vec_index_to_cond_assign(ir->condition);
+
+ /* Last, handle the LHS */
+ ir_dereference_array *orig_deref = ir->lhs->as_dereference_array();
+
+ if (!orig_deref ||
+ orig_deref->array->type->is_matrix() ||
+ orig_deref->array->type->is_array())
+ return visit_continue;
+
+ void *mem_ctx = talloc_parent(ir);
+
+ assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
+
+ /* Store the index to a temporary to avoid reusing its tree. */
+ index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i",
+ ir_var_temporary);
+ ir->insert_before(index);
+ deref = new(ir) ir_dereference_variable(index);
+ assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL);
+ ir->insert_before(assign);
+
+ /* Store the RHS to a temporary to avoid reusing its tree. */
+ var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v",
+ ir_var_temporary);
+ ir->insert_before(var);
+ deref = new(ir) ir_dereference_variable(var);
+ assign = new(ir) ir_assignment(deref, ir->rhs, NULL);
+ ir->insert_before(assign);
+
+ /* Generate a conditional move of each vector element to the temp. */
+ for (i = 0; i < orig_deref->array->type->vector_elements; i++) {
+ ir_rvalue *condition, *swizzle;
+
+ deref = new(ir) ir_dereference_variable(index);
+ condition = new(ir) ir_expression(ir_binop_equal,
+ glsl_type::bool_type,
+ deref,
+ new(ir) ir_constant(i));
+
+ /* Just clone the rest of the deref chain when trying to get at the
+ * underlying variable.
+ */
+ swizzle = new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL),
+ i, 0, 0, 0, 1);
+
+ deref = new(ir) ir_dereference_variable(var);
+ assign = new(ir) ir_assignment(swizzle, deref, condition);
+ ir->insert_before(assign);
+ }
+ ir->remove();
+
+ this->progress = true;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_cond_assign_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_cond_assign(param);
+
+ if (new_param != param) {
+ param->replace_with(new_param);
+ }
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_cond_assign_visitor::visit_enter(ir_return *ir)
+{
+ if (ir->value) {
+ ir->value = convert_vec_index_to_cond_assign(ir->value);
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vec_index_to_cond_assign_visitor::visit_enter(ir_if *ir)
+{
+ ir->condition = convert_vec_index_to_cond_assign(ir->condition);
+
+ return visit_continue;
+}
+
+bool
+do_vec_index_to_cond_assign(exec_list *instructions)
+{
+ ir_vec_index_to_cond_assign_visitor v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_vec_index_to_swizzle.cpp b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp index 969dc8f94..e0d641549 100644 --- a/mesalib/src/glsl/ir_vec_index_to_swizzle.cpp +++ b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp @@ -1,157 +1,157 @@ -/* - * 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->set_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->replace_with(new_param); - } - } - - 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 v.progress; -} +/*
+ * 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 lower_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->set_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->replace_with(new_param);
+ }
+ }
+
+ 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 v.progress;
+}
diff --git a/mesalib/src/glsl/lower_vector.cpp b/mesalib/src/glsl/lower_vector.cpp new file mode 100644 index 000000000..3ed8d05d6 --- /dev/null +++ b/mesalib/src/glsl/lower_vector.cpp @@ -0,0 +1,224 @@ +/*
+ * 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 lower_vector.cpp
+ * IR lowering pass to remove some types of ir_quadop_vector
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "ir.h"
+#include "ir_rvalue_visitor.h"
+
+class lower_vector_visitor : public ir_rvalue_visitor {
+public:
+ lower_vector_visitor() : progress(false)
+ {
+ /* empty */
+ }
+
+ void handle_rvalue(ir_rvalue **rvalue);
+
+ /**
+ * Should SWZ-like expressions be lowered?
+ */
+ bool dont_lower_swz;
+
+ bool progress;
+};
+
+/**
+ * Determine if an IR expression tree looks like an extended swizzle
+ *
+ * Extended swizzles consist of access of a single vector source (with possible
+ * per component negation) and the constants -1, 0, or 1.
+ */
+bool
+is_extended_swizzle(ir_expression *ir)
+{
+ /* Track any variables that are accessed by this expression.
+ */
+ ir_variable *var = NULL;
+
+ assert(ir->operation == ir_quadop_vector);
+
+ for (unsigned i = 0; i < ir->type->vector_elements; i++) {
+ ir_rvalue *op = ir->operands[i];
+
+ while (op != NULL) {
+ switch (op->ir_type) {
+ case ir_type_constant: {
+ const ir_constant *const c = op->as_constant();
+
+ if (!c->is_one() && !c->is_zero() && !c->is_negative_one())
+ return false;
+
+ op = NULL;
+ break;
+ }
+
+ case ir_type_dereference_variable: {
+ ir_dereference_variable *const d = (ir_dereference_variable *) op;
+
+ if ((var != NULL) && (var != d->var))
+ return false;
+
+ var = d->var;
+ op = NULL;
+ break;
+ }
+
+ case ir_type_expression: {
+ ir_expression *const ex = (ir_expression *) op;
+
+ if (ex->operation != ir_unop_neg)
+ return false;
+
+ op = ex->operands[0];
+ break;
+ }
+
+ case ir_type_swizzle:
+ op = ((ir_swizzle *) op)->val;
+ break;
+
+ default:
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void
+lower_vector_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_expression *expr = (*rvalue)->as_expression();
+ if ((expr == NULL) || (expr->operation != ir_quadop_vector))
+ return;
+
+ if (this->dont_lower_swz && is_extended_swizzle(expr))
+ return;
+
+ /* FINISHME: Is this the right thing to use for the talloc context?
+ */
+ void *const mem_ctx = expr;
+
+ assert(expr->type->vector_elements == expr->get_num_operands());
+
+ /* Generate a temporary with the same type as the ir_quadop_operation.
+ */
+ ir_variable *const temp =
+ new(mem_ctx) ir_variable(expr->type, "vecop_tmp", ir_var_temporary);
+
+ this->base_ir->insert_before(temp);
+
+ /* Counter of the number of components collected so far.
+ */
+ unsigned assigned;
+
+ /* Write-mask in the destination that receives counted by 'assigned'.
+ */
+ unsigned write_mask;
+
+
+ /* Generate upto four assignments to that variable. Try to group component
+ * assignments together:
+ *
+ * - All constant components can be assigned at once.
+ * - All assigments of components from a single variable with the same
+ * unary operator can be assigned at once.
+ */
+ ir_constant_data d = { { 0 } };
+
+ assigned = 0;
+ write_mask = 0;
+ for (unsigned i = 0; i < expr->type->vector_elements; i++) {
+ const ir_constant *const c = expr->operands[i]->as_constant();
+
+ if (c == NULL)
+ continue;
+
+ switch (expr->type->base_type) {
+ case GLSL_TYPE_UINT: d.u[assigned] = c->value.u[0]; break;
+ case GLSL_TYPE_INT: d.i[assigned] = c->value.i[0]; break;
+ case GLSL_TYPE_FLOAT: d.f[assigned] = c->value.f[0]; break;
+ case GLSL_TYPE_BOOL: d.b[assigned] = c->value.b[0]; break;
+ default: assert(!"Should not get here."); break;
+ }
+
+ write_mask |= (1U << i);
+ assigned++;
+ }
+
+ assert((write_mask == 0) == (assigned == 0));
+
+ /* If there were constant values, generate an assignment.
+ */
+ if (assigned > 0) {
+ ir_constant *const c =
+ new(mem_ctx) ir_constant(glsl_type::get_instance(expr->type->base_type,
+ assigned, 0),
+ &d);
+ ir_dereference *const lhs = new(mem_ctx) ir_dereference_variable(temp);
+ ir_assignment *const assign =
+ new(mem_ctx) ir_assignment(lhs, c, NULL, write_mask);
+
+ this->base_ir->insert_before(assign);
+ }
+
+ /* FINISHME: This should try to coalesce assignments.
+ */
+ for (unsigned i = 0; i < expr->type->vector_elements; i++) {
+ if (expr->operands[i]->ir_type == ir_type_constant)
+ continue;
+
+ ir_dereference *const lhs = new(mem_ctx) ir_dereference_variable(temp);
+ ir_assignment *const assign =
+ new(mem_ctx) ir_assignment(lhs, expr->operands[i], NULL, (1U << i));
+
+ this->base_ir->insert_before(assign);
+ assigned++;
+ }
+
+ assert(assigned == expr->type->vector_elements);
+
+ *rvalue = new(mem_ctx) ir_dereference_variable(temp);
+ this->progress = true;
+}
+
+bool
+lower_quadop_vector(exec_list *instructions, bool dont_lower_swz)
+{
+ lower_vector_visitor v;
+
+ v.dont_lower_swz = dont_lower_swz;
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index b51b2405c..a0755ac2c 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -1,342 +1,344 @@ -/* - * 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 <io.h> - -#ifdef _MSC_VER -#define __STDC__ 1 -#include <getopt.h> -typedef size_t ssize_t; -#define open _open -#define read _read -#define fstat _fstat -#define stat _stat -#define close _close -#define O_RDONLY _O_RDONLY -#endif - -#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" -#include "loop_analysis.h" - -extern "C" struct gl_shader * -_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type); - -/* Copied from shader_api.c for the stand-alone compiler. - */ -struct gl_shader * -_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type) -{ - struct gl_shader *shader; - - (void) ctx; - - assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER); - shader = talloc_zero(NULL, struct gl_shader); - if (shader) { - shader->Type = type; - shader->Name = name; - shader->RefCount = 1; - } - return shader; -} - -static void -initialize_context(GLcontext *ctx, gl_api api) -{ - memset(ctx, 0, sizeof(*ctx)); - - ctx->API = api; - - ctx->Extensions.ARB_draw_buffers = GL_TRUE; - ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; - ctx->Extensions.EXT_texture_array = GL_TRUE; - ctx->Extensions.NV_texture_rectangle = GL_TRUE; - - /* 1.10 minimums. */ - ctx->Const.MaxLights = 8; - ctx->Const.MaxClipPlanes = 8; - ctx->Const.MaxTextureUnits = 2; - - /* More than the 1.10 minimum to appease parser tests taken from - * apps that (hopefully) already checked the number of coords. - */ - ctx->Const.MaxTextureCoordUnits = 4; - - ctx->Const.VertexProgram.MaxAttribs = 16; - ctx->Const.VertexProgram.MaxUniformComponents = 512; - ctx->Const.MaxVarying = 8; - ctx->Const.MaxVertexTextureImageUnits = 0; - ctx->Const.MaxCombinedTextureImageUnits = 2; - ctx->Const.MaxTextureImageUnits = 2; - ctx->Const.FragmentProgram.MaxUniformComponents = 64; - - ctx->Const.MaxDrawBuffers = 2; - - ctx->Driver.NewShader = _mesa_new_shader; -} - -/* Returned string will have 'ctx' as its talloc owner. */ -static char * -load_text_file(void *ctx, const char *file_name) -{ - char *text = NULL; - struct stat st; - ssize_t total_read = 0; - int fd = 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) { - free(text); - text = NULL; - break; - } - - if (bytes == 0) { - break; - } - - total_read += bytes; - } while (total_read < st.st_size); - - text[total_read] = '\0'; - } - } - - close(fd); - - return text; -} - - -void -usage_fail(const char *name) -{ - printf("%s <filename.frag|filename.vert>\n", name); - exit(EXIT_FAILURE); -} - - -int glsl_es = 0; -int dump_ast = 0; -int dump_hir = 0; -int dump_lir = 0; -int do_link = 0; - -const struct option compiler_opts[] = { - { "glsl-es", 0, &glsl_es, 1 }, - { "dump-ast", 0, &dump_ast, 1 }, - { "dump-hir", 0, &dump_hir, 1 }, - { "dump-lir", 0, &dump_lir, 1 }, - { "link", 0, &do_link, 1 }, - { NULL, 0, NULL, 0 } -}; - -void -compile_shader(GLcontext *ctx, struct gl_shader *shader) -{ - struct _mesa_glsl_parse_state *state = - new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); - - const char *source = shader->Source; - state->error = preprocess(state, &source, &state->info_log, - state->extensions, ctx->API); - - 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 = new(shader) exec_list; - if (!state->error && !state->translation_unit.is_empty()) - _mesa_ast_to_hir(shader->ir, state); - - /* Print out the unoptimized IR. */ - if (!state->error && dump_hir) { - validate_ir_tree(shader->ir); - _mesa_print_ir(shader->ir, state); - } - - /* 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_tree_grafting(shader->ir) || progress; - progress = do_constant_propagation(shader->ir) || progress; - progress = do_constant_variable_unlinked(shader->ir) || progress; - progress = do_constant_folding(shader->ir) || progress; - progress = do_algebraic(shader->ir) || progress; - progress = do_vec_index_to_swizzle(shader->ir) || progress; - progress = do_vec_index_to_cond_assign(shader->ir) || progress; - progress = do_swizzle_swizzle(shader->ir) || progress; - - loop_state *ls = analyze_loop_variables(shader->ir); - progress = set_loop_controls(shader->ir, ls) || progress; - progress = unroll_loops(shader->ir, ls, 32) || progress; - delete ls; - } 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; - shader->Version = state->language_version; - memcpy(shader->builtins_to_link, state->builtins_to_link, - sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); - shader->num_builtins_to_link = state->num_builtins_to_link; - - if (shader->InfoLog) - talloc_free(shader->InfoLog); - - shader->InfoLog = state->info_log; - - /* Retain any live IR, but trash the rest. */ - reparent_ir(shader->ir, shader); - - talloc_free(state); - - return; -} - -int -main(int argc, char **argv) -{ - int status = EXIT_SUCCESS; - GLcontext local_ctx; - GLcontext *ctx = &local_ctx; - - int c; - int idx = 0; - while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1) - /* empty */ ; - - - if (argc <= optind) - usage_fail(argv[0]); - - initialize_context(ctx, (glsl_es) ? API_OPENGLES2 : API_OPENGL); - - struct gl_shader_program *whole_program; - - whole_program = talloc_zero (NULL, struct gl_shader_program); - assert(whole_program != NULL); - - for (/* empty */; argc > optind; optind++) { - whole_program->Shaders = (struct gl_shader **) - talloc_realloc(whole_program, whole_program->Shaders, - struct gl_shader *, whole_program->NumShaders + 1); - assert(whole_program->Shaders != NULL); - - struct gl_shader *shader = talloc_zero(whole_program, gl_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]); - if (shader->Source == NULL) { - printf("File \"%s\" does not exist.\n", argv[optind]); - exit(EXIT_FAILURE); - } - - compile_shader(ctx, 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(ctx, whole_program); - status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; - - if (strlen(whole_program->InfoLog) > 0) - printf("Info log for linking:\n%s\n", whole_program->InfoLog); - } - - for (unsigned i = 0; i < whole_program->_NumLinkedShaders; i++) - talloc_free(whole_program->_LinkedShaders[i]); - - talloc_free(whole_program); - _mesa_glsl_release_types(); - _mesa_glsl_release_functions(); - - return status; -} +/*
+ * 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 <io.h>
+
+#ifdef _MSC_VER
+#define __STDC__ 1
+#include <getopt.h>
+typedef size_t ssize_t;
+#define open _open
+#define read _read
+#define fstat _fstat
+#define stat _stat
+#define close _close
+#define O_RDONLY _O_RDONLY
+#endif
+
+#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"
+#include "loop_analysis.h"
+
+extern "C" struct gl_shader *
+_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type);
+
+extern "C" void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh);
+
+/* Copied from shader_api.c for the stand-alone compiler.
+ */
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh)
+{
+ *ptr = sh;
+}
+
+struct gl_shader *
+_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
+{
+ struct gl_shader *shader;
+
+ (void) ctx;
+
+ assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
+ shader = talloc_zero(NULL, struct gl_shader);
+ if (shader) {
+ shader->Type = type;
+ shader->Name = name;
+ shader->RefCount = 1;
+ }
+ return shader;
+}
+
+static void
+initialize_context(struct gl_context *ctx, gl_api api)
+{
+ memset(ctx, 0, sizeof(*ctx));
+
+ ctx->API = api;
+
+ ctx->Extensions.ARB_draw_buffers = GL_TRUE;
+ ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
+ ctx->Extensions.EXT_texture_array = GL_TRUE;
+ ctx->Extensions.NV_texture_rectangle = GL_TRUE;
+
+ /* 1.10 minimums. */
+ ctx->Const.MaxLights = 8;
+ ctx->Const.MaxClipPlanes = 8;
+ ctx->Const.MaxTextureUnits = 2;
+
+ /* More than the 1.10 minimum to appease parser tests taken from
+ * apps that (hopefully) already checked the number of coords.
+ */
+ ctx->Const.MaxTextureCoordUnits = 4;
+
+ ctx->Const.VertexProgram.MaxAttribs = 16;
+ ctx->Const.VertexProgram.MaxUniformComponents = 512;
+ ctx->Const.MaxVarying = 8;
+ ctx->Const.MaxVertexTextureImageUnits = 0;
+ ctx->Const.MaxCombinedTextureImageUnits = 2;
+ ctx->Const.MaxTextureImageUnits = 2;
+ ctx->Const.FragmentProgram.MaxUniformComponents = 64;
+
+ ctx->Const.MaxDrawBuffers = 2;
+
+ ctx->Driver.NewShader = _mesa_new_shader;
+}
+
+/* Returned string will have 'ctx' as its talloc owner. */
+static char *
+load_text_file(void *ctx, const char *file_name)
+{
+ char *text = NULL;
+ struct stat st;
+ ssize_t total_read = 0;
+ int fd = 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) {
+ free(text);
+ 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 glsl_es = 0;
+int dump_ast = 0;
+int dump_hir = 0;
+int dump_lir = 0;
+int do_link = 0;
+
+const struct option compiler_opts[] = {
+ { "glsl-es", 0, &glsl_es, 1 },
+ { "dump-ast", 0, &dump_ast, 1 },
+ { "dump-hir", 0, &dump_hir, 1 },
+ { "dump-lir", 0, &dump_lir, 1 },
+ { "link", 0, &do_link, 1 },
+ { NULL, 0, NULL, 0 }
+};
+
+/**
+ * \brief Print proper usage and exit with failure.
+ */
+void
+usage_fail(const char *name)
+{
+
+ const char *header =
+ "usage: %s [options] <file.vert | file.geom | file.frag>\n"
+ "\n"
+ "Possible options are:\n";
+ printf(header, name, name);
+ for (const struct option *o = compiler_opts; o->name != 0; ++o) {
+ printf(" --%s\n", o->name);
+ }
+ exit(EXIT_FAILURE);
+}
+
+
+void
+compile_shader(struct gl_context *ctx, struct gl_shader *shader)
+{
+ struct _mesa_glsl_parse_state *state =
+ new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
+
+ const char *source = shader->Source;
+ state->error = preprocess(state, &source, &state->info_log,
+ state->extensions, ctx->API);
+
+ 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 = new(shader) exec_list;
+ if (!state->error && !state->translation_unit.is_empty())
+ _mesa_ast_to_hir(shader->ir, state);
+
+ /* Print out the unoptimized IR. */
+ if (!state->error && dump_hir) {
+ validate_ir_tree(shader->ir);
+ _mesa_print_ir(shader->ir, state);
+ }
+
+ /* Optimization passes */
+ if (!state->error && !shader->ir->is_empty()) {
+ bool progress;
+ do {
+ progress = do_common_optimization(shader->ir, false, 32);
+ } 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;
+ shader->Version = state->language_version;
+ memcpy(shader->builtins_to_link, state->builtins_to_link,
+ sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
+ shader->num_builtins_to_link = state->num_builtins_to_link;
+
+ if (shader->InfoLog)
+ talloc_free(shader->InfoLog);
+
+ shader->InfoLog = state->info_log;
+
+ /* Retain any live IR, but trash the rest. */
+ reparent_ir(shader->ir, shader);
+
+ talloc_free(state);
+
+ return;
+}
+
+int
+main(int argc, char **argv)
+{
+ int status = EXIT_SUCCESS;
+ struct gl_context local_ctx;
+ struct gl_context *ctx = &local_ctx;
+
+ int c;
+ int idx = 0;
+ while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1)
+ /* empty */ ;
+
+
+ if (argc <= optind)
+ usage_fail(argv[0]);
+
+ initialize_context(ctx, (glsl_es) ? API_OPENGLES2 : API_OPENGL);
+
+ struct gl_shader_program *whole_program;
+
+ whole_program = talloc_zero (NULL, struct gl_shader_program);
+ assert(whole_program != NULL);
+
+ for (/* empty */; argc > optind; optind++) {
+ whole_program->Shaders = (struct gl_shader **)
+ talloc_realloc(whole_program, whole_program->Shaders,
+ struct gl_shader *, whole_program->NumShaders + 1);
+ assert(whole_program->Shaders != NULL);
+
+ struct gl_shader *shader = talloc_zero(whole_program, gl_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]);
+ if (shader->Source == NULL) {
+ printf("File \"%s\" does not exist.\n", argv[optind]);
+ exit(EXIT_FAILURE);
+ }
+
+ compile_shader(ctx, 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(ctx, whole_program);
+ status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
+
+ if (strlen(whole_program->InfoLog) > 0)
+ printf("Info log for linking:\n%s\n", whole_program->InfoLog);
+ }
+
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; i++)
+ talloc_free(whole_program->_LinkedShaders[i]);
+
+ talloc_free(whole_program);
+ _mesa_glsl_release_types();
+ _mesa_glsl_release_functions();
+
+ return status;
+}
diff --git a/mesalib/src/glsl/ir_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index 2ed66db47..82f90197d 100644 --- a/mesalib/src/glsl/ir_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -1,474 +1,411 @@ -/* - * 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_algebraic.cpp - * - * Takes advantage of association, commutivity, and other algebraic - * properties to simplify expressions. - */ - -#include "ir.h" -#include "ir_visitor.h" -#include "ir_rvalue_visitor.h" -#include "ir_optimization.h" -#include "glsl_types.h" - -/** - * Visitor class for replacing expressions with ir_constant values. - */ - -class ir_algebraic_visitor : public ir_rvalue_visitor { -public: - ir_algebraic_visitor() - { - this->progress = false; - this->mem_ctx = NULL; - } - - virtual ~ir_algebraic_visitor() - { - } - - ir_rvalue *handle_expression(ir_expression *ir); - void handle_rvalue(ir_rvalue **rvalue); - bool reassociate_constant(ir_expression *ir1, - int const_index, - ir_constant *constant, - ir_expression *ir2); - void reassociate_operands(ir_expression *ir1, - int op1, - ir_expression *ir2, - int op2); - ir_rvalue *swizzle_if_required(ir_expression *expr, - ir_rvalue *operand); - - void *mem_ctx; - - bool progress; -}; - -static bool -is_vec_zero(ir_constant *ir) -{ - int c; - - if (!ir) - return false; - if (!ir->type->is_scalar() && - !ir->type->is_vector()) - return false; - - for (c = 0; c < ir->type->vector_elements; c++) { - switch (ir->type->base_type) { - case GLSL_TYPE_FLOAT: - if (ir->value.f[c] != 0.0) - return false; - break; - case GLSL_TYPE_INT: - if (ir->value.i[c] != 0) - return false; - break; - case GLSL_TYPE_UINT: - if (ir->value.u[c] != 0) - return false; - break; - case GLSL_TYPE_BOOL: - if (ir->value.b[c] != false) - return false; - break; - default: - assert(!"bad base type"); - return false; - } - } - - return true; -} - -static bool -is_vec_one(ir_constant *ir) -{ - int c; - - if (!ir) - return false; - if (!ir->type->is_scalar() && - !ir->type->is_vector()) - return false; - - for (c = 0; c < ir->type->vector_elements; c++) { - switch (ir->type->base_type) { - case GLSL_TYPE_FLOAT: - if (ir->value.f[c] != 1.0) - return false; - break; - case GLSL_TYPE_INT: - if (ir->value.i[c] != 1) - return false; - break; - case GLSL_TYPE_UINT: - if (ir->value.u[c] != 1) - return false; - break; - case GLSL_TYPE_BOOL: - if (ir->value.b[c] != true) - return false; - break; - default: - assert(!"bad base type"); - return false; - } - } - - return true; -} - -static void -update_type(ir_expression *ir) -{ - if (ir->operands[0]->type->is_vector()) - ir->type = ir->operands[0]->type; - else - ir->type = ir->operands[1]->type; -} - -void -ir_algebraic_visitor::reassociate_operands(ir_expression *ir1, - int op1, - ir_expression *ir2, - int op2) -{ - ir_rvalue *temp = ir2->operands[op2]; - ir2->operands[op2] = ir1->operands[op1]; - ir1->operands[op1] = temp; - - /* Update the type of ir2. The type of ir1 won't have changed -- - * base types matched, and at least one of the operands of the 2 - * binops is still a vector if any of them were. - */ - update_type(ir2); - - this->progress = true; -} - -/** - * Reassociates a constant down a tree of adds or multiplies. - * - * Consider (2 * (a * (b * 0.5))). We want to send up with a * b. - */ -bool -ir_algebraic_visitor::reassociate_constant(ir_expression *ir1, int const_index, - ir_constant *constant, - ir_expression *ir2) -{ - if (!ir2 || ir1->operation != ir2->operation) - return false; - - /* Don't want to even think about matrices. */ - if (ir1->operands[0]->type->is_matrix() || - ir1->operands[0]->type->is_matrix() || - ir2->operands[1]->type->is_matrix() || - ir2->operands[1]->type->is_matrix()) - return false; - - ir_constant *ir2_const[2]; - ir2_const[0] = ir2->operands[0]->constant_expression_value(); - ir2_const[1] = ir2->operands[1]->constant_expression_value(); - - if (ir2_const[0] && ir2_const[1]) - return false; - - if (ir2_const[0]) { - reassociate_operands(ir1, const_index, ir2, 1); - return true; - } else if (ir2_const[1]) { - reassociate_operands(ir1, const_index, ir2, 0); - return true; - } - - if (reassociate_constant(ir1, const_index, constant, - ir2->operands[0]->as_expression())) { - update_type(ir2); - return true; - } - - if (reassociate_constant(ir1, const_index, constant, - ir2->operands[1]->as_expression())) { - update_type(ir2); - return true; - } - - return false; -} - -/* When eliminating an expression and just returning one of its operands, - * we may need to swizzle that operand out to a vector if the expression was - * vector type. - */ -ir_rvalue * -ir_algebraic_visitor::swizzle_if_required(ir_expression *expr, - ir_rvalue *operand) -{ - if (expr->type->is_vector() && operand->type->is_scalar()) { - return new(mem_ctx) ir_swizzle(operand, 0, 0, 0, 0, - expr->type->vector_elements); - } else - return operand; -} - -ir_rvalue * -ir_algebraic_visitor::handle_expression(ir_expression *ir) -{ - ir_constant *op_const[2] = {NULL, NULL}; - ir_expression *op_expr[2] = {NULL, NULL}; - ir_expression *temp; - unsigned int i; - - for (i = 0; i < ir->get_num_operands(); i++) { - if (ir->operands[i]->type->is_matrix()) - return ir; - - op_const[i] = ir->operands[i]->constant_expression_value(); - op_expr[i] = ir->operands[i]->as_expression(); - } - - if (this->mem_ctx == NULL) - this->mem_ctx = talloc_parent(ir); - - switch (ir->operation) { - case ir_unop_logic_not: { - enum ir_expression_operation new_op = ir_unop_logic_not; - - if (op_expr[0] == NULL) - break; - - switch (op_expr[0]->operation) { - case ir_binop_less: new_op = ir_binop_gequal; break; - case ir_binop_greater: new_op = ir_binop_lequal; break; - case ir_binop_lequal: new_op = ir_binop_greater; break; - case ir_binop_gequal: new_op = ir_binop_less; break; - case ir_binop_equal: new_op = ir_binop_nequal; break; - case ir_binop_nequal: new_op = ir_binop_equal; break; - case ir_binop_all_equal: new_op = ir_binop_any_nequal; break; - case ir_binop_any_nequal: new_op = ir_binop_all_equal; break; - - default: - /* The default case handler is here to silence a warning from GCC. - */ - break; - } - - if (new_op != ir_unop_logic_not) { - this->progress = true; - return new(mem_ctx) ir_expression(new_op, - ir->type, - op_expr[0]->operands[0], - op_expr[0]->operands[1]); - } - - break; - } - - case ir_binop_add: - if (is_vec_zero(op_const[0])) { - this->progress = true; - return swizzle_if_required(ir, ir->operands[1]); - } - if (is_vec_zero(op_const[1])) { - this->progress = true; - return swizzle_if_required(ir, ir->operands[0]); - } - - /* Reassociate addition of constants so that we can do constant - * folding. - */ - if (op_const[0] && !op_const[1]) - reassociate_constant(ir, 0, op_const[0], - ir->operands[1]->as_expression()); - if (op_const[1] && !op_const[0]) - reassociate_constant(ir, 1, op_const[1], - ir->operands[0]->as_expression()); - break; - - case ir_binop_sub: - if (is_vec_zero(op_const[0])) { - this->progress = true; - temp = new(mem_ctx) ir_expression(ir_unop_neg, - ir->operands[1]->type, - ir->operands[1], - NULL); - return swizzle_if_required(ir, temp); - } - if (is_vec_zero(op_const[1])) { - this->progress = true; - return swizzle_if_required(ir, ir->operands[0]); - } - break; - - case ir_binop_mul: - if (is_vec_one(op_const[0])) { - this->progress = true; - return swizzle_if_required(ir, ir->operands[1]); - } - if (is_vec_one(op_const[1])) { - this->progress = true; - return swizzle_if_required(ir, ir->operands[0]); - } - - if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) { - this->progress = true; - return ir_constant::zero(ir, ir->type); - } - - /* Reassociate multiplication of constants so that we can do - * constant folding. - */ - if (op_const[0] && !op_const[1]) - reassociate_constant(ir, 0, op_const[0], - ir->operands[1]->as_expression()); - if (op_const[1] && !op_const[0]) - reassociate_constant(ir, 1, op_const[1], - ir->operands[0]->as_expression()); - - break; - - case ir_binop_div: - if (is_vec_one(op_const[0]) && ir->type->base_type == GLSL_TYPE_FLOAT) { - this->progress = true; - temp = new(mem_ctx) ir_expression(ir_unop_rcp, - ir->operands[1]->type, - ir->operands[1], - NULL); - return swizzle_if_required(ir, temp); - } - if (is_vec_one(op_const[1])) { - this->progress = true; - return swizzle_if_required(ir, ir->operands[0]); - } - break; - - case ir_binop_logic_and: - /* FINISHME: Also simplify (a && a) to (a). */ - if (is_vec_one(op_const[0])) { - this->progress = true; - return ir->operands[1]; - } else if (is_vec_one(op_const[1])) { - this->progress = true; - return ir->operands[0]; - } else if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) { - this->progress = true; - return ir_constant::zero(mem_ctx, ir->type); - } - break; - - case ir_binop_logic_xor: - /* FINISHME: Also simplify (a ^^ a) to (false). */ - if (is_vec_zero(op_const[0])) { - this->progress = true; - return ir->operands[1]; - } else if (is_vec_zero(op_const[1])) { - this->progress = true; - return ir->operands[0]; - } else if (is_vec_one(op_const[0])) { - this->progress = true; - return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type, - ir->operands[1], NULL); - } else if (is_vec_one(op_const[1])) { - this->progress = true; - return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type, - ir->operands[0], NULL); - } - break; - - case ir_binop_logic_or: - /* FINISHME: Also simplify (a || a) to (a). */ - if (is_vec_zero(op_const[0])) { - this->progress = true; - return ir->operands[1]; - } else if (is_vec_zero(op_const[1])) { - this->progress = true; - return ir->operands[0]; - } else if (is_vec_one(op_const[0]) || is_vec_one(op_const[1])) { - ir_constant_data data; - - for (unsigned i = 0; i < 16; i++) - data.b[i] = true; - - this->progress = true; - return new(mem_ctx) ir_constant(ir->type, &data); - } - break; - - case ir_unop_rcp: - if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp) { - this->progress = true; - return op_expr[0]->operands[0]; - } - - /* FINISHME: We should do rcp(rsq(x)) -> sqrt(x) for some - * backends, except that some backends will have done sqrt -> - * rcp(rsq(x)) and we don't want to undo it for them. - */ - - /* As far as we know, all backends are OK with rsq. */ - if (op_expr[0] && op_expr[0]->operation == ir_unop_sqrt) { - this->progress = true; - temp = new(mem_ctx) ir_expression(ir_unop_rsq, - op_expr[0]->operands[0]->type, - op_expr[0]->operands[0], - NULL); - return swizzle_if_required(ir, temp); - } - - break; - - default: - break; - } - - return ir; -} - -void -ir_algebraic_visitor::handle_rvalue(ir_rvalue **rvalue) -{ - if (!*rvalue) - return; - - ir_expression *expr = (*rvalue)->as_expression(); - if (!expr) - return; - - *rvalue = handle_expression(expr); -} - -bool -do_algebraic(exec_list *instructions) -{ - ir_algebraic_visitor v; - - visit_list_elements(&v, instructions); - - return v.progress; -} +/*
+ * 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 opt_algebraic.cpp
+ *
+ * Takes advantage of association, commutivity, and other algebraic
+ * properties to simplify expressions.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_rvalue_visitor.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+/**
+ * Visitor class for replacing expressions with ir_constant values.
+ */
+
+class ir_algebraic_visitor : public ir_rvalue_visitor {
+public:
+ ir_algebraic_visitor()
+ {
+ this->progress = false;
+ this->mem_ctx = NULL;
+ }
+
+ virtual ~ir_algebraic_visitor()
+ {
+ }
+
+ ir_rvalue *handle_expression(ir_expression *ir);
+ void handle_rvalue(ir_rvalue **rvalue);
+ bool reassociate_constant(ir_expression *ir1,
+ int const_index,
+ ir_constant *constant,
+ ir_expression *ir2);
+ void reassociate_operands(ir_expression *ir1,
+ int op1,
+ ir_expression *ir2,
+ int op2);
+ ir_rvalue *swizzle_if_required(ir_expression *expr,
+ ir_rvalue *operand);
+
+ void *mem_ctx;
+
+ bool progress;
+};
+
+static inline bool
+is_vec_zero(ir_constant *ir)
+{
+ return (ir == NULL) ? false : ir->is_zero();
+}
+
+static inline bool
+is_vec_one(ir_constant *ir)
+{
+ return (ir == NULL) ? false : ir->is_one();
+}
+
+static void
+update_type(ir_expression *ir)
+{
+ if (ir->operands[0]->type->is_vector())
+ ir->type = ir->operands[0]->type;
+ else
+ ir->type = ir->operands[1]->type;
+}
+
+void
+ir_algebraic_visitor::reassociate_operands(ir_expression *ir1,
+ int op1,
+ ir_expression *ir2,
+ int op2)
+{
+ ir_rvalue *temp = ir2->operands[op2];
+ ir2->operands[op2] = ir1->operands[op1];
+ ir1->operands[op1] = temp;
+
+ /* Update the type of ir2. The type of ir1 won't have changed --
+ * base types matched, and at least one of the operands of the 2
+ * binops is still a vector if any of them were.
+ */
+ update_type(ir2);
+
+ this->progress = true;
+}
+
+/**
+ * Reassociates a constant down a tree of adds or multiplies.
+ *
+ * Consider (2 * (a * (b * 0.5))). We want to send up with a * b.
+ */
+bool
+ir_algebraic_visitor::reassociate_constant(ir_expression *ir1, int const_index,
+ ir_constant *constant,
+ ir_expression *ir2)
+{
+ if (!ir2 || ir1->operation != ir2->operation)
+ return false;
+
+ /* Don't want to even think about matrices. */
+ if (ir1->operands[0]->type->is_matrix() ||
+ ir1->operands[1]->type->is_matrix() ||
+ ir2->operands[0]->type->is_matrix() ||
+ ir2->operands[1]->type->is_matrix())
+ return false;
+
+ ir_constant *ir2_const[2];
+ ir2_const[0] = ir2->operands[0]->constant_expression_value();
+ ir2_const[1] = ir2->operands[1]->constant_expression_value();
+
+ if (ir2_const[0] && ir2_const[1])
+ return false;
+
+ if (ir2_const[0]) {
+ reassociate_operands(ir1, const_index, ir2, 1);
+ return true;
+ } else if (ir2_const[1]) {
+ reassociate_operands(ir1, const_index, ir2, 0);
+ return true;
+ }
+
+ if (reassociate_constant(ir1, const_index, constant,
+ ir2->operands[0]->as_expression())) {
+ update_type(ir2);
+ return true;
+ }
+
+ if (reassociate_constant(ir1, const_index, constant,
+ ir2->operands[1]->as_expression())) {
+ update_type(ir2);
+ return true;
+ }
+
+ return false;
+}
+
+/* When eliminating an expression and just returning one of its operands,
+ * we may need to swizzle that operand out to a vector if the expression was
+ * vector type.
+ */
+ir_rvalue *
+ir_algebraic_visitor::swizzle_if_required(ir_expression *expr,
+ ir_rvalue *operand)
+{
+ if (expr->type->is_vector() && operand->type->is_scalar()) {
+ return new(mem_ctx) ir_swizzle(operand, 0, 0, 0, 0,
+ expr->type->vector_elements);
+ } else
+ return operand;
+}
+
+ir_rvalue *
+ir_algebraic_visitor::handle_expression(ir_expression *ir)
+{
+ ir_constant *op_const[2] = {NULL, NULL};
+ ir_expression *op_expr[2] = {NULL, NULL};
+ ir_expression *temp;
+ unsigned int i;
+
+ assert(ir->get_num_operands() <= 2);
+ for (i = 0; i < ir->get_num_operands(); i++) {
+ if (ir->operands[i]->type->is_matrix())
+ return ir;
+
+ op_const[i] = ir->operands[i]->constant_expression_value();
+ op_expr[i] = ir->operands[i]->as_expression();
+ }
+
+ if (this->mem_ctx == NULL)
+ this->mem_ctx = talloc_parent(ir);
+
+ switch (ir->operation) {
+ case ir_unop_logic_not: {
+ enum ir_expression_operation new_op = ir_unop_logic_not;
+
+ if (op_expr[0] == NULL)
+ break;
+
+ switch (op_expr[0]->operation) {
+ case ir_binop_less: new_op = ir_binop_gequal; break;
+ case ir_binop_greater: new_op = ir_binop_lequal; break;
+ case ir_binop_lequal: new_op = ir_binop_greater; break;
+ case ir_binop_gequal: new_op = ir_binop_less; break;
+ case ir_binop_equal: new_op = ir_binop_nequal; break;
+ case ir_binop_nequal: new_op = ir_binop_equal; break;
+ case ir_binop_all_equal: new_op = ir_binop_any_nequal; break;
+ case ir_binop_any_nequal: new_op = ir_binop_all_equal; break;
+
+ default:
+ /* The default case handler is here to silence a warning from GCC.
+ */
+ break;
+ }
+
+ if (new_op != ir_unop_logic_not) {
+ this->progress = true;
+ return new(mem_ctx) ir_expression(new_op,
+ ir->type,
+ op_expr[0]->operands[0],
+ op_expr[0]->operands[1]);
+ }
+
+ break;
+ }
+
+ case ir_binop_add:
+ if (is_vec_zero(op_const[0])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[1]);
+ }
+ if (is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[0]);
+ }
+
+ /* Reassociate addition of constants so that we can do constant
+ * folding.
+ */
+ if (op_const[0] && !op_const[1])
+ reassociate_constant(ir, 0, op_const[0],
+ ir->operands[1]->as_expression());
+ if (op_const[1] && !op_const[0])
+ reassociate_constant(ir, 1, op_const[1],
+ ir->operands[0]->as_expression());
+ break;
+
+ case ir_binop_sub:
+ if (is_vec_zero(op_const[0])) {
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_neg,
+ ir->operands[1]->type,
+ ir->operands[1],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ }
+ if (is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[0]);
+ }
+ break;
+
+ case ir_binop_mul:
+ if (is_vec_one(op_const[0])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[1]);
+ }
+ if (is_vec_one(op_const[1])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[0]);
+ }
+
+ if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return ir_constant::zero(ir, ir->type);
+ }
+
+ /* Reassociate multiplication of constants so that we can do
+ * constant folding.
+ */
+ if (op_const[0] && !op_const[1])
+ reassociate_constant(ir, 0, op_const[0],
+ ir->operands[1]->as_expression());
+ if (op_const[1] && !op_const[0])
+ reassociate_constant(ir, 1, op_const[1],
+ ir->operands[0]->as_expression());
+
+ break;
+
+ case ir_binop_div:
+ if (is_vec_one(op_const[0]) && ir->type->base_type == GLSL_TYPE_FLOAT) {
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_rcp,
+ ir->operands[1]->type,
+ ir->operands[1],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ }
+ if (is_vec_one(op_const[1])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[0]);
+ }
+ break;
+
+ case ir_binop_logic_and:
+ /* FINISHME: Also simplify (a && a) to (a). */
+ if (is_vec_one(op_const[0])) {
+ this->progress = true;
+ return ir->operands[1];
+ } else if (is_vec_one(op_const[1])) {
+ this->progress = true;
+ return ir->operands[0];
+ } else if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return ir_constant::zero(mem_ctx, ir->type);
+ }
+ break;
+
+ case ir_binop_logic_xor:
+ /* FINISHME: Also simplify (a ^^ a) to (false). */
+ if (is_vec_zero(op_const[0])) {
+ this->progress = true;
+ return ir->operands[1];
+ } else if (is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return ir->operands[0];
+ } else if (is_vec_one(op_const[0])) {
+ this->progress = true;
+ return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type,
+ ir->operands[1], NULL);
+ } else if (is_vec_one(op_const[1])) {
+ this->progress = true;
+ return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type,
+ ir->operands[0], NULL);
+ }
+ break;
+
+ case ir_binop_logic_or:
+ /* FINISHME: Also simplify (a || a) to (a). */
+ if (is_vec_zero(op_const[0])) {
+ this->progress = true;
+ return ir->operands[1];
+ } else if (is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return ir->operands[0];
+ } else if (is_vec_one(op_const[0]) || is_vec_one(op_const[1])) {
+ ir_constant_data data;
+
+ for (unsigned i = 0; i < 16; i++)
+ data.b[i] = true;
+
+ this->progress = true;
+ return new(mem_ctx) ir_constant(ir->type, &data);
+ }
+ break;
+
+ case ir_unop_rcp:
+ if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp) {
+ this->progress = true;
+ return op_expr[0]->operands[0];
+ }
+
+ /* FINISHME: We should do rcp(rsq(x)) -> sqrt(x) for some
+ * backends, except that some backends will have done sqrt ->
+ * rcp(rsq(x)) and we don't want to undo it for them.
+ */
+
+ /* As far as we know, all backends are OK with rsq. */
+ if (op_expr[0] && op_expr[0]->operation == ir_unop_sqrt) {
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_rsq,
+ op_expr[0]->operands[0]->type,
+ op_expr[0]->operands[0],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ return ir;
+}
+
+void
+ir_algebraic_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_expression *expr = (*rvalue)->as_expression();
+ if (!expr || expr->operation == ir_quadop_vector)
+ return;
+
+ *rvalue = handle_expression(expr);
+}
+
+bool
+do_algebraic(exec_list *instructions)
+{
+ ir_algebraic_visitor v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_constant_folding.cpp b/mesalib/src/glsl/opt_constant_folding.cpp index 554c54fae..d2234b354 100644 --- a/mesalib/src/glsl/ir_constant_folding.cpp +++ b/mesalib/src/glsl/opt_constant_folding.cpp @@ -1,147 +1,147 @@ -/* - * 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_rvalue_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_rvalue_visitor { -public: - ir_constant_folding_visitor() - { - this->progress = false; - } - - virtual ~ir_constant_folding_visitor() - { - /* empty */ - } - - virtual ir_visitor_status visit_enter(ir_assignment *ir); - virtual ir_visitor_status visit_enter(ir_call *ir); - - virtual void handle_rvalue(ir_rvalue **rvalue); - - bool progress; -}; - -void -ir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue) -{ - if (*rvalue == NULL || (*rvalue)->ir_type == ir_type_constant) - return; - - /* Note that we do rvalue visitoring on leaving. So if an - * expression has a non-constant operand, no need to go looking - * down it to find if it's constant. This cuts the time of this - * pass down drastically. - */ - ir_expression *expr = (*rvalue)->as_expression(); - if (expr) { - for (unsigned int i = 0; i < expr->get_num_operands(); i++) { - if (!expr->operands[i]->as_constant()) - return; - } - } - - ir_constant *constant = (*rvalue)->constant_expression_value(); - if (constant) { - *rvalue = constant; - this->progress = true; - } else { - (*rvalue)->accept(this); - } -} - -ir_visitor_status -ir_constant_folding_visitor::visit_enter(ir_assignment *ir) -{ - ir->rhs->accept(this); - handle_rvalue(&ir->rhs); - - if (ir->condition) { - ir->condition->accept(this); - handle_rvalue(&ir->condition); - - ir_constant *const_val = ir->condition->as_constant(); - /* If the condition is constant, either remove the condition or - * remove the never-executed assignment. - */ - if (const_val) { - if (const_val->value.b[0]) - ir->condition = NULL; - else - ir->remove(); - this->progress = true; - } - } - - /* Don't descend into the LHS because we want it to stay as a - * variable dereference. FINISHME: We probably should to get array - * indices though. - */ - return visit_continue_with_parent; -} - -ir_visitor_status -ir_constant_folding_visitor::visit_enter(ir_call *ir) -{ - exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *sig_param = (ir_variable *)sig_iter.get(); - - if (sig_param->mode == ir_var_in) { - ir_rvalue *new_param = param_rval; - - handle_rvalue(&new_param); - if (new_param != param_rval) { - param_rval->replace_with(new_param); - } - } - sig_iter.next(); - } - - return visit_continue_with_parent; -} - -bool -do_constant_folding(exec_list *instructions) -{ - ir_constant_folding_visitor constant_folding; - - visit_list_elements(&constant_folding, instructions); - - return constant_folding.progress; -} +/*
+ * 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 opt_constant_folding.cpp
+ * Replace constant-valued expressions with references to constant values.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_rvalue_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_rvalue_visitor {
+public:
+ ir_constant_folding_visitor()
+ {
+ this->progress = false;
+ }
+
+ virtual ~ir_constant_folding_visitor()
+ {
+ /* empty */
+ }
+
+ virtual ir_visitor_status visit_enter(ir_assignment *ir);
+ virtual ir_visitor_status visit_enter(ir_call *ir);
+
+ virtual void handle_rvalue(ir_rvalue **rvalue);
+
+ bool progress;
+};
+
+void
+ir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (*rvalue == NULL || (*rvalue)->ir_type == ir_type_constant)
+ return;
+
+ /* Note that we do rvalue visitoring on leaving. So if an
+ * expression has a non-constant operand, no need to go looking
+ * down it to find if it's constant. This cuts the time of this
+ * pass down drastically.
+ */
+ ir_expression *expr = (*rvalue)->as_expression();
+ if (expr) {
+ for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
+ if (!expr->operands[i]->as_constant())
+ return;
+ }
+ }
+
+ ir_constant *constant = (*rvalue)->constant_expression_value();
+ if (constant) {
+ *rvalue = constant;
+ this->progress = true;
+ } else {
+ (*rvalue)->accept(this);
+ }
+}
+
+ir_visitor_status
+ir_constant_folding_visitor::visit_enter(ir_assignment *ir)
+{
+ ir->rhs->accept(this);
+ handle_rvalue(&ir->rhs);
+
+ if (ir->condition) {
+ ir->condition->accept(this);
+ handle_rvalue(&ir->condition);
+
+ ir_constant *const_val = ir->condition->as_constant();
+ /* If the condition is constant, either remove the condition or
+ * remove the never-executed assignment.
+ */
+ if (const_val) {
+ if (const_val->value.b[0])
+ ir->condition = NULL;
+ else
+ ir->remove();
+ this->progress = true;
+ }
+ }
+
+ /* Don't descend into the LHS because we want it to stay as a
+ * variable dereference. FINISHME: We probably should to get array
+ * indices though.
+ */
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_constant_folding_visitor::visit_enter(ir_call *ir)
+{
+ exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_rvalue *param_rval = (ir_rvalue *)iter.get();
+ ir_variable *sig_param = (ir_variable *)sig_iter.get();
+
+ if (sig_param->mode == ir_var_in) {
+ ir_rvalue *new_param = param_rval;
+
+ handle_rvalue(&new_param);
+ if (new_param != param_rval) {
+ param_rval->replace_with(new_param);
+ }
+ }
+ sig_iter.next();
+ }
+
+ return visit_continue_with_parent;
+}
+
+bool
+do_constant_folding(exec_list *instructions)
+{
+ ir_constant_folding_visitor constant_folding;
+
+ visit_list_elements(&constant_folding, instructions);
+
+ return constant_folding.progress;
+}
diff --git a/mesalib/src/glsl/ir_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp index 5d875b7be..db797a85f 100644 --- a/mesalib/src/glsl/ir_constant_propagation.cpp +++ b/mesalib/src/glsl/opt_constant_propagation.cpp @@ -1,437 +1,437 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * constant of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, constant, 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 constantright 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 CONSTANTRIGHT 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_propagation.cpp - * - * Tracks assignments of constants to channels of variables, and - * usage of those constant channels with direct usage of the constants. - * - * This can lead to constant folding and algebraic optimizations in - * those later expressions, while causing no increase in instruction - * count (due to constants being generally free to load from a - * constant push buffer or as instruction immediate values) and - * possibly reducing register pressure. - */ - -#include "ir.h" -#include "ir_visitor.h" -#include "ir_rvalue_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 *var, unsigned write_mask, ir_constant *constant) - { - assert(var); - assert(constant); - this->var = var; - this->write_mask = write_mask; - this->constant = constant; - } - - ir_variable *var; - ir_constant *constant; - unsigned write_mask; -}; - - -class kill_entry : public exec_node -{ -public: - kill_entry(ir_variable *var, unsigned write_mask) - { - assert(var); - this->var = var; - this->write_mask = write_mask; - } - - ir_variable *var; - unsigned write_mask; -}; - -class ir_constant_propagation_visitor : public ir_rvalue_visitor { -public: - ir_constant_propagation_visitor() - { - progress = false; - mem_ctx = talloc_new(0); - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - } - ~ir_constant_propagation_visitor() - { - talloc_free(mem_ctx); - } - - 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_leave(class ir_assignment *); - virtual ir_visitor_status visit_enter(class ir_call *); - virtual ir_visitor_status visit_enter(class ir_if *); - - void add_constant(ir_assignment *ir); - void kill(ir_variable *ir, unsigned write_mask); - void handle_if_block(exec_list *instructions); - void handle_rvalue(ir_rvalue **rvalue); - - /** List of acp_entry: The available constants to propagate */ - exec_list *acp; - - /** - * List of kill_entry: The masks of variables whose values were - * killed in this block. - */ - exec_list *kills; - - bool progress; - - bool killed_all; - - void *mem_ctx; -}; - - -void -ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue) -{ - if (this->in_assignee || !*rvalue) - return; - - const glsl_type *type = (*rvalue)->type; - if (!type->is_scalar() && !type->is_vector()) - return; - - ir_swizzle *swiz = NULL; - ir_dereference_variable *deref = (*rvalue)->as_dereference_variable(); - if (!deref) { - swiz = (*rvalue)->as_swizzle(); - if (!swiz) - return; - - deref = swiz->val->as_dereference_variable(); - if (!deref) - return; - } - - ir_constant_data data; - memset(&data, 0, sizeof(data)); - - for (unsigned int i = 0; i < type->components(); i++) { - int channel; - acp_entry *found = NULL; - - if (swiz) { - switch (i) { - case 0: channel = swiz->mask.x; break; - case 1: channel = swiz->mask.y; break; - case 2: channel = swiz->mask.z; break; - case 3: channel = swiz->mask.w; break; - default: assert(!"shouldn't be reached"); channel = 0; break; - } - } else { - channel = i; - } - - foreach_iter(exec_list_iterator, iter, *this->acp) { - acp_entry *entry = (acp_entry *)iter.get(); - if (entry->var == deref->var && entry->write_mask & (1 << channel)) { - found = entry; - break; - } - } - - if (!found) - return; - - int rhs_channel = 0; - for (int j = 0; j < 4; j++) { - if (j == channel) - break; - if (found->write_mask & (1 << j)) - rhs_channel++; - } - - switch (type->base_type) { - case GLSL_TYPE_FLOAT: - data.f[i] = found->constant->value.f[rhs_channel]; - break; - case GLSL_TYPE_INT: - data.i[i] = found->constant->value.i[rhs_channel]; - break; - case GLSL_TYPE_UINT: - data.u[i] = found->constant->value.u[rhs_channel]; - break; - case GLSL_TYPE_BOOL: - data.b[i] = found->constant->value.b[rhs_channel]; - break; - default: - assert(!"not reached"); - break; - } - } - - *rvalue = new(talloc_parent(deref)) ir_constant(type, &data); - this->progress = true; -} - -ir_visitor_status -ir_constant_propagation_visitor::visit_enter(ir_function_signature *ir) -{ - /* Treat entry into a function signature as a completely separate - * block. Any instructions at global scope will be shuffled into - * main() at link time, so they're irrelevant to us. - */ - exec_list *orig_acp = this->acp; - exec_list *orig_kills = this->kills; - bool orig_killed_all = this->killed_all; - - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - this->killed_all = false; - - visit_list_elements(this, &ir->body); - - this->kills = orig_kills; - this->acp = orig_acp; - this->killed_all = orig_killed_all; - - return visit_continue_with_parent; -} - -ir_visitor_status -ir_constant_propagation_visitor::visit_leave(ir_assignment *ir) -{ - if (this->in_assignee) - return visit_continue; - - kill(ir->lhs->variable_referenced(), ir->write_mask); - - add_constant(ir); - - return visit_continue; -} - -ir_visitor_status -ir_constant_propagation_visitor::visit_enter(ir_function *ir) -{ - (void) ir; - return visit_continue; -} - -ir_visitor_status -ir_constant_propagation_visitor::visit_enter(ir_call *ir) -{ - /* Do constant propagation on call parameters, but skip any out params */ - exec_list_iterator sig_param_iter = ir->get_callee()->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, ir->actual_parameters) { - ir_variable *sig_param = (ir_variable *)sig_param_iter.get(); - ir_rvalue *param = (ir_rvalue *)iter.get(); - if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) { - ir_rvalue *new_param = param; - handle_rvalue(&new_param); - if (new_param != param) - param->replace_with(new_param); - else - param->accept(this); - } - sig_param_iter.next(); - } - - /* Since we're unlinked, we don't (necssarily) know the side effects of - * this call. So kill all copies. - */ - acp->make_empty(); - this->killed_all = true; - - return visit_continue_with_parent; -} - -void -ir_constant_propagation_visitor::handle_if_block(exec_list *instructions) -{ - exec_list *orig_acp = this->acp; - exec_list *orig_kills = this->kills; - bool orig_killed_all = this->killed_all; - - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - this->killed_all = false; - - /* Populate the initial acp with a constant of the original */ - foreach_iter(exec_list_iterator, iter, *orig_acp) { - acp_entry *a = (acp_entry *)iter.get(); - this->acp->push_tail(new(this->mem_ctx) acp_entry(a->var, a->write_mask, - a->constant)); - } - - visit_list_elements(this, instructions); - - if (this->killed_all) { - orig_acp->make_empty(); - } - - exec_list *new_kills = this->kills; - this->kills = orig_kills; - this->acp = orig_acp; - this->killed_all = this->killed_all || orig_killed_all; - - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); - kill(k->var, k->write_mask); - } -} - -ir_visitor_status -ir_constant_propagation_visitor::visit_enter(ir_if *ir) -{ - ir->condition->accept(this); - handle_rvalue(&ir->condition); - - handle_if_block(&ir->then_instructions); - handle_if_block(&ir->else_instructions); - - /* handle_if_block() already descended into the children. */ - return visit_continue_with_parent; -} - -ir_visitor_status -ir_constant_propagation_visitor::visit_enter(ir_loop *ir) -{ - exec_list *orig_acp = this->acp; - exec_list *orig_kills = this->kills; - bool orig_killed_all = this->killed_all; - - /* FINISHME: For now, the initial acp for loops is totally empty. - * We could go through once, then go through again with the acp - * cloned minus the killed entries after the first run through. - */ - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - this->killed_all = false; - - visit_list_elements(this, &ir->body_instructions); - - if (this->killed_all) { - orig_acp->make_empty(); - } - - exec_list *new_kills = this->kills; - this->kills = orig_kills; - this->acp = orig_acp; - this->killed_all = this->killed_all || orig_killed_all; - - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); - kill(k->var, k->write_mask); - } - - /* already descended into the children. */ - return visit_continue_with_parent; -} - -void -ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask) -{ - assert(var != NULL); - - /* We don't track non-vectors. */ - if (!var->type->is_vector() && !var->type->is_scalar()) - return; - - /* Remove any entries currently in the ACP for this kill. */ - foreach_iter(exec_list_iterator, iter, *this->acp) { - acp_entry *entry = (acp_entry *)iter.get(); - - if (entry->var == var) { - entry->write_mask &= ~write_mask; - if (entry->write_mask == 0) - entry->remove(); - } - } - - /* Add this writemask of the variable to the list of killed - * variables in this block. - */ - foreach_iter(exec_list_iterator, iter, *this->kills) { - kill_entry *entry = (kill_entry *)iter.get(); - - if (entry->var == var) { - entry->write_mask |= write_mask; - return; - } - } - /* Not already in the list. Make new entry. */ - this->kills->push_tail(new(this->mem_ctx) kill_entry(var, write_mask)); -} - -/** - * Adds an entry to the available constant list if it's a plain assignment - * of a variable to a variable. - */ -void -ir_constant_propagation_visitor::add_constant(ir_assignment *ir) -{ - acp_entry *entry; - - if (ir->condition) { - ir_constant *condition = ir->condition->as_constant(); - if (!condition || !condition->value.b[0]) - return; - } - - if (!ir->write_mask) - return; - - ir_dereference_variable *deref = ir->lhs->as_dereference_variable(); - ir_constant *constant = ir->rhs->as_constant(); - - if (!deref || !constant) - return; - - /* Only do constant propagation on vectors. Constant matrices, - * arrays, or structures would require more work elsewhere. - */ - if (!deref->var->type->is_vector() && !deref->var->type->is_scalar()) - return; - - entry = new(this->mem_ctx) acp_entry(deref->var, ir->write_mask, constant); - this->acp->push_tail(entry); -} - -/** - * Does a constant propagation pass on the code present in the instruction stream. - */ -bool -do_constant_propagation(exec_list *instructions) -{ - ir_constant_propagation_visitor v; - - visit_list_elements(&v, instructions); - - return v.progress; -} +/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * constant of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, constant, 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 constantright 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 CONSTANTRIGHT 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 opt_constant_propagation.cpp
+ *
+ * Tracks assignments of constants to channels of variables, and
+ * usage of those constant channels with direct usage of the constants.
+ *
+ * This can lead to constant folding and algebraic optimizations in
+ * those later expressions, while causing no increase in instruction
+ * count (due to constants being generally free to load from a
+ * constant push buffer or as instruction immediate values) and
+ * possibly reducing register pressure.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_rvalue_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 *var, unsigned write_mask, ir_constant *constant)
+ {
+ assert(var);
+ assert(constant);
+ this->var = var;
+ this->write_mask = write_mask;
+ this->constant = constant;
+ }
+
+ ir_variable *var;
+ ir_constant *constant;
+ unsigned write_mask;
+};
+
+
+class kill_entry : public exec_node
+{
+public:
+ kill_entry(ir_variable *var, unsigned write_mask)
+ {
+ assert(var);
+ this->var = var;
+ this->write_mask = write_mask;
+ }
+
+ ir_variable *var;
+ unsigned write_mask;
+};
+
+class ir_constant_propagation_visitor : public ir_rvalue_visitor {
+public:
+ ir_constant_propagation_visitor()
+ {
+ progress = false;
+ mem_ctx = talloc_new(0);
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ }
+ ~ir_constant_propagation_visitor()
+ {
+ talloc_free(mem_ctx);
+ }
+
+ 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_leave(class ir_assignment *);
+ virtual ir_visitor_status visit_enter(class ir_call *);
+ virtual ir_visitor_status visit_enter(class ir_if *);
+
+ void add_constant(ir_assignment *ir);
+ void kill(ir_variable *ir, unsigned write_mask);
+ void handle_if_block(exec_list *instructions);
+ void handle_rvalue(ir_rvalue **rvalue);
+
+ /** List of acp_entry: The available constants to propagate */
+ exec_list *acp;
+
+ /**
+ * List of kill_entry: The masks of variables whose values were
+ * killed in this block.
+ */
+ exec_list *kills;
+
+ bool progress;
+
+ bool killed_all;
+
+ void *mem_ctx;
+};
+
+
+void
+ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (this->in_assignee || !*rvalue)
+ return;
+
+ const glsl_type *type = (*rvalue)->type;
+ if (!type->is_scalar() && !type->is_vector())
+ return;
+
+ ir_swizzle *swiz = NULL;
+ ir_dereference_variable *deref = (*rvalue)->as_dereference_variable();
+ if (!deref) {
+ swiz = (*rvalue)->as_swizzle();
+ if (!swiz)
+ return;
+
+ deref = swiz->val->as_dereference_variable();
+ if (!deref)
+ return;
+ }
+
+ ir_constant_data data;
+ memset(&data, 0, sizeof(data));
+
+ for (unsigned int i = 0; i < type->components(); i++) {
+ int channel;
+ acp_entry *found = NULL;
+
+ if (swiz) {
+ switch (i) {
+ case 0: channel = swiz->mask.x; break;
+ case 1: channel = swiz->mask.y; break;
+ case 2: channel = swiz->mask.z; break;
+ case 3: channel = swiz->mask.w; break;
+ default: assert(!"shouldn't be reached"); channel = 0; break;
+ }
+ } else {
+ channel = i;
+ }
+
+ foreach_iter(exec_list_iterator, iter, *this->acp) {
+ acp_entry *entry = (acp_entry *)iter.get();
+ if (entry->var == deref->var && entry->write_mask & (1 << channel)) {
+ found = entry;
+ break;
+ }
+ }
+
+ if (!found)
+ return;
+
+ int rhs_channel = 0;
+ for (int j = 0; j < 4; j++) {
+ if (j == channel)
+ break;
+ if (found->write_mask & (1 << j))
+ rhs_channel++;
+ }
+
+ switch (type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ data.f[i] = found->constant->value.f[rhs_channel];
+ break;
+ case GLSL_TYPE_INT:
+ data.i[i] = found->constant->value.i[rhs_channel];
+ break;
+ case GLSL_TYPE_UINT:
+ data.u[i] = found->constant->value.u[rhs_channel];
+ break;
+ case GLSL_TYPE_BOOL:
+ data.b[i] = found->constant->value.b[rhs_channel];
+ break;
+ default:
+ assert(!"not reached");
+ break;
+ }
+ }
+
+ *rvalue = new(talloc_parent(deref)) ir_constant(type, &data);
+ this->progress = true;
+}
+
+ir_visitor_status
+ir_constant_propagation_visitor::visit_enter(ir_function_signature *ir)
+{
+ /* Treat entry into a function signature as a completely separate
+ * block. Any instructions at global scope will be shuffled into
+ * main() at link time, so they're irrelevant to us.
+ */
+ exec_list *orig_acp = this->acp;
+ exec_list *orig_kills = this->kills;
+ bool orig_killed_all = this->killed_all;
+
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ this->killed_all = false;
+
+ visit_list_elements(this, &ir->body);
+
+ this->kills = orig_kills;
+ this->acp = orig_acp;
+ this->killed_all = orig_killed_all;
+
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_constant_propagation_visitor::visit_leave(ir_assignment *ir)
+{
+ if (this->in_assignee)
+ return visit_continue;
+
+ kill(ir->lhs->variable_referenced(), ir->write_mask);
+
+ add_constant(ir);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_constant_propagation_visitor::visit_enter(ir_function *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_constant_propagation_visitor::visit_enter(ir_call *ir)
+{
+ /* Do constant propagation on call parameters, but skip any out params */
+ exec_list_iterator sig_param_iter = ir->get_callee()->parameters.iterator();
+ foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
+ ir_rvalue *param = (ir_rvalue *)iter.get();
+ if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) {
+ ir_rvalue *new_param = param;
+ handle_rvalue(&new_param);
+ if (new_param != param)
+ param->replace_with(new_param);
+ else
+ param->accept(this);
+ }
+ sig_param_iter.next();
+ }
+
+ /* Since we're unlinked, we don't (necssarily) know the side effects of
+ * this call. So kill all copies.
+ */
+ acp->make_empty();
+ this->killed_all = true;
+
+ return visit_continue_with_parent;
+}
+
+void
+ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
+{
+ exec_list *orig_acp = this->acp;
+ exec_list *orig_kills = this->kills;
+ bool orig_killed_all = this->killed_all;
+
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ this->killed_all = false;
+
+ /* Populate the initial acp with a constant of the original */
+ foreach_iter(exec_list_iterator, iter, *orig_acp) {
+ acp_entry *a = (acp_entry *)iter.get();
+ this->acp->push_tail(new(this->mem_ctx) acp_entry(a->var, a->write_mask,
+ a->constant));
+ }
+
+ visit_list_elements(this, instructions);
+
+ if (this->killed_all) {
+ orig_acp->make_empty();
+ }
+
+ exec_list *new_kills = this->kills;
+ this->kills = orig_kills;
+ this->acp = orig_acp;
+ this->killed_all = this->killed_all || orig_killed_all;
+
+ foreach_iter(exec_list_iterator, iter, *new_kills) {
+ kill_entry *k = (kill_entry *)iter.get();
+ kill(k->var, k->write_mask);
+ }
+}
+
+ir_visitor_status
+ir_constant_propagation_visitor::visit_enter(ir_if *ir)
+{
+ ir->condition->accept(this);
+ handle_rvalue(&ir->condition);
+
+ handle_if_block(&ir->then_instructions);
+ handle_if_block(&ir->else_instructions);
+
+ /* handle_if_block() already descended into the children. */
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_constant_propagation_visitor::visit_enter(ir_loop *ir)
+{
+ exec_list *orig_acp = this->acp;
+ exec_list *orig_kills = this->kills;
+ bool orig_killed_all = this->killed_all;
+
+ /* FINISHME: For now, the initial acp for loops is totally empty.
+ * We could go through once, then go through again with the acp
+ * cloned minus the killed entries after the first run through.
+ */
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ this->killed_all = false;
+
+ visit_list_elements(this, &ir->body_instructions);
+
+ if (this->killed_all) {
+ orig_acp->make_empty();
+ }
+
+ exec_list *new_kills = this->kills;
+ this->kills = orig_kills;
+ this->acp = orig_acp;
+ this->killed_all = this->killed_all || orig_killed_all;
+
+ foreach_iter(exec_list_iterator, iter, *new_kills) {
+ kill_entry *k = (kill_entry *)iter.get();
+ kill(k->var, k->write_mask);
+ }
+
+ /* already descended into the children. */
+ return visit_continue_with_parent;
+}
+
+void
+ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask)
+{
+ assert(var != NULL);
+
+ /* We don't track non-vectors. */
+ if (!var->type->is_vector() && !var->type->is_scalar())
+ return;
+
+ /* Remove any entries currently in the ACP for this kill. */
+ foreach_iter(exec_list_iterator, iter, *this->acp) {
+ acp_entry *entry = (acp_entry *)iter.get();
+
+ if (entry->var == var) {
+ entry->write_mask &= ~write_mask;
+ if (entry->write_mask == 0)
+ entry->remove();
+ }
+ }
+
+ /* Add this writemask of the variable to the list of killed
+ * variables in this block.
+ */
+ foreach_iter(exec_list_iterator, iter, *this->kills) {
+ kill_entry *entry = (kill_entry *)iter.get();
+
+ if (entry->var == var) {
+ entry->write_mask |= write_mask;
+ return;
+ }
+ }
+ /* Not already in the list. Make new entry. */
+ this->kills->push_tail(new(this->mem_ctx) kill_entry(var, write_mask));
+}
+
+/**
+ * Adds an entry to the available constant list if it's a plain assignment
+ * of a variable to a variable.
+ */
+void
+ir_constant_propagation_visitor::add_constant(ir_assignment *ir)
+{
+ acp_entry *entry;
+
+ if (ir->condition) {
+ ir_constant *condition = ir->condition->as_constant();
+ if (!condition || !condition->value.b[0])
+ return;
+ }
+
+ if (!ir->write_mask)
+ return;
+
+ ir_dereference_variable *deref = ir->lhs->as_dereference_variable();
+ ir_constant *constant = ir->rhs->as_constant();
+
+ if (!deref || !constant)
+ return;
+
+ /* Only do constant propagation on vectors. Constant matrices,
+ * arrays, or structures would require more work elsewhere.
+ */
+ if (!deref->var->type->is_vector() && !deref->var->type->is_scalar())
+ return;
+
+ entry = new(this->mem_ctx) acp_entry(deref->var, ir->write_mask, constant);
+ this->acp->push_tail(entry);
+}
+
+/**
+ * Does a constant propagation pass on the code present in the instruction stream.
+ */
+bool
+do_constant_propagation(exec_list *instructions)
+{
+ ir_constant_propagation_visitor v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_constant_variable.cpp b/mesalib/src/glsl/opt_constant_variable.cpp index 1fb73e765..fedae851f 100644 --- a/mesalib/src/glsl/ir_constant_variable.cpp +++ b/mesalib/src/glsl/opt_constant_variable.cpp @@ -1,198 +1,198 @@ -/* - * 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; - bool our_scope; -}; - -class ir_constant_variable_visitor : public ir_hierarchical_visitor { -public: - virtual ir_visitor_status visit_enter(ir_dereference_variable *); - virtual ir_visitor_status visit(ir_variable *); - virtual ir_visitor_status visit_enter(ir_assignment *); - virtual ir_visitor_status visit_enter(ir_call *); - - 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(ir_variable *ir) -{ - struct assignment_entry *entry = get_assignment_entry(ir, &this->list); - entry->our_scope = true; - return visit_continue; -} - -/* Skip derefs of variables so that we can detect declarations. */ -ir_visitor_status -ir_constant_variable_visitor::visit_enter(ir_dereference_variable *ir) -{ - (void)ir; - return visit_continue_with_parent; -} - -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->whole_variable_written(); - 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; -} - -ir_visitor_status -ir_constant_variable_visitor::visit_enter(ir_call *ir) -{ - exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *param = (ir_variable *)sig_iter.get(); - - if (param->mode == ir_var_out || - param->mode == ir_var_inout) { - ir_variable *var = param_rval->variable_referenced(); - struct assignment_entry *entry; - - assert(var); - entry = get_assignment_entry(var, &this->list); - entry->assignment_count++; - } - sig_iter.next(); - } - 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->our_scope) { - 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; -} +/*
+ * 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 opt_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;
+ bool our_scope;
+};
+
+class ir_constant_variable_visitor : public ir_hierarchical_visitor {
+public:
+ virtual ir_visitor_status visit_enter(ir_dereference_variable *);
+ virtual ir_visitor_status visit(ir_variable *);
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+ virtual ir_visitor_status visit_enter(ir_call *);
+
+ 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(ir_variable *ir)
+{
+ struct assignment_entry *entry = get_assignment_entry(ir, &this->list);
+ entry->our_scope = true;
+ return visit_continue;
+}
+
+/* Skip derefs of variables so that we can detect declarations. */
+ir_visitor_status
+ir_constant_variable_visitor::visit_enter(ir_dereference_variable *ir)
+{
+ (void)ir;
+ return visit_continue_with_parent;
+}
+
+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->whole_variable_written();
+ 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;
+}
+
+ir_visitor_status
+ir_constant_variable_visitor::visit_enter(ir_call *ir)
+{
+ exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_rvalue *param_rval = (ir_rvalue *)iter.get();
+ ir_variable *param = (ir_variable *)sig_iter.get();
+
+ if (param->mode == ir_var_out ||
+ param->mode == ir_var_inout) {
+ ir_variable *var = param_rval->variable_referenced();
+ struct assignment_entry *entry;
+
+ assert(var);
+ entry = get_assignment_entry(var, &this->list);
+ entry->assignment_count++;
+ }
+ sig_iter.next();
+ }
+ 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->our_scope) {
+ 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;
+}
diff --git a/mesalib/src/glsl/ir_copy_propagation.cpp b/mesalib/src/glsl/opt_copy_propagation.cpp index 0fe8fa6c4..088c4bdbc 100644 --- a/mesalib/src/glsl/ir_copy_propagation.cpp +++ b/mesalib/src/glsl/opt_copy_propagation.cpp @@ -1,348 +1,348 @@ -/* - * 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. - * - * 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 kill_entry : public exec_node -{ -public: - kill_entry(ir_variable *var) - { - assert(var); - this->var = var; - } - - ir_variable *var; -}; - -class ir_copy_propagation_visitor : public ir_hierarchical_visitor { -public: - ir_copy_propagation_visitor() - { - progress = false; - mem_ctx = talloc_new(0); - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - } - ~ir_copy_propagation_visitor() - { - talloc_free(mem_ctx); - } - - 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_leave(class ir_assignment *); - virtual ir_visitor_status visit_enter(class ir_call *); - virtual ir_visitor_status visit_enter(class ir_if *); - - void add_copy(ir_assignment *ir); - void kill(ir_variable *ir); - void handle_if_block(exec_list *instructions); - - /** List of acp_entry: The available copies to propagate */ - exec_list *acp; - /** - * List of kill_entry: The variables whose values were killed in this - * block. - */ - exec_list *kills; - - bool progress; - - bool killed_all; - - void *mem_ctx; -}; - -ir_visitor_status -ir_copy_propagation_visitor::visit_enter(ir_function_signature *ir) -{ - /* Treat entry into a function signature as a completely separate - * block. Any instructions at global scope will be shuffled into - * main() at link time, so they're irrelevant to us. - */ - exec_list *orig_acp = this->acp; - exec_list *orig_kills = this->kills; - bool orig_killed_all = this->killed_all; - - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - this->killed_all = false; - - visit_list_elements(this, &ir->body); - - this->kills = orig_kills; - this->acp = orig_acp; - this->killed_all = orig_killed_all; - - return visit_continue_with_parent; -} - -ir_visitor_status -ir_copy_propagation_visitor::visit_leave(ir_assignment *ir) -{ - kill(ir->lhs->variable_referenced()); - - add_copy(ir); - - return visit_continue; -} - -ir_visitor_status -ir_copy_propagation_visitor::visit_enter(ir_function *ir) -{ - (void) ir; - return visit_continue; -} - -/** - * 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) -{ - if (this->in_assignee) - return visit_continue; - - ir_variable *var = ir->var; - - 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) -{ - /* Do copy propagation on call parameters, but skip any out params */ - exec_list_iterator sig_param_iter = ir->get_callee()->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, ir->actual_parameters) { - ir_variable *sig_param = (ir_variable *)sig_param_iter.get(); - ir_instruction *ir = (ir_instruction *)iter.get(); - if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) { - ir->accept(this); - } - sig_param_iter.next(); - } - - /* Since we're unlinked, we don't (necssarily) know the side effects of - * this call. So kill all copies. - */ - acp->make_empty(); - this->killed_all = true; - - return visit_continue_with_parent; -} - -void -ir_copy_propagation_visitor::handle_if_block(exec_list *instructions) -{ - exec_list *orig_acp = this->acp; - exec_list *orig_kills = this->kills; - bool orig_killed_all = this->killed_all; - - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - this->killed_all = false; - - /* Populate the initial acp with a copy of the original */ - foreach_iter(exec_list_iterator, iter, *orig_acp) { - acp_entry *a = (acp_entry *)iter.get(); - this->acp->push_tail(new(this->mem_ctx) acp_entry(a->lhs, a->rhs)); - } - - visit_list_elements(this, instructions); - - if (this->killed_all) { - orig_acp->make_empty(); - } - - exec_list *new_kills = this->kills; - this->kills = orig_kills; - this->acp = orig_acp; - this->killed_all = this->killed_all || orig_killed_all; - - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); - kill(k->var); - } -} - -ir_visitor_status -ir_copy_propagation_visitor::visit_enter(ir_if *ir) -{ - ir->condition->accept(this); - - handle_if_block(&ir->then_instructions); - handle_if_block(&ir->else_instructions); - - /* handle_if_block() already descended into the children. */ - return visit_continue_with_parent; -} - -ir_visitor_status -ir_copy_propagation_visitor::visit_enter(ir_loop *ir) -{ - exec_list *orig_acp = this->acp; - exec_list *orig_kills = this->kills; - bool orig_killed_all = this->killed_all; - - /* FINISHME: For now, the initial acp for loops is totally empty. - * We could go through once, then go through again with the acp - * cloned minus the killed entries after the first run through. - */ - this->acp = new(mem_ctx) exec_list; - this->kills = new(mem_ctx) exec_list; - this->killed_all = false; - - visit_list_elements(this, &ir->body_instructions); - - if (this->killed_all) { - orig_acp->make_empty(); - } - - exec_list *new_kills = this->kills; - this->kills = orig_kills; - this->acp = orig_acp; - this->killed_all = this->killed_all || orig_killed_all; - - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); - kill(k->var); - } - - /* already descended into the children. */ - return visit_continue_with_parent; -} - -void -ir_copy_propagation_visitor::kill(ir_variable *var) -{ - assert(var != NULL); - - /* Remove any entries currently in the ACP for this kill. */ - foreach_iter(exec_list_iterator, iter, *acp) { - acp_entry *entry = (acp_entry *)iter.get(); - - if (entry->lhs == var || entry->rhs == var) { - entry->remove(); - } - } - - /* Add the LHS variable to the list of killed variables in this block. - */ - this->kills->push_tail(new(this->mem_ctx) kill_entry(var)); -} - -/** - * Adds an entry to the available copy list if it's a plain assignment - * of a variable to a variable. - */ -void -ir_copy_propagation_visitor::add_copy(ir_assignment *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->whole_variable_written(); - ir_variable *rhs_var = ir->rhs->whole_variable_referenced(); - - if ((lhs_var != NULL) && (rhs_var != NULL)) { - if (lhs_var == rhs_var) { - /* This is a dumb assignment, but we've conveniently noticed - * it here. Removing it now would mess up the loop iteration - * calling us. Just flag it to not execute, and someone else - * will clean up the mess. - */ - ir->condition = new(talloc_parent(ir)) ir_constant(false); - this->progress = true; - } else { - entry = new(this->mem_ctx) acp_entry(lhs_var, rhs_var); - this->acp->push_tail(entry); - } - } -} - -/** - * Does a copy propagation pass on the code present in the instruction stream. - */ -bool -do_copy_propagation(exec_list *instructions) -{ - ir_copy_propagation_visitor v; - - visit_list_elements(&v, instructions); - - return v.progress; -} +/*
+ * 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 opt_copy_propagation.cpp
+ *
+ * Moves usage of recently-copied variables to the previous copy of
+ * the variable.
+ *
+ * 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 kill_entry : public exec_node
+{
+public:
+ kill_entry(ir_variable *var)
+ {
+ assert(var);
+ this->var = var;
+ }
+
+ ir_variable *var;
+};
+
+class ir_copy_propagation_visitor : public ir_hierarchical_visitor {
+public:
+ ir_copy_propagation_visitor()
+ {
+ progress = false;
+ mem_ctx = talloc_new(0);
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ }
+ ~ir_copy_propagation_visitor()
+ {
+ talloc_free(mem_ctx);
+ }
+
+ 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_leave(class ir_assignment *);
+ virtual ir_visitor_status visit_enter(class ir_call *);
+ virtual ir_visitor_status visit_enter(class ir_if *);
+
+ void add_copy(ir_assignment *ir);
+ void kill(ir_variable *ir);
+ void handle_if_block(exec_list *instructions);
+
+ /** List of acp_entry: The available copies to propagate */
+ exec_list *acp;
+ /**
+ * List of kill_entry: The variables whose values were killed in this
+ * block.
+ */
+ exec_list *kills;
+
+ bool progress;
+
+ bool killed_all;
+
+ void *mem_ctx;
+};
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_function_signature *ir)
+{
+ /* Treat entry into a function signature as a completely separate
+ * block. Any instructions at global scope will be shuffled into
+ * main() at link time, so they're irrelevant to us.
+ */
+ exec_list *orig_acp = this->acp;
+ exec_list *orig_kills = this->kills;
+ bool orig_killed_all = this->killed_all;
+
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ this->killed_all = false;
+
+ visit_list_elements(this, &ir->body);
+
+ this->kills = orig_kills;
+ this->acp = orig_acp;
+ this->killed_all = orig_killed_all;
+
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_leave(ir_assignment *ir)
+{
+ kill(ir->lhs->variable_referenced());
+
+ add_copy(ir);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_function *ir)
+{
+ (void) ir;
+ return visit_continue;
+}
+
+/**
+ * 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)
+{
+ if (this->in_assignee)
+ return visit_continue;
+
+ ir_variable *var = ir->var;
+
+ 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)
+{
+ /* Do copy propagation on call parameters, but skip any out params */
+ exec_list_iterator sig_param_iter = ir->get_callee()->parameters.iterator();
+ foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) {
+ ir->accept(this);
+ }
+ sig_param_iter.next();
+ }
+
+ /* Since we're unlinked, we don't (necssarily) know the side effects of
+ * this call. So kill all copies.
+ */
+ acp->make_empty();
+ this->killed_all = true;
+
+ return visit_continue_with_parent;
+}
+
+void
+ir_copy_propagation_visitor::handle_if_block(exec_list *instructions)
+{
+ exec_list *orig_acp = this->acp;
+ exec_list *orig_kills = this->kills;
+ bool orig_killed_all = this->killed_all;
+
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ this->killed_all = false;
+
+ /* Populate the initial acp with a copy of the original */
+ foreach_iter(exec_list_iterator, iter, *orig_acp) {
+ acp_entry *a = (acp_entry *)iter.get();
+ this->acp->push_tail(new(this->mem_ctx) acp_entry(a->lhs, a->rhs));
+ }
+
+ visit_list_elements(this, instructions);
+
+ if (this->killed_all) {
+ orig_acp->make_empty();
+ }
+
+ exec_list *new_kills = this->kills;
+ this->kills = orig_kills;
+ this->acp = orig_acp;
+ this->killed_all = this->killed_all || orig_killed_all;
+
+ foreach_iter(exec_list_iterator, iter, *new_kills) {
+ kill_entry *k = (kill_entry *)iter.get();
+ kill(k->var);
+ }
+}
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_if *ir)
+{
+ ir->condition->accept(this);
+
+ handle_if_block(&ir->then_instructions);
+ handle_if_block(&ir->else_instructions);
+
+ /* handle_if_block() already descended into the children. */
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_copy_propagation_visitor::visit_enter(ir_loop *ir)
+{
+ exec_list *orig_acp = this->acp;
+ exec_list *orig_kills = this->kills;
+ bool orig_killed_all = this->killed_all;
+
+ /* FINISHME: For now, the initial acp for loops is totally empty.
+ * We could go through once, then go through again with the acp
+ * cloned minus the killed entries after the first run through.
+ */
+ this->acp = new(mem_ctx) exec_list;
+ this->kills = new(mem_ctx) exec_list;
+ this->killed_all = false;
+
+ visit_list_elements(this, &ir->body_instructions);
+
+ if (this->killed_all) {
+ orig_acp->make_empty();
+ }
+
+ exec_list *new_kills = this->kills;
+ this->kills = orig_kills;
+ this->acp = orig_acp;
+ this->killed_all = this->killed_all || orig_killed_all;
+
+ foreach_iter(exec_list_iterator, iter, *new_kills) {
+ kill_entry *k = (kill_entry *)iter.get();
+ kill(k->var);
+ }
+
+ /* already descended into the children. */
+ return visit_continue_with_parent;
+}
+
+void
+ir_copy_propagation_visitor::kill(ir_variable *var)
+{
+ assert(var != NULL);
+
+ /* Remove any entries currently in the ACP for this kill. */
+ foreach_iter(exec_list_iterator, iter, *acp) {
+ acp_entry *entry = (acp_entry *)iter.get();
+
+ if (entry->lhs == var || entry->rhs == var) {
+ entry->remove();
+ }
+ }
+
+ /* Add the LHS variable to the list of killed variables in this block.
+ */
+ this->kills->push_tail(new(this->mem_ctx) kill_entry(var));
+}
+
+/**
+ * Adds an entry to the available copy list if it's a plain assignment
+ * of a variable to a variable.
+ */
+void
+ir_copy_propagation_visitor::add_copy(ir_assignment *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->whole_variable_written();
+ ir_variable *rhs_var = ir->rhs->whole_variable_referenced();
+
+ if ((lhs_var != NULL) && (rhs_var != NULL)) {
+ if (lhs_var == rhs_var) {
+ /* This is a dumb assignment, but we've conveniently noticed
+ * it here. Removing it now would mess up the loop iteration
+ * calling us. Just flag it to not execute, and someone else
+ * will clean up the mess.
+ */
+ ir->condition = new(talloc_parent(ir)) ir_constant(false);
+ this->progress = true;
+ } else {
+ entry = new(this->mem_ctx) acp_entry(lhs_var, rhs_var);
+ this->acp->push_tail(entry);
+ }
+ }
+}
+
+/**
+ * Does a copy propagation pass on the code present in the instruction stream.
+ */
+bool
+do_copy_propagation(exec_list *instructions)
+{
+ ir_copy_propagation_visitor v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp index 5cf5e99ad..492ba73a1 100644 --- a/mesalib/src/glsl/ir_dead_code.cpp +++ b/mesalib/src/glsl/opt_dead_code.cpp @@ -1,142 +1,142 @@ -/* - * 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_variable_refcount.h" -#include "glsl_types.h" - -static bool debug = false; - -/** - * 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_variable_refcount_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 (debug) { - printf("%s@%p: %d refs, %d assigns, %sdeclared in our scope\n", - entry->var->name, (void *) entry->var, - entry->referenced_count, entry->assigned_count, - entry->declaration ? "" : "not "); - } - - 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->mode != ir_var_out && - entry->var->mode != ir_var_inout && - !ir_has_call(entry->assign)) { - entry->assign->remove(); - progress = true; - - if (debug) { - printf("Removed assignment to %s@%p\n", - entry->var->name, (void *) entry->var); - } - } - } else { - /* If there are no assignments or references to the variable left, - * then we can remove its declaration. - */ - - /* uniform initializers are precious, and could get used by another - * stage. - */ - if (entry->var->mode == ir_var_uniform && - entry->var->constant_value) - continue; - - entry->var->remove(); - progress = true; - - if (debug) { - printf("Removed declaration of %s@%p\n", - entry->var->name, (void *) entry->var); - } - } - } - - 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; -} +/*
+ * 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 opt_dead_code.cpp
+ *
+ * Eliminates dead assignments and variable declarations from the code.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_variable_refcount.h"
+#include "glsl_types.h"
+
+static bool debug = false;
+
+/**
+ * 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_variable_refcount_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 (debug) {
+ printf("%s@%p: %d refs, %d assigns, %sdeclared in our scope\n",
+ entry->var->name, (void *) entry->var,
+ entry->referenced_count, entry->assigned_count,
+ entry->declaration ? "" : "not ");
+ }
+
+ 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->mode != ir_var_out &&
+ entry->var->mode != ir_var_inout &&
+ !ir_has_call(entry->assign)) {
+ entry->assign->remove();
+ progress = true;
+
+ if (debug) {
+ printf("Removed assignment to %s@%p\n",
+ entry->var->name, (void *) entry->var);
+ }
+ }
+ } else {
+ /* If there are no assignments or references to the variable left,
+ * then we can remove its declaration.
+ */
+
+ /* uniform initializers are precious, and could get used by another
+ * stage.
+ */
+ if (entry->var->mode == ir_var_uniform &&
+ entry->var->constant_value)
+ continue;
+
+ entry->var->remove();
+ progress = true;
+
+ if (debug) {
+ printf("Removed declaration of %s@%p\n",
+ entry->var->name, (void *) entry->var);
+ }
+ }
+ }
+
+ 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;
+}
diff --git a/mesalib/src/glsl/ir_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp index 4bbedf0ff..182eccac2 100644 --- a/mesalib/src/glsl/ir_dead_code_local.cpp +++ b/mesalib/src/glsl/opt_dead_code_local.cpp @@ -1,229 +1,229 @@ -/* - * 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(void *ctx, ir_assignment *ir, exec_list *assignments) -{ - 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->whole_variable_written() != 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 available to be removed. - * But not if the assignment has other side effects. - */ - if (ir_has_call(ir)) - return progress; - - 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; - - void *ctx = talloc_new(NULL); - /* 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(ctx, ir_assign, &assignments) || progress; - } else { - kill_for_derefs_visitor kill(&assignments); - ir->accept(&kill); - } - - if (ir == last) - break; - } - *out_progress = progress; - talloc_free(ctx); -} - -/** - * 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; -} +/*
+ * 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 opt_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(void *ctx, ir_assignment *ir, exec_list *assignments)
+{
+ 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->whole_variable_written() != 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 available to be removed.
+ * But not if the assignment has other side effects.
+ */
+ if (ir_has_call(ir))
+ return progress;
+
+ 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;
+
+ void *ctx = talloc_new(NULL);
+ /* 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(ctx, ir_assign, &assignments) || progress;
+ } else {
+ kill_for_derefs_visitor kill(&assignments);
+ ir->accept(&kill);
+ }
+
+ if (ir == last)
+ break;
+ }
+ *out_progress = progress;
+ talloc_free(ctx);
+}
+
+/**
+ * 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;
+}
diff --git a/mesalib/src/glsl/ir_dead_functions.cpp b/mesalib/src/glsl/opt_dead_functions.cpp index 26554441d..6f0761bcc 100644 --- a/mesalib/src/glsl/ir_dead_functions.cpp +++ b/mesalib/src/glsl/opt_dead_functions.cpp @@ -1,151 +1,153 @@ - /* - * 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_functions.cpp - * - * Eliminates unused functions from the linked program. - */ - - #include "ir.h" - #include "ir_visitor.h" - #include "ir_expression_flattening.h" - #include "glsl_types.h" - - class signature_entry : public exec_node - { - public: - signature_entry(ir_function_signature *sig) - { - this->signature = sig; - this->used = false; - } - - ir_function_signature *signature; - bool used; - }; - - class ir_dead_functions_visitor : public ir_hierarchical_visitor { - public: - ir_dead_functions_visitor() - { - this->mem_ctx = talloc_new(NULL); - } - - ~ir_dead_functions_visitor() - { - talloc_free(this->mem_ctx); - } - - virtual ir_visitor_status visit_enter(ir_function_signature *); - virtual ir_visitor_status visit_enter(ir_call *); - - signature_entry *get_signature_entry(ir_function_signature *var); - - bool (*predicate)(ir_instruction *ir); - - /* List of signature_entry */ - exec_list signature_list; - void *mem_ctx; - }; - - - signature_entry * - ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig) - { - foreach_iter(exec_list_iterator, iter, this->signature_list) { - signature_entry *entry = (signature_entry *)iter.get(); - if (entry->signature == sig) - return entry; - } - - signature_entry *entry = new(mem_ctx) signature_entry(sig); - this->signature_list.push_tail(entry); - return entry; - } - - - ir_visitor_status - ir_dead_functions_visitor::visit_enter(ir_function_signature *ir) - { - signature_entry *entry = this->get_signature_entry(ir); - - if (strcmp(ir->function_name(), "main") == 0) { - entry->used = true; - } - - return visit_continue; - } - - - ir_visitor_status - ir_dead_functions_visitor::visit_enter(ir_call *ir) - { - signature_entry *entry = this->get_signature_entry(ir->get_callee()); - - entry->used = true; - - return visit_continue; -} - -bool -do_dead_functions(exec_list *instructions) -{ - ir_dead_functions_visitor v; - bool progress = false; - - visit_list_elements(&v, instructions); - - /* Now that we've figured out which function signatures are used, remove - * the unused ones, and remove function definitions that have no more - * signatures. - */ - foreach_iter(exec_list_iterator, iter, v.signature_list) { - signature_entry *entry = (signature_entry *)iter.get(); - - if (!entry->used) { - entry->signature->remove(); - progress = true; - } - delete(entry); - } - - /* We don't just do this above when we nuked a signature because of - * const pointers. - */ - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - ir_function *func = ir->as_function(); - - if (func && func->signatures.is_empty()) { - /* At this point (post-linking), the symbol table is no - * longer in use, so not removing the function from the - * symbol table should be OK. - */ - func->remove(); - progress = true; - } - } - - return progress; -} + /*
+ * 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 opt_dead_functions.cpp
+ *
+ * Eliminates unused functions from the linked program.
+ */
+
+ #include "ir.h"
+ #include "ir_visitor.h"
+ #include "ir_expression_flattening.h"
+ #include "glsl_types.h"
+
+ class signature_entry : public exec_node
+ {
+ public:
+ signature_entry(ir_function_signature *sig)
+ {
+ this->signature = sig;
+ this->used = false;
+ }
+
+ ir_function_signature *signature;
+ bool used;
+ };
+
+ class ir_dead_functions_visitor : public ir_hierarchical_visitor {
+ public:
+ ir_dead_functions_visitor()
+ {
+ this->mem_ctx = talloc_new(NULL);
+ }
+
+ ~ir_dead_functions_visitor()
+ {
+ talloc_free(this->mem_ctx);
+ }
+
+ virtual ir_visitor_status visit_enter(ir_function_signature *);
+ virtual ir_visitor_status visit_enter(ir_call *);
+
+ signature_entry *get_signature_entry(ir_function_signature *var);
+
+ bool (*predicate)(ir_instruction *ir);
+
+ /* List of signature_entry */
+ exec_list signature_list;
+ void *mem_ctx;
+ };
+
+
+ signature_entry *
+ ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig)
+ {
+ foreach_iter(exec_list_iterator, iter, this->signature_list) {
+ signature_entry *entry = (signature_entry *)iter.get();
+ if (entry->signature == sig)
+ return entry;
+ }
+
+ signature_entry *entry = new(mem_ctx) signature_entry(sig);
+ this->signature_list.push_tail(entry);
+ return entry;
+ }
+
+
+ ir_visitor_status
+ ir_dead_functions_visitor::visit_enter(ir_function_signature *ir)
+ {
+ signature_entry *entry = this->get_signature_entry(ir);
+
+ if (strcmp(ir->function_name(), "main") == 0) {
+ entry->used = true;
+ }
+
+ return visit_continue;
+ }
+
+
+ ir_visitor_status
+ ir_dead_functions_visitor::visit_enter(ir_call *ir)
+ {
+ signature_entry *entry = this->get_signature_entry(ir->get_callee());
+
+ entry->used = true;
+
+ return visit_continue;
+}
+
+bool
+do_dead_functions(exec_list *instructions)
+{
+ ir_dead_functions_visitor v;
+ bool progress = false;
+
+ visit_list_elements(&v, instructions);
+
+ /* Now that we've figured out which function signatures are used, remove
+ * the unused ones, and remove function definitions that have no more
+ * signatures.
+ */
+ foreach_iter(exec_list_iterator, iter, v.signature_list) {
+ signature_entry *entry = (signature_entry *)iter.get();
+
+ if (!entry->used) {
+ entry->signature->remove();
+ delete entry->signature;
+ progress = true;
+ }
+ delete(entry);
+ }
+
+ /* We don't just do this above when we nuked a signature because of
+ * const pointers.
+ */
+ foreach_iter(exec_list_iterator, iter, *instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_function *func = ir->as_function();
+
+ if (func && func->signatures.is_empty()) {
+ /* At this point (post-linking), the symbol table is no
+ * longer in use, so not removing the function from the
+ * symbol table should be OK.
+ */
+ func->remove();
+ delete func;
+ progress = true;
+ }
+ }
+
+ return progress;
+}
diff --git a/mesalib/src/glsl/opt_discard_simplification.cpp b/mesalib/src/glsl/opt_discard_simplification.cpp new file mode 100644 index 000000000..df8caba4d --- /dev/null +++ b/mesalib/src/glsl/opt_discard_simplification.cpp @@ -0,0 +1,180 @@ +/*
+ * 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 opt_discard_simplification.cpp
+ *
+ * This pass simplifies if-statements and loops containing unconditional
+ * discards.
+ *
+ * Case 1: Both branches contain unconditional discards:
+ * -----------------------------------------------------
+ *
+ * if (cond) {
+ * s1;
+ * discard;
+ * s2;
+ * } else {
+ * s3;
+ * discard;
+ * s4;
+ * }
+ *
+ * becomes:
+ *
+ * discard
+ *
+ * Case 2: The "then" clause contains an unconditional discard:
+ * ------------------------------------------------------------
+ *
+ * if (cond) {
+ * s1;
+ * discard;
+ * s2;
+ * } else {
+ * s3;
+ * }
+ *
+ * becomes:
+ *
+ * if (cond) {
+ * discard;
+ * } else {
+ * s3;
+ * }
+ *
+ * Case 3: The "else" clause contains an unconditional discard:
+ * ------------------------------------------------------------
+ *
+ * if (cond) {
+ * s1;
+ * } else {
+ * s2;
+ * discard;
+ * s3;
+ * }
+ *
+ * becomes:
+ *
+ * if (cond) {
+ * s1;
+ * } else {
+ * discard;
+ * }
+ */
+
+#include "glsl_types.h"
+#include "ir.h"
+
+class discard_simplifier : public ir_hierarchical_visitor {
+public:
+ discard_simplifier()
+ {
+ this->progress = false;
+ }
+
+ ir_visitor_status visit_enter(ir_if *);
+ ir_visitor_status visit_enter(ir_loop *);
+
+ bool progress;
+};
+
+static ir_discard *
+find_unconditional_discard(exec_list &instructions)
+{
+ foreach_list(n, &instructions) {
+ ir_discard *ir = ((ir_instruction *) n)->as_discard();
+ if (ir != NULL && ir->condition == NULL)
+ return ir;
+ }
+ return NULL;
+}
+
+static bool
+is_only_instruction(ir_discard *discard)
+{
+ return (discard->prev->is_head_sentinel() &&
+ discard->next->is_tail_sentinel());
+}
+
+ir_visitor_status
+discard_simplifier::visit_enter(ir_if *ir)
+{
+ ir_discard *then_discard = find_unconditional_discard(ir->then_instructions);
+ ir_discard *else_discard = find_unconditional_discard(ir->else_instructions);
+
+ if (then_discard == NULL && else_discard == NULL)
+ return visit_continue;
+
+ /* If both branches result in discard, replace whole if with discard. */
+ if (then_discard != NULL && else_discard != NULL) {
+ this->progress = true;
+ ir->replace_with(then_discard);
+ return visit_continue_with_parent;
+ }
+
+ /* Otherwise, one branch has a discard. */
+ if (then_discard != NULL && !is_only_instruction(then_discard)) {
+ this->progress = true;
+ ir->then_instructions.make_empty();
+ ir->then_instructions.push_tail(then_discard);
+ } else if (else_discard != NULL && !is_only_instruction(else_discard)) {
+ this->progress = true;
+ ir->else_instructions.make_empty();
+ ir->else_instructions.push_tail(else_discard);
+ }
+
+ visit_list_elements(this, &ir->then_instructions);
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+discard_simplifier::visit_enter(ir_loop *ir)
+{
+ ir_discard *discard = find_unconditional_discard(ir->body_instructions);
+
+ if (discard) {
+ ir->replace_with(discard);
+ return visit_continue_with_parent;
+ }
+
+ return visit_continue;
+}
+
+bool
+do_discard_simplification(exec_list *instructions)
+{
+ /* Look for a top-level unconditional discard */
+ ir_discard *discard = find_unconditional_discard(*instructions);
+ if (discard != NULL) {
+ instructions->make_empty();
+ instructions->push_tail(discard);
+ return true;
+ }
+
+ discard_simplifier v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp index 874602c84..83197e11a 100644 --- a/mesalib/src/glsl/ir_function_inlining.cpp +++ b/mesalib/src/glsl/opt_function_inlining.cpp @@ -1,417 +1,424 @@ -/* - * 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 "program/hash_table.h" - -static void -do_sampler_replacement(exec_list *instructions, - ir_variable *sampler, - ir_dereference *deref); - -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; -}; - - -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->replace_with(new(ctx) ir_assignment(lhs, ret->value, NULL)); - } 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_sentinel()); - ret->remove(); - } - } -} - -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_table_pointer_hash, hash_table_pointer_compare); - - 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, "_ret_val", - ir_var_auto); - 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++) { - ir_variable *sig_param = (ir_variable *) sig_param_iter.get(); - ir_rvalue *param = (ir_rvalue *) param_iter.get(); - - /* Generate a new variable for the parameter. */ - if (sig_param->type->base_type == GLSL_TYPE_SAMPLER) { - /* For samplers, we want the inlined sampler references - * referencing the passed in sampler variable, since that - * will have the location information, which an assignment of - * a sampler wouldn't. Fix it up below. - */ - parameters[i] = NULL; - } else { - parameters[i] = sig_param->clone(ctx, 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 (parameters[i] && (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(); - } - - exec_list new_instructions; - - /* Generate the inlined body of the function to a new list */ - foreach_iter(exec_list_iterator, iter, callee->body) { - ir_instruction *ir = (ir_instruction *)iter.get(); - ir_instruction *new_ir = ir->clone(ctx, ht); - - new_instructions.push_tail(new_ir); - visit_tree(new_ir, replace_return_with_assignment, retval); - } - - /* If any samplers were passed in, replace any deref of the sampler - * with a deref of the sampler argument. - */ - param_iter = this->actual_parameters.iterator(); - sig_param_iter = this->callee->parameters.iterator(); - for (i = 0; i < num_parameters; i++) { - ir_instruction *const param = (ir_instruction *) param_iter.get(); - ir_variable *sig_param = (ir_variable *) sig_param_iter.get(); - - if (sig_param->type->base_type == GLSL_TYPE_SAMPLER) { - ir_dereference *deref = param->as_dereference(); - - assert(deref); - do_sampler_replacement(&new_instructions, sig_param, deref); - } - param_iter.next(); - sig_param_iter.next(); - } - - /* Now push those new instructions in. */ - foreach_iter(exec_list_iterator, iter, new_instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - next_ir->insert_before(ir); - } - - /* Copy back the value of any 'out' parameters from the function body - * variables to our own. - */ - i = 0; - param_iter = this->actual_parameters.iterator(); - sig_param_iter = this->callee->parameters.iterator(); - for (i = 0; i < num_parameters; i++) { - ir_instruction *const param = (ir_instruction *) param_iter.get(); - const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get(); - - /* Move our param variable into the actual param if it's an 'out' type. */ - if (parameters[i] && (sig_param->mode == ir_var_out || - sig_param->mode == ir_var_inout)) { - ir_assignment *assign; - - assign = new(ctx) ir_assignment(param->clone(ctx, NULL)->as_rvalue(), - new(ctx) ir_dereference_variable(parameters[i]), - NULL); - next_ir->insert_before(assign); - } - - param_iter.next(); - sig_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)) { - /* If the call was part of some tree, then it should have been - * flattened out or we shouldn't have seen it because of a - * visit_continue_with_parent in this visitor. - */ - assert(ir == base_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; -} - -/** - * Replaces references to the "sampler" variable with a clone of "deref." - * - * From the spec, samplers can appear in the tree as function - * (non-out) parameters and as the result of array indexing and - * structure field selection. In our builtin implementation, they - * also appear in the sampler field of an ir_tex instruction. - */ - -class ir_sampler_replacement_visitor : public ir_hierarchical_visitor { -public: - ir_sampler_replacement_visitor(ir_variable *sampler, ir_dereference *deref) - { - this->sampler = sampler; - this->deref = deref; - } - - virtual ~ir_sampler_replacement_visitor() - { - } - - virtual ir_visitor_status visit_leave(ir_call *); - virtual ir_visitor_status visit_leave(ir_dereference_array *); - virtual ir_visitor_status visit_leave(ir_dereference_record *); - virtual ir_visitor_status visit_leave(ir_texture *); - - void replace_deref(ir_dereference **deref); - void replace_rvalue(ir_rvalue **rvalue); - - ir_variable *sampler; - ir_dereference *deref; -}; - -void -ir_sampler_replacement_visitor::replace_deref(ir_dereference **deref) -{ - ir_dereference_variable *deref_var = (*deref)->as_dereference_variable(); - if (deref_var && deref_var->var == this->sampler) { - *deref = this->deref->clone(talloc_parent(*deref), NULL); - } -} - -void -ir_sampler_replacement_visitor::replace_rvalue(ir_rvalue **rvalue) -{ - if (!*rvalue) - return; - - ir_dereference *deref = (*rvalue)->as_dereference(); - - if (!deref) - return; - - replace_deref(&deref); - *rvalue = deref; -} - -ir_visitor_status -ir_sampler_replacement_visitor::visit_leave(ir_texture *ir) -{ - replace_deref(&ir->sampler); - - return visit_continue; -} - -ir_visitor_status -ir_sampler_replacement_visitor::visit_leave(ir_dereference_array *ir) -{ - replace_rvalue(&ir->array); - return visit_continue; -} - -ir_visitor_status -ir_sampler_replacement_visitor::visit_leave(ir_dereference_record *ir) -{ - replace_rvalue(&ir->record); - return visit_continue; -} - -ir_visitor_status -ir_sampler_replacement_visitor::visit_leave(ir_call *ir) -{ - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param = (ir_rvalue *)iter.get(); - ir_rvalue *new_param = param; - replace_rvalue(&new_param); - - if (new_param != param) { - param->replace_with(new_param); - } - } - return visit_continue; -} - -static void -do_sampler_replacement(exec_list *instructions, - ir_variable *sampler, - ir_dereference *deref) -{ - ir_sampler_replacement_visitor v(sampler, deref); - - visit_list_elements(&v, instructions); -} +/*
+ * 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 opt_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 "program/hash_table.h"
+
+static void
+do_sampler_replacement(exec_list *instructions,
+ ir_variable *sampler,
+ ir_dereference *deref);
+
+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;
+};
+
+
+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->replace_with(new(ctx) ir_assignment(lhs, ret->value, NULL));
+ } 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_sentinel());
+ ret->remove();
+ }
+ }
+}
+
+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_table_pointer_hash, hash_table_pointer_compare);
+
+ 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, "_ret_val",
+ ir_var_auto);
+ 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++) {
+ ir_variable *sig_param = (ir_variable *) sig_param_iter.get();
+ ir_rvalue *param = (ir_rvalue *) param_iter.get();
+
+ /* Generate a new variable for the parameter. */
+ if (sig_param->type->base_type == GLSL_TYPE_SAMPLER) {
+ /* For samplers, we want the inlined sampler references
+ * referencing the passed in sampler variable, since that
+ * will have the location information, which an assignment of
+ * a sampler wouldn't. Fix it up below.
+ */
+ parameters[i] = NULL;
+ } else {
+ parameters[i] = sig_param->clone(ctx, ht);
+ parameters[i]->mode = ir_var_auto;
+
+ /* Remove the read-only decoration becuase we're going to write
+ * directly to this variable. If the cloned variable is left
+ * read-only and the inlined function is inside a loop, the loop
+ * analysis code will get confused.
+ */
+ parameters[i]->read_only = false;
+ next_ir->insert_before(parameters[i]);
+ }
+
+ /* Move the actual param into our param variable if it's an 'in' type. */
+ if (parameters[i] && (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();
+ }
+
+ exec_list new_instructions;
+
+ /* Generate the inlined body of the function to a new list */
+ foreach_iter(exec_list_iterator, iter, callee->body) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_instruction *new_ir = ir->clone(ctx, ht);
+
+ new_instructions.push_tail(new_ir);
+ visit_tree(new_ir, replace_return_with_assignment, retval);
+ }
+
+ /* If any samplers were passed in, replace any deref of the sampler
+ * with a deref of the sampler argument.
+ */
+ param_iter = this->actual_parameters.iterator();
+ sig_param_iter = this->callee->parameters.iterator();
+ for (i = 0; i < num_parameters; i++) {
+ ir_instruction *const param = (ir_instruction *) param_iter.get();
+ ir_variable *sig_param = (ir_variable *) sig_param_iter.get();
+
+ if (sig_param->type->base_type == GLSL_TYPE_SAMPLER) {
+ ir_dereference *deref = param->as_dereference();
+
+ assert(deref);
+ do_sampler_replacement(&new_instructions, sig_param, deref);
+ }
+ param_iter.next();
+ sig_param_iter.next();
+ }
+
+ /* Now push those new instructions in. */
+ foreach_iter(exec_list_iterator, iter, new_instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ next_ir->insert_before(ir);
+ }
+
+ /* Copy back the value of any 'out' parameters from the function body
+ * variables to our own.
+ */
+ i = 0;
+ param_iter = this->actual_parameters.iterator();
+ sig_param_iter = this->callee->parameters.iterator();
+ for (i = 0; i < num_parameters; i++) {
+ ir_instruction *const param = (ir_instruction *) param_iter.get();
+ const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get();
+
+ /* Move our param variable into the actual param if it's an 'out' type. */
+ if (parameters[i] && (sig_param->mode == ir_var_out ||
+ sig_param->mode == ir_var_inout)) {
+ ir_assignment *assign;
+
+ assign = new(ctx) ir_assignment(param->clone(ctx, NULL)->as_rvalue(),
+ new(ctx) ir_dereference_variable(parameters[i]),
+ NULL);
+ next_ir->insert_before(assign);
+ }
+
+ param_iter.next();
+ sig_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)) {
+ /* If the call was part of some tree, then it should have been
+ * flattened out or we shouldn't have seen it because of a
+ * visit_continue_with_parent in this visitor.
+ */
+ assert(ir == base_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;
+}
+
+/**
+ * Replaces references to the "sampler" variable with a clone of "deref."
+ *
+ * From the spec, samplers can appear in the tree as function
+ * (non-out) parameters and as the result of array indexing and
+ * structure field selection. In our builtin implementation, they
+ * also appear in the sampler field of an ir_tex instruction.
+ */
+
+class ir_sampler_replacement_visitor : public ir_hierarchical_visitor {
+public:
+ ir_sampler_replacement_visitor(ir_variable *sampler, ir_dereference *deref)
+ {
+ this->sampler = sampler;
+ this->deref = deref;
+ }
+
+ virtual ~ir_sampler_replacement_visitor()
+ {
+ }
+
+ virtual ir_visitor_status visit_leave(ir_call *);
+ virtual ir_visitor_status visit_leave(ir_dereference_array *);
+ virtual ir_visitor_status visit_leave(ir_dereference_record *);
+ virtual ir_visitor_status visit_leave(ir_texture *);
+
+ void replace_deref(ir_dereference **deref);
+ void replace_rvalue(ir_rvalue **rvalue);
+
+ ir_variable *sampler;
+ ir_dereference *deref;
+};
+
+void
+ir_sampler_replacement_visitor::replace_deref(ir_dereference **deref)
+{
+ ir_dereference_variable *deref_var = (*deref)->as_dereference_variable();
+ if (deref_var && deref_var->var == this->sampler) {
+ *deref = this->deref->clone(talloc_parent(*deref), NULL);
+ }
+}
+
+void
+ir_sampler_replacement_visitor::replace_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_dereference *deref = (*rvalue)->as_dereference();
+
+ if (!deref)
+ return;
+
+ replace_deref(&deref);
+ *rvalue = deref;
+}
+
+ir_visitor_status
+ir_sampler_replacement_visitor::visit_leave(ir_texture *ir)
+{
+ replace_deref(&ir->sampler);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_sampler_replacement_visitor::visit_leave(ir_dereference_array *ir)
+{
+ replace_rvalue(&ir->array);
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_sampler_replacement_visitor::visit_leave(ir_dereference_record *ir)
+{
+ replace_rvalue(&ir->record);
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_sampler_replacement_visitor::visit_leave(ir_call *ir)
+{
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_rvalue *param = (ir_rvalue *)iter.get();
+ ir_rvalue *new_param = param;
+ replace_rvalue(&new_param);
+
+ if (new_param != param) {
+ param->replace_with(new_param);
+ }
+ }
+ return visit_continue;
+}
+
+static void
+do_sampler_replacement(exec_list *instructions,
+ ir_variable *sampler,
+ ir_dereference *deref)
+{
+ ir_sampler_replacement_visitor v(sampler, deref);
+
+ visit_list_elements(&v, instructions);
+}
diff --git a/mesalib/src/glsl/ir_if_simplification.cpp b/mesalib/src/glsl/opt_if_simplification.cpp index 021615ebd..ce94f42fe 100644 --- a/mesalib/src/glsl/ir_if_simplification.cpp +++ b/mesalib/src/glsl/opt_if_simplification.cpp @@ -1,84 +1,84 @@ -/* - * 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_if_simplification.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; -} +/*
+ * 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 opt_if_simplification.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;
+}
diff --git a/mesalib/src/glsl/ir_noop_swizzle.cpp b/mesalib/src/glsl/opt_noop_swizzle.cpp index 0403dfa4e..c034d7339 100644 --- a/mesalib/src/glsl/ir_noop_swizzle.cpp +++ b/mesalib/src/glsl/opt_noop_swizzle.cpp @@ -1,80 +1,80 @@ -/* - * 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_noop_swizzle.cpp - * - * If a swizzle doesn't change the order or count of components, then - * remove the swizzle so that other optimization passes see the value - * behind it. - */ - -#include "ir.h" -#include "ir_visitor.h" -#include "ir_rvalue_visitor.h" -#include "ir_print_visitor.h" -#include "glsl_types.h" - -class ir_noop_swizzle_visitor : public ir_rvalue_visitor { -public: - ir_noop_swizzle_visitor() - { - this->progress = false; - } - - void handle_rvalue(ir_rvalue **rvalue); - bool progress; -}; - -void -ir_noop_swizzle_visitor::handle_rvalue(ir_rvalue **rvalue) -{ - if (!*rvalue) - return; - - ir_swizzle *swiz = (*rvalue)->as_swizzle(); - if (!swiz || swiz->type != swiz->val->type) - return; - - int elems = swiz->val->type->vector_elements; - if (swiz->mask.x != 0) - return; - if (elems >= 2 && swiz->mask.y != 1) - return; - if (elems >= 3 && swiz->mask.z != 2) - return; - if (elems >= 4 && swiz->mask.w != 3) - return; - - this->progress = true; - *rvalue = swiz->val; -} - -bool -do_noop_swizzle(exec_list *instructions) -{ - ir_noop_swizzle_visitor v; - visit_list_elements(&v, instructions); - - return v.progress; -} +/*
+ * 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 opt_noop_swizzle.cpp
+ *
+ * If a swizzle doesn't change the order or count of components, then
+ * remove the swizzle so that other optimization passes see the value
+ * behind it.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_rvalue_visitor.h"
+#include "ir_print_visitor.h"
+#include "glsl_types.h"
+
+class ir_noop_swizzle_visitor : public ir_rvalue_visitor {
+public:
+ ir_noop_swizzle_visitor()
+ {
+ this->progress = false;
+ }
+
+ void handle_rvalue(ir_rvalue **rvalue);
+ bool progress;
+};
+
+void
+ir_noop_swizzle_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_swizzle *swiz = (*rvalue)->as_swizzle();
+ if (!swiz || swiz->type != swiz->val->type)
+ return;
+
+ int elems = swiz->val->type->vector_elements;
+ if (swiz->mask.x != 0)
+ return;
+ if (elems >= 2 && swiz->mask.y != 1)
+ return;
+ if (elems >= 3 && swiz->mask.z != 2)
+ return;
+ if (elems >= 4 && swiz->mask.w != 3)
+ return;
+
+ this->progress = true;
+ *rvalue = swiz->val;
+}
+
+bool
+do_noop_swizzle(exec_list *instructions)
+{
+ ir_noop_swizzle_visitor v;
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/ir_structure_splitting.cpp b/mesalib/src/glsl/opt_structure_splitting.cpp index ff3ec936e..fead62e21 100644 --- a/mesalib/src/glsl/ir_structure_splitting.cpp +++ b/mesalib/src/glsl/opt_structure_splitting.cpp @@ -1,361 +1,361 @@ -/* - * 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_structure_splitting.cpp - * - * If a structure is only ever referenced by its components, then - * split those components out to individual variables so they can be - * handled normally by other optimization passes. - * - * This skips structures like uniforms, which need to be accessible as - * structures for their access by the GL. - */ - -#include "ir.h" -#include "ir_visitor.h" -#include "ir_print_visitor.h" -#include "ir_rvalue_visitor.h" -#include "glsl_types.h" - -static bool debug = false; - -// XXX using variable_entry2 here to avoid collision (MSVC multiply-defined -// function) with the variable_entry class seen in ir_variable_refcount.h -// Perhaps we can use the one in ir_variable_refcount.h and make this class -// here go away? -class variable_entry2 : public exec_node -{ -public: - variable_entry2(ir_variable *var) - { - this->var = var; - this->whole_structure_access = 0; - this->declaration = false; - this->components = NULL; - this->mem_ctx = NULL; - } - - ir_variable *var; /* The key: the variable's pointer. */ - - /** Number of times the variable is referenced, including assignments. */ - unsigned whole_structure_access; - - bool declaration; /* If the variable had a decl in the instruction stream */ - - ir_variable **components; - - /** talloc_parent(this->var) -- the shader's talloc context. */ - void *mem_ctx; -}; - - -class ir_structure_reference_visitor : public ir_hierarchical_visitor { -public: - ir_structure_reference_visitor(void) - { - this->mem_ctx = talloc_new(NULL); - this->variable_list.make_empty(); - } - - ~ir_structure_reference_visitor(void) - { - talloc_free(mem_ctx); - } - - virtual ir_visitor_status visit(ir_variable *); - virtual ir_visitor_status visit(ir_dereference_variable *); - virtual ir_visitor_status visit_enter(ir_dereference_record *); - virtual ir_visitor_status visit_enter(ir_assignment *); - virtual ir_visitor_status visit_enter(ir_function_signature *); - - variable_entry2 *get_variable_entry2(ir_variable *var); - - /* List of variable_entry */ - exec_list variable_list; - - void *mem_ctx; -}; - -variable_entry2 * -ir_structure_reference_visitor::get_variable_entry2(ir_variable *var) -{ - assert(var); - - if (!var->type->is_record() || var->mode == ir_var_uniform) - return NULL; - - foreach_iter(exec_list_iterator, iter, this->variable_list) { - variable_entry2 *entry = (variable_entry2 *)iter.get(); - if (entry->var == var) - return entry; - } - - variable_entry2 *entry = new(mem_ctx) variable_entry2(var); - this->variable_list.push_tail(entry); - return entry; -} - - -ir_visitor_status -ir_structure_reference_visitor::visit(ir_variable *ir) -{ - variable_entry2 *entry = this->get_variable_entry2(ir); - - if (entry) - entry->declaration = true; - - return visit_continue; -} - -ir_visitor_status -ir_structure_reference_visitor::visit(ir_dereference_variable *ir) -{ - ir_variable *const var = ir->variable_referenced(); - variable_entry2 *entry = this->get_variable_entry2(var); - - if (entry) - entry->whole_structure_access++; - - return visit_continue; -} - -ir_visitor_status -ir_structure_reference_visitor::visit_enter(ir_dereference_record *ir) -{ - (void) ir; - /* Don't descend into the ir_dereference_variable below. */ - return visit_continue_with_parent; -} - -ir_visitor_status -ir_structure_reference_visitor::visit_enter(ir_assignment *ir) -{ - if (ir->lhs->as_dereference_variable() && - ir->rhs->as_dereference_variable() && - !ir->condition) { - /* We'll split copies of a structure to copies of components, so don't - * descend to the ir_dereference_variables. - */ - return visit_continue_with_parent; - } - return visit_continue; -} - -ir_visitor_status -ir_structure_reference_visitor::visit_enter(ir_function_signature *ir) -{ - /* We don't want to descend into the function parameters and - * dead-code eliminate them, so just accept the body here. - */ - visit_list_elements(this, &ir->body); - return visit_continue_with_parent; -} - -class ir_structure_splitting_visitor : public ir_rvalue_visitor { -public: - ir_structure_splitting_visitor(exec_list *vars) - { - this->variable_list = vars; - } - - virtual ~ir_structure_splitting_visitor() - { - } - - virtual ir_visitor_status visit_leave(ir_assignment *); - - void split_deref(ir_dereference **deref); - void handle_rvalue(ir_rvalue **rvalue); - variable_entry2 *get_splitting_entry(ir_variable *var); - - exec_list *variable_list; - void *mem_ctx; -}; - -variable_entry2 * -ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var) -{ - assert(var); - - if (!var->type->is_record()) - return NULL; - - foreach_iter(exec_list_iterator, iter, *this->variable_list) { - variable_entry2 *entry = (variable_entry2 *)iter.get(); - if (entry->var == var) { - return entry; - } - } - - return NULL; -} - -void -ir_structure_splitting_visitor::split_deref(ir_dereference **deref) -{ - if ((*deref)->ir_type != ir_type_dereference_record) - return; - - ir_dereference_record *deref_record = (ir_dereference_record *)*deref; - ir_dereference_variable *deref_var = deref_record->record->as_dereference_variable(); - if (!deref_var) - return; - - variable_entry2 *entry = get_splitting_entry(deref_var->var); - if (!entry) - return; - - unsigned int i; - for (i = 0; i < entry->var->type->length; i++) { - if (strcmp(deref_record->field, - entry->var->type->fields.structure[i].name) == 0) - break; - } - assert(i != entry->var->type->length); - - *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[i]); -} - -void -ir_structure_splitting_visitor::handle_rvalue(ir_rvalue **rvalue) -{ - if (!*rvalue) - return; - - ir_dereference *deref = (*rvalue)->as_dereference(); - - if (!deref) - return; - - split_deref(&deref); - *rvalue = deref; -} - -ir_visitor_status -ir_structure_splitting_visitor::visit_leave(ir_assignment *ir) -{ - ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable(); - ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable(); - variable_entry2 *lhs_entry = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL; - variable_entry2 *rhs_entry = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL; - const glsl_type *type = ir->rhs->type; - - if ((lhs_entry || rhs_entry) && !ir->condition) { - for (unsigned int i = 0; i < type->length; i++) { - ir_dereference *new_lhs, *new_rhs; - void *mem_ctx = lhs_entry ? lhs_entry->mem_ctx : rhs_entry->mem_ctx; - - if (lhs_entry) { - new_lhs = new(mem_ctx) ir_dereference_variable(lhs_entry->components[i]); - } else { - new_lhs = new(mem_ctx) - ir_dereference_record(ir->lhs->clone(mem_ctx, NULL), - type->fields.structure[i].name); - } - - if (rhs_entry) { - new_rhs = new(mem_ctx) ir_dereference_variable(rhs_entry->components[i]); - } else { - new_rhs = new(mem_ctx) - ir_dereference_record(ir->rhs->clone(mem_ctx, NULL), - type->fields.structure[i].name); - } - - ir->insert_before(new(mem_ctx) ir_assignment(new_lhs, - new_rhs, - NULL)); - } - ir->remove(); - } else { - handle_rvalue(&ir->rhs); - split_deref(&ir->lhs); - } - - handle_rvalue(&ir->condition); - - return visit_continue; -} - -bool -do_structure_splitting(exec_list *instructions) -{ - ir_structure_reference_visitor refs; - - visit_list_elements(&refs, instructions); - - /* Trim out variables we can't split. */ - foreach_iter(exec_list_iterator, iter, refs.variable_list) { - variable_entry2 *entry = (variable_entry2 *)iter.get(); - - if (debug) { - printf("structure %s@%p: decl %d, whole_access %d\n", - entry->var->name, (void *) entry->var, entry->declaration, - entry->whole_structure_access); - } - - if (!entry->declaration || entry->whole_structure_access) { - entry->remove(); - } - } - - if (refs.variable_list.is_empty()) - return false; - - void *mem_ctx = talloc_new(NULL); - - /* Replace the decls of the structures to be split with their split - * components. - */ - foreach_iter(exec_list_iterator, iter, refs.variable_list) { - variable_entry2 *entry = (variable_entry2 *)iter.get(); - const struct glsl_type *type = entry->var->type; - - entry->mem_ctx = talloc_parent(entry->var); - - entry->components = talloc_array(mem_ctx, - ir_variable *, - type->length); - - for (unsigned int i = 0; i < entry->var->type->length; i++) { - const char *name = talloc_asprintf(mem_ctx, "%s_%s", - entry->var->name, - type->fields.structure[i].name); - - entry->components[i] = - new(entry->mem_ctx) ir_variable(type->fields.structure[i].type, - name, - ir_var_temporary); - entry->var->insert_before(entry->components[i]); - } - - entry->var->remove(); - } - - ir_structure_splitting_visitor split(&refs.variable_list); - visit_list_elements(&split, instructions); - - talloc_free(mem_ctx); - - return true; -} +/*
+ * 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 opt_structure_splitting.cpp
+ *
+ * If a structure is only ever referenced by its components, then
+ * split those components out to individual variables so they can be
+ * handled normally by other optimization passes.
+ *
+ * This skips structures like uniforms, which need to be accessible as
+ * structures for their access by the GL.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_print_visitor.h"
+#include "ir_rvalue_visitor.h"
+#include "glsl_types.h"
+
+static bool debug = false;
+
+// XXX using variable_entry2 here to avoid collision (MSVC multiply-defined
+// function) with the variable_entry class seen in ir_variable_refcount.h
+// Perhaps we can use the one in ir_variable_refcount.h and make this class
+// here go away?
+class variable_entry2 : public exec_node
+{
+public:
+ variable_entry2(ir_variable *var)
+ {
+ this->var = var;
+ this->whole_structure_access = 0;
+ this->declaration = false;
+ this->components = NULL;
+ this->mem_ctx = NULL;
+ }
+
+ ir_variable *var; /* The key: the variable's pointer. */
+
+ /** Number of times the variable is referenced, including assignments. */
+ unsigned whole_structure_access;
+
+ bool declaration; /* If the variable had a decl in the instruction stream */
+
+ ir_variable **components;
+
+ /** talloc_parent(this->var) -- the shader's talloc context. */
+ void *mem_ctx;
+};
+
+
+class ir_structure_reference_visitor : public ir_hierarchical_visitor {
+public:
+ ir_structure_reference_visitor(void)
+ {
+ this->mem_ctx = talloc_new(NULL);
+ this->variable_list.make_empty();
+ }
+
+ ~ir_structure_reference_visitor(void)
+ {
+ talloc_free(mem_ctx);
+ }
+
+ virtual ir_visitor_status visit(ir_variable *);
+ virtual ir_visitor_status visit(ir_dereference_variable *);
+ virtual ir_visitor_status visit_enter(ir_dereference_record *);
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+ virtual ir_visitor_status visit_enter(ir_function_signature *);
+
+ variable_entry2 *get_variable_entry2(ir_variable *var);
+
+ /* List of variable_entry */
+ exec_list variable_list;
+
+ void *mem_ctx;
+};
+
+variable_entry2 *
+ir_structure_reference_visitor::get_variable_entry2(ir_variable *var)
+{
+ assert(var);
+
+ if (!var->type->is_record() || var->mode == ir_var_uniform)
+ return NULL;
+
+ foreach_iter(exec_list_iterator, iter, this->variable_list) {
+ variable_entry2 *entry = (variable_entry2 *)iter.get();
+ if (entry->var == var)
+ return entry;
+ }
+
+ variable_entry2 *entry = new(mem_ctx) variable_entry2(var);
+ this->variable_list.push_tail(entry);
+ return entry;
+}
+
+
+ir_visitor_status
+ir_structure_reference_visitor::visit(ir_variable *ir)
+{
+ variable_entry2 *entry = this->get_variable_entry2(ir);
+
+ if (entry)
+ entry->declaration = true;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_structure_reference_visitor::visit(ir_dereference_variable *ir)
+{
+ ir_variable *const var = ir->variable_referenced();
+ variable_entry2 *entry = this->get_variable_entry2(var);
+
+ if (entry)
+ entry->whole_structure_access++;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_structure_reference_visitor::visit_enter(ir_dereference_record *ir)
+{
+ (void) ir;
+ /* Don't descend into the ir_dereference_variable below. */
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_structure_reference_visitor::visit_enter(ir_assignment *ir)
+{
+ if (ir->lhs->as_dereference_variable() &&
+ ir->rhs->as_dereference_variable() &&
+ !ir->condition) {
+ /* We'll split copies of a structure to copies of components, so don't
+ * descend to the ir_dereference_variables.
+ */
+ return visit_continue_with_parent;
+ }
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_structure_reference_visitor::visit_enter(ir_function_signature *ir)
+{
+ /* We don't want to descend into the function parameters and
+ * dead-code eliminate them, so just accept the body here.
+ */
+ visit_list_elements(this, &ir->body);
+ return visit_continue_with_parent;
+}
+
+class ir_structure_splitting_visitor : public ir_rvalue_visitor {
+public:
+ ir_structure_splitting_visitor(exec_list *vars)
+ {
+ this->variable_list = vars;
+ }
+
+ virtual ~ir_structure_splitting_visitor()
+ {
+ }
+
+ virtual ir_visitor_status visit_leave(ir_assignment *);
+
+ void split_deref(ir_dereference **deref);
+ void handle_rvalue(ir_rvalue **rvalue);
+ variable_entry2 *get_splitting_entry(ir_variable *var);
+
+ exec_list *variable_list;
+ void *mem_ctx;
+};
+
+variable_entry2 *
+ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var)
+{
+ assert(var);
+
+ if (!var->type->is_record())
+ return NULL;
+
+ foreach_iter(exec_list_iterator, iter, *this->variable_list) {
+ variable_entry2 *entry = (variable_entry2 *)iter.get();
+ if (entry->var == var) {
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
+void
+ir_structure_splitting_visitor::split_deref(ir_dereference **deref)
+{
+ if ((*deref)->ir_type != ir_type_dereference_record)
+ return;
+
+ ir_dereference_record *deref_record = (ir_dereference_record *)*deref;
+ ir_dereference_variable *deref_var = deref_record->record->as_dereference_variable();
+ if (!deref_var)
+ return;
+
+ variable_entry2 *entry = get_splitting_entry(deref_var->var);
+ if (!entry)
+ return;
+
+ unsigned int i;
+ for (i = 0; i < entry->var->type->length; i++) {
+ if (strcmp(deref_record->field,
+ entry->var->type->fields.structure[i].name) == 0)
+ break;
+ }
+ assert(i != entry->var->type->length);
+
+ *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[i]);
+}
+
+void
+ir_structure_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_dereference *deref = (*rvalue)->as_dereference();
+
+ if (!deref)
+ return;
+
+ split_deref(&deref);
+ *rvalue = deref;
+}
+
+ir_visitor_status
+ir_structure_splitting_visitor::visit_leave(ir_assignment *ir)
+{
+ ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable();
+ ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable();
+ variable_entry2 *lhs_entry = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL;
+ variable_entry2 *rhs_entry = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL;
+ const glsl_type *type = ir->rhs->type;
+
+ if ((lhs_entry || rhs_entry) && !ir->condition) {
+ for (unsigned int i = 0; i < type->length; i++) {
+ ir_dereference *new_lhs, *new_rhs;
+ void *mem_ctx = lhs_entry ? lhs_entry->mem_ctx : rhs_entry->mem_ctx;
+
+ if (lhs_entry) {
+ new_lhs = new(mem_ctx) ir_dereference_variable(lhs_entry->components[i]);
+ } else {
+ new_lhs = new(mem_ctx)
+ ir_dereference_record(ir->lhs->clone(mem_ctx, NULL),
+ type->fields.structure[i].name);
+ }
+
+ if (rhs_entry) {
+ new_rhs = new(mem_ctx) ir_dereference_variable(rhs_entry->components[i]);
+ } else {
+ new_rhs = new(mem_ctx)
+ ir_dereference_record(ir->rhs->clone(mem_ctx, NULL),
+ type->fields.structure[i].name);
+ }
+
+ ir->insert_before(new(mem_ctx) ir_assignment(new_lhs,
+ new_rhs,
+ NULL));
+ }
+ ir->remove();
+ } else {
+ handle_rvalue(&ir->rhs);
+ split_deref(&ir->lhs);
+ }
+
+ handle_rvalue(&ir->condition);
+
+ return visit_continue;
+}
+
+bool
+do_structure_splitting(exec_list *instructions)
+{
+ ir_structure_reference_visitor refs;
+
+ visit_list_elements(&refs, instructions);
+
+ /* Trim out variables we can't split. */
+ foreach_iter(exec_list_iterator, iter, refs.variable_list) {
+ variable_entry2 *entry = (variable_entry2 *)iter.get();
+
+ if (debug) {
+ printf("structure %s@%p: decl %d, whole_access %d\n",
+ entry->var->name, (void *) entry->var, entry->declaration,
+ entry->whole_structure_access);
+ }
+
+ if (!entry->declaration || entry->whole_structure_access) {
+ entry->remove();
+ }
+ }
+
+ if (refs.variable_list.is_empty())
+ return false;
+
+ void *mem_ctx = talloc_new(NULL);
+
+ /* Replace the decls of the structures to be split with their split
+ * components.
+ */
+ foreach_iter(exec_list_iterator, iter, refs.variable_list) {
+ variable_entry2 *entry = (variable_entry2 *)iter.get();
+ const struct glsl_type *type = entry->var->type;
+
+ entry->mem_ctx = talloc_parent(entry->var);
+
+ entry->components = talloc_array(mem_ctx,
+ ir_variable *,
+ type->length);
+
+ for (unsigned int i = 0; i < entry->var->type->length; i++) {
+ const char *name = talloc_asprintf(mem_ctx, "%s_%s",
+ entry->var->name,
+ type->fields.structure[i].name);
+
+ entry->components[i] =
+ new(entry->mem_ctx) ir_variable(type->fields.structure[i].type,
+ name,
+ ir_var_temporary);
+ entry->var->insert_before(entry->components[i]);
+ }
+
+ entry->var->remove();
+ }
+
+ ir_structure_splitting_visitor split(&refs.variable_list);
+ visit_list_elements(&split, instructions);
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
diff --git a/mesalib/src/glsl/ir_swizzle_swizzle.cpp b/mesalib/src/glsl/opt_swizzle_swizzle.cpp index 0ffb4fa31..e23655240 100644 --- a/mesalib/src/glsl/ir_swizzle_swizzle.cpp +++ b/mesalib/src/glsl/opt_swizzle_swizzle.cpp @@ -1,93 +1,93 @@ -/* - * 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; -} +/*
+ * 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 opt_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;
+}
diff --git a/mesalib/src/glsl/ir_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp index 9b569b828..556f8258b 100644 --- a/mesalib/src/glsl/ir_tree_grafting.cpp +++ b/mesalib/src/glsl/opt_tree_grafting.cpp @@ -1,367 +1,367 @@ -/* - * 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_tree_grafting.cpp - * - * Takes assignments to variables that are dereferenced only once and - * pastes the RHS expression into where the variable is dereferenced. - * - * In the process of various operations like function inlining and - * tertiary op handling, we'll end up with our expression trees having - * been chopped up into a series of assignments of short expressions - * to temps. Other passes like ir_algebraic.cpp would prefer to see - * the deepest expression trees they can to try to optimize them. - * - * This is a lot like copy propagaton. In comparison, copy - * propagation only acts on plain copies, not arbitrary expressions on - * the RHS. Generally, we wouldn't want to go pasting some - * complicated expression everywhere it got used, though, so we don't - * handle expressions in that pass. - * - * The hard part is making sure we don't move an expression across - * some other assignments that would change the value of the - * expression. So we split this into two passes: First, find the - * variables in our scope which are written to once and read once, and - * then go through basic blocks seeing if we find an opportunity to - * move those expressions safely. - */ - -#include "ir.h" -#include "ir_visitor.h" -#include "ir_variable_refcount.h" -#include "ir_basic_block.h" -#include "ir_optimization.h" -#include "glsl_types.h" - -static bool debug = false; - -class ir_tree_grafting_visitor : public ir_hierarchical_visitor { -public: - ir_tree_grafting_visitor(ir_assignment *graft_assign, - ir_variable *graft_var) - { - this->progress = false; - this->graft_assign = graft_assign; - this->graft_var = graft_var; - } - - virtual ir_visitor_status visit_leave(class ir_assignment *); - virtual ir_visitor_status visit_enter(class ir_call *); - virtual ir_visitor_status visit_enter(class ir_expression *); - virtual ir_visitor_status visit_enter(class ir_function *); - virtual ir_visitor_status visit_enter(class ir_function_signature *); - virtual ir_visitor_status visit_enter(class ir_if *); - virtual ir_visitor_status visit_enter(class ir_loop *); - virtual ir_visitor_status visit_enter(class ir_swizzle *); - virtual ir_visitor_status visit_enter(class ir_texture *); - - bool do_graft(ir_rvalue **rvalue); - - bool progress; - ir_variable *graft_var; - ir_assignment *graft_assign; -}; - -struct find_deref_info { - ir_variable *var; - bool found; -}; - -void -dereferences_variable_callback(ir_instruction *ir, void *data) -{ - struct find_deref_info *info = (struct find_deref_info *)data; - ir_dereference_variable *deref = ir->as_dereference_variable(); - - if (deref && deref->var == info->var) - info->found = true; -} - -static bool -dereferences_variable(ir_instruction *ir, ir_variable *var) -{ - struct find_deref_info info; - - info.var = var; - info.found = false; - - visit_tree(ir, dereferences_variable_callback, &info); - - return info.found; -} - -bool -ir_tree_grafting_visitor::do_graft(ir_rvalue **rvalue) -{ - if (!*rvalue) - return false; - - ir_dereference_variable *deref = (*rvalue)->as_dereference_variable(); - - if (!deref || deref->var != this->graft_var) - return false; - - if (debug) { - printf("GRAFTING:\n"); - this->graft_assign->print(); - printf("\n"); - printf("TO:\n"); - (*rvalue)->print(); - printf("\n"); - } - - this->graft_assign->remove(); - *rvalue = this->graft_assign->rhs; - - this->progress = true; - return true; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_loop *ir) -{ - (void)ir; - /* Do not traverse into the body of the loop since that is a - * different basic block. - */ - return visit_stop; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_leave(ir_assignment *ir) -{ - if (do_graft(&ir->rhs) || - do_graft(&ir->condition)) - return visit_stop; - - /* If this assignment updates a variable used in the assignment - * we're trying to graft, then we're done. - */ - if (dereferences_variable(this->graft_assign->rhs, - ir->lhs->variable_referenced())) { - if (debug) { - printf("graft killed by: "); - ir->print(); - printf("\n"); - } - return visit_stop; - } - - return visit_continue; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_function *ir) -{ - (void) ir; - return visit_continue_with_parent; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_function_signature *ir) -{ - (void)ir; - return visit_continue_with_parent; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_call *ir) -{ - exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator(); - /* Reminder: iterating ir_call iterates its parameters. */ - foreach_iter(exec_list_iterator, iter, *ir) { - ir_variable *sig_param = (ir_variable *)sig_iter.get(); - ir_rvalue *ir = (ir_rvalue *)iter.get(); - ir_rvalue *new_ir = ir; - - if (sig_param->mode != ir_var_in) - continue; - - if (do_graft(&new_ir)) { - ir->replace_with(new_ir); - return visit_stop; - } - sig_iter.next(); - } - - return visit_continue; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_expression *ir) -{ - for (unsigned int i = 0; i < ir->get_num_operands(); i++) { - if (do_graft(&ir->operands[i])) - return visit_stop; - } - - return visit_continue; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_if *ir) -{ - if (do_graft(&ir->condition)) - return visit_stop; - - /* Do not traverse into the body of the if-statement since that is a - * different basic block. - */ - return visit_continue_with_parent; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_swizzle *ir) -{ - if (do_graft(&ir->val)) - return visit_stop; - - return visit_continue; -} - -ir_visitor_status -ir_tree_grafting_visitor::visit_enter(ir_texture *ir) -{ - if (do_graft(&ir->coordinate) || - do_graft(&ir->projector) || - do_graft(&ir->shadow_comparitor)) - return visit_stop; - - switch (ir->op) { - case ir_tex: - break; - case ir_txb: - if (do_graft(&ir->lod_info.bias)) - return visit_stop; - break; - case ir_txf: - case ir_txl: - if (do_graft(&ir->lod_info.lod)) - return visit_stop; - break; - case ir_txd: - if (do_graft(&ir->lod_info.grad.dPdx) || - do_graft(&ir->lod_info.grad.dPdy)) - return visit_stop; - break; - } - - return visit_continue; -} - -struct tree_grafting_info { - ir_variable_refcount_visitor *refs; - bool progress; -}; - -static bool -try_tree_grafting(ir_assignment *start, - ir_variable *lhs_var, - ir_instruction *bb_last) -{ - ir_tree_grafting_visitor v(start, lhs_var); - - if (debug) { - printf("trying to graft: "); - lhs_var->print(); - printf("\n"); - } - - for (ir_instruction *ir = (ir_instruction *)start->next; - ir != bb_last->next; - ir = (ir_instruction *)ir->next) { - - if (debug) { - printf("- "); - ir->print(); - printf("\n"); - } - - ir_visitor_status s = ir->accept(&v); - if (s == visit_stop) - return v.progress; - } - - return false; -} - -static void -tree_grafting_basic_block(ir_instruction *bb_first, - ir_instruction *bb_last, - void *data) -{ - struct tree_grafting_info *info = (struct tree_grafting_info *)data; - ir_instruction *ir, *next; - - for (ir = bb_first, next = (ir_instruction *)ir->next; - ir != bb_last->next; - ir = next, next = (ir_instruction *)ir->next) { - ir_assignment *assign = ir->as_assignment(); - - if (!assign) - continue; - - ir_variable *lhs_var = assign->whole_variable_written(); - if (!lhs_var) - continue; - - if (lhs_var->mode == ir_var_out || - lhs_var->mode == ir_var_inout) - continue; - - variable_entry *entry = info->refs->get_variable_entry(lhs_var); - - if (!entry->declaration || - entry->assigned_count != 1 || - entry->referenced_count != 2) - continue; - - assert(assign == entry->assign); - - /* Found a possibly graftable assignment. Now, walk through the - * rest of the BB seeing if the deref is here, and if nothing interfered with - * pasting its expression's values in between. - */ - info->progress |= try_tree_grafting(assign, lhs_var, bb_last); - } -} - -/** - * Does a copy propagation pass on the code present in the instruction stream. - */ -bool -do_tree_grafting(exec_list *instructions) -{ - ir_variable_refcount_visitor refs; - struct tree_grafting_info info; - - info.progress = false; - info.refs = &refs; - - visit_list_elements(info.refs, instructions); - - call_for_basic_blocks(instructions, tree_grafting_basic_block, &info); - - return info.progress; -} +/*
+ * 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 opt_tree_grafting.cpp
+ *
+ * Takes assignments to variables that are dereferenced only once and
+ * pastes the RHS expression into where the variable is dereferenced.
+ *
+ * In the process of various operations like function inlining and
+ * tertiary op handling, we'll end up with our expression trees having
+ * been chopped up into a series of assignments of short expressions
+ * to temps. Other passes like ir_algebraic.cpp would prefer to see
+ * the deepest expression trees they can to try to optimize them.
+ *
+ * This is a lot like copy propagaton. In comparison, copy
+ * propagation only acts on plain copies, not arbitrary expressions on
+ * the RHS. Generally, we wouldn't want to go pasting some
+ * complicated expression everywhere it got used, though, so we don't
+ * handle expressions in that pass.
+ *
+ * The hard part is making sure we don't move an expression across
+ * some other assignments that would change the value of the
+ * expression. So we split this into two passes: First, find the
+ * variables in our scope which are written to once and read once, and
+ * then go through basic blocks seeing if we find an opportunity to
+ * move those expressions safely.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_variable_refcount.h"
+#include "ir_basic_block.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+
+static bool debug = false;
+
+class ir_tree_grafting_visitor : public ir_hierarchical_visitor {
+public:
+ ir_tree_grafting_visitor(ir_assignment *graft_assign,
+ ir_variable *graft_var)
+ {
+ this->progress = false;
+ this->graft_assign = graft_assign;
+ this->graft_var = graft_var;
+ }
+
+ virtual ir_visitor_status visit_leave(class ir_assignment *);
+ virtual ir_visitor_status visit_enter(class ir_call *);
+ virtual ir_visitor_status visit_enter(class ir_expression *);
+ virtual ir_visitor_status visit_enter(class ir_function *);
+ virtual ir_visitor_status visit_enter(class ir_function_signature *);
+ virtual ir_visitor_status visit_enter(class ir_if *);
+ virtual ir_visitor_status visit_enter(class ir_loop *);
+ virtual ir_visitor_status visit_enter(class ir_swizzle *);
+ virtual ir_visitor_status visit_enter(class ir_texture *);
+
+ bool do_graft(ir_rvalue **rvalue);
+
+ bool progress;
+ ir_variable *graft_var;
+ ir_assignment *graft_assign;
+};
+
+struct find_deref_info {
+ ir_variable *var;
+ bool found;
+};
+
+void
+dereferences_variable_callback(ir_instruction *ir, void *data)
+{
+ struct find_deref_info *info = (struct find_deref_info *)data;
+ ir_dereference_variable *deref = ir->as_dereference_variable();
+
+ if (deref && deref->var == info->var)
+ info->found = true;
+}
+
+static bool
+dereferences_variable(ir_instruction *ir, ir_variable *var)
+{
+ struct find_deref_info info;
+
+ info.var = var;
+ info.found = false;
+
+ visit_tree(ir, dereferences_variable_callback, &info);
+
+ return info.found;
+}
+
+bool
+ir_tree_grafting_visitor::do_graft(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return false;
+
+ ir_dereference_variable *deref = (*rvalue)->as_dereference_variable();
+
+ if (!deref || deref->var != this->graft_var)
+ return false;
+
+ if (debug) {
+ printf("GRAFTING:\n");
+ this->graft_assign->print();
+ printf("\n");
+ printf("TO:\n");
+ (*rvalue)->print();
+ printf("\n");
+ }
+
+ this->graft_assign->remove();
+ *rvalue = this->graft_assign->rhs;
+
+ this->progress = true;
+ return true;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_loop *ir)
+{
+ (void)ir;
+ /* Do not traverse into the body of the loop since that is a
+ * different basic block.
+ */
+ return visit_stop;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_leave(ir_assignment *ir)
+{
+ if (do_graft(&ir->rhs) ||
+ do_graft(&ir->condition))
+ return visit_stop;
+
+ /* If this assignment updates a variable used in the assignment
+ * we're trying to graft, then we're done.
+ */
+ if (dereferences_variable(this->graft_assign->rhs,
+ ir->lhs->variable_referenced())) {
+ if (debug) {
+ printf("graft killed by: ");
+ ir->print();
+ printf("\n");
+ }
+ return visit_stop;
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_function *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_function_signature *ir)
+{
+ (void)ir;
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_call *ir)
+{
+ exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
+ /* Reminder: iterating ir_call iterates its parameters. */
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_variable *sig_param = (ir_variable *)sig_iter.get();
+ ir_rvalue *ir = (ir_rvalue *)iter.get();
+ ir_rvalue *new_ir = ir;
+
+ if (sig_param->mode != ir_var_in)
+ continue;
+
+ if (do_graft(&new_ir)) {
+ ir->replace_with(new_ir);
+ return visit_stop;
+ }
+ sig_iter.next();
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_expression *ir)
+{
+ for (unsigned int i = 0; i < ir->get_num_operands(); i++) {
+ if (do_graft(&ir->operands[i]))
+ return visit_stop;
+ }
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_if *ir)
+{
+ if (do_graft(&ir->condition))
+ return visit_stop;
+
+ /* Do not traverse into the body of the if-statement since that is a
+ * different basic block.
+ */
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_swizzle *ir)
+{
+ if (do_graft(&ir->val))
+ return visit_stop;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
+{
+ if (do_graft(&ir->coordinate) ||
+ do_graft(&ir->projector) ||
+ do_graft(&ir->shadow_comparitor))
+ return visit_stop;
+
+ switch (ir->op) {
+ case ir_tex:
+ break;
+ case ir_txb:
+ if (do_graft(&ir->lod_info.bias))
+ return visit_stop;
+ break;
+ case ir_txf:
+ case ir_txl:
+ if (do_graft(&ir->lod_info.lod))
+ return visit_stop;
+ break;
+ case ir_txd:
+ if (do_graft(&ir->lod_info.grad.dPdx) ||
+ do_graft(&ir->lod_info.grad.dPdy))
+ return visit_stop;
+ break;
+ }
+
+ return visit_continue;
+}
+
+struct tree_grafting_info {
+ ir_variable_refcount_visitor *refs;
+ bool progress;
+};
+
+static bool
+try_tree_grafting(ir_assignment *start,
+ ir_variable *lhs_var,
+ ir_instruction *bb_last)
+{
+ ir_tree_grafting_visitor v(start, lhs_var);
+
+ if (debug) {
+ printf("trying to graft: ");
+ lhs_var->print();
+ printf("\n");
+ }
+
+ for (ir_instruction *ir = (ir_instruction *)start->next;
+ ir != bb_last->next;
+ ir = (ir_instruction *)ir->next) {
+
+ if (debug) {
+ printf("- ");
+ ir->print();
+ printf("\n");
+ }
+
+ ir_visitor_status s = ir->accept(&v);
+ if (s == visit_stop)
+ return v.progress;
+ }
+
+ return false;
+}
+
+static void
+tree_grafting_basic_block(ir_instruction *bb_first,
+ ir_instruction *bb_last,
+ void *data)
+{
+ struct tree_grafting_info *info = (struct tree_grafting_info *)data;
+ ir_instruction *ir, *next;
+
+ for (ir = bb_first, next = (ir_instruction *)ir->next;
+ ir != bb_last->next;
+ ir = next, next = (ir_instruction *)ir->next) {
+ ir_assignment *assign = ir->as_assignment();
+
+ if (!assign)
+ continue;
+
+ ir_variable *lhs_var = assign->whole_variable_written();
+ if (!lhs_var)
+ continue;
+
+ if (lhs_var->mode == ir_var_out ||
+ lhs_var->mode == ir_var_inout)
+ continue;
+
+ variable_entry *entry = info->refs->get_variable_entry(lhs_var);
+
+ if (!entry->declaration ||
+ entry->assigned_count != 1 ||
+ entry->referenced_count != 2)
+ continue;
+
+ assert(assign == entry->assign);
+
+ /* Found a possibly graftable assignment. Now, walk through the
+ * rest of the BB seeing if the deref is here, and if nothing interfered with
+ * pasting its expression's values in between.
+ */
+ info->progress |= try_tree_grafting(assign, lhs_var, bb_last);
+ }
+}
+
+/**
+ * Does a copy propagation pass on the code present in the instruction stream.
+ */
+bool
+do_tree_grafting(exec_list *instructions)
+{
+ ir_variable_refcount_visitor refs;
+ struct tree_grafting_info info;
+
+ info.progress = false;
+ info.refs = &refs;
+
+ visit_list_elements(info.refs, instructions);
+
+ call_for_basic_blocks(instructions, tree_grafting_basic_block, &info);
+
+ return info.progress;
+}
diff --git a/mesalib/src/glsl/program.h b/mesalib/src/glsl/program.h index 893169b6c..6834b42f4 100644 --- a/mesalib/src/glsl/program.h +++ b/mesalib/src/glsl/program.h @@ -1,27 +1,27 @@ -/* - * 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 "main/core.h" - -extern void -link_shaders(GLcontext *ctx, struct gl_shader_program *prog); +/*
+ * 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 "main/core.h"
+
+extern void
+link_shaders(struct gl_context *ctx, struct gl_shader_program *prog);
diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp index 4458c48d6..0aecfa19c 100644 --- a/mesalib/src/glsl/s_expression.cpp +++ b/mesalib/src/glsl/s_expression.cpp @@ -1,140 +1,141 @@ -/* -*- 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, size_t n) -{ - this->str = talloc_strndup (this, tmp, n); - 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) -{ - s_expression *expr = NULL; - - // Skip leading spaces. - src += strspn(src, " \v\t\r\n"); - - size_t n = strcspn(src, "( \v\t\r\n)"); - if (n == 0) - return NULL; // no atom - - // Check if the atom is a number. - char *float_end = NULL; - double f = strtod(src, &float_end); - if (float_end != src) { - char *int_end = NULL; - int i = strtol(src, &int_end, 10); - // If strtod matched more characters, it must have a decimal part - if (float_end > int_end) - expr = new(ctx) s_float(f); - else - expr = new(ctx) s_int(i); - } else { - // Not a number; return a symbol. - expr = new(ctx) s_symbol(src, n); - } - - src += n; - - return expr; -} - -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; - - // Skip leading spaces. - src += strspn(src, " \v\t\r\n"); - if (src[0] == '(') { - ++src; - - s_list *list = new(ctx) s_list; - s_expression *expr; - - while ((expr = read_expression(ctx, src)) != NULL) { - list->subexpressions.push_tail(expr); - } - src += strspn(src, " \v\t\r\n"); - if (src[0] != ')') { - printf("Unclosed expression (check your parenthesis).\n"); - return NULL; - } - ++src; - 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(")"); -} - +/* -*- 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, size_t n)
+{
+ this->str = talloc_strndup (this, tmp, n);
+ 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)
+{
+ s_expression *expr = NULL;
+
+ // Skip leading spaces.
+ src += strspn(src, " \v\t\r\n");
+
+ size_t n = strcspn(src, "( \v\t\r\n)");
+ if (n == 0)
+ return NULL; // no atom
+
+ // Check if the atom is a number.
+ char *float_end = NULL;
+ double f = glsl_strtod(src, &float_end);
+ if (float_end != src) {
+ char *int_end = NULL;
+ int i = strtol(src, &int_end, 10);
+ // If strtod matched more characters, it must have a decimal part
+ if (float_end > int_end)
+ expr = new(ctx) s_float(f);
+ else
+ expr = new(ctx) s_int(i);
+ } else {
+ // Not a number; return a symbol.
+ expr = new(ctx) s_symbol(src, n);
+ }
+
+ src += n;
+
+ return expr;
+}
+
+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;
+
+ // Skip leading spaces.
+ src += strspn(src, " \v\t\r\n");
+ if (src[0] == '(') {
+ ++src;
+
+ s_list *list = new(ctx) s_list;
+ s_expression *expr;
+
+ while ((expr = read_expression(ctx, src)) != NULL) {
+ list->subexpressions.push_tail(expr);
+ }
+ src += strspn(src, " \v\t\r\n");
+ if (src[0] != ')') {
+ printf("Unclosed expression (check your parenthesis).\n");
+ return NULL;
+ }
+ ++src;
+ 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();
+ if (!expr->next->is_tail_sentinel())
+ printf(" ");
+ }
+ printf(")");
+}
+
diff --git a/mesalib/src/glsl/s_expression.h b/mesalib/src/glsl/s_expression.h index aa22475a1..6b5e52f5a 100644 --- a/mesalib/src/glsl/s_expression.h +++ b/mesalib/src/glsl/s_expression.h @@ -1,142 +1,143 @@ -/* -*- 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 *, size_t); - - 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 */ +/* -*- 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 "strtod.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 *, size_t);
+
+ 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 */
diff --git a/mesalib/src/glsl/strtod.c b/mesalib/src/glsl/strtod.c new file mode 100644 index 000000000..630eedff1 --- /dev/null +++ b/mesalib/src/glsl/strtod.c @@ -0,0 +1,56 @@ +/*
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdlib.h>
+
+#ifdef _GNU_SOURCE
+#include <locale.h>
+#ifdef __APPLE__
+#include <xlocale.h>
+#endif
+#endif
+
+#include "strtod.h"
+
+
+
+/**
+ * Wrapper around strtod which uses the "C" locale so the decimal
+ * point is always '.'
+ */
+double
+glsl_strtod(const char *s, char **end)
+{
+#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__)
+ static locale_t loc = NULL;
+ if (!loc) {
+ loc = newlocale(LC_CTYPE_MASK, "C", NULL);
+ }
+ return strtod_l(s, end, loc);
+#else
+ return strtod(s, end);
+#endif
+}
diff --git a/mesalib/src/glsl/strtod.h b/mesalib/src/glsl/strtod.h new file mode 100644 index 000000000..c9ff0a87f --- /dev/null +++ b/mesalib/src/glsl/strtod.h @@ -0,0 +1,43 @@ +/*
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef STRTOD_H
+#define STRTOD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern double
+glsl_strtod(const char *s, char **end);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
|