From 32aaf89823de11e98cb59d5ec78c66cd3e74bcd4 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 15 Nov 2010 14:35:46 -0800 Subject: glsl: Rename various ir_* files to lower_* and opt_*. This helps distinguish between lowering passes, optimization passes, and other compiler code. --- src/glsl/SConscript | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'src/glsl/SConscript') diff --git a/src/glsl/SConscript b/src/glsl/SConscript index c183e208d6..f9cc823a2d 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -27,54 +27,54 @@ sources = [ '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_div_to_mul_rcp.cpp', + 'lower_explog_to_explog2.cpp', + 'lower_if_to_cond_assign.cpp', + 'lower_jumps.cpp', + 'lower_mat_op_to_vec.cpp', + 'lower_mod_to_fract.cpp', 'lower_noise.cpp', + 'lower_sub_to_add_neg.cpp', 'lower_variable_index_to_cond_assign.cpp', + 'lower_vec_index_to_cond_assign.cpp', + 'lower_vec_index_to_swizzle.cpp', + 'opt_algebraic.cpp', + 'opt_constant_folding.cpp', + 'opt_noop_swizzle.cpp', 'opt_redundant_jumps.cpp', + 'opt_constant_expression.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_function_inlining.cpp', + 'opt_if_simplification.cpp', + 'opt_structure_splitting.cpp', + 'opt_swizzle_swizzle.cpp', + 'opt_tree_grafting.cpp', 's_expression.cpp', ] -- cgit v1.2.3 From 9b4b70e7e28e5371ca5fddd6f8c7e09d8efd5ce0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 15 Nov 2010 18:59:39 -0700 Subject: glsl: remove opt_constant_expression.cpp from SConscript And alphabetize the opt_* files. --- src/glsl/SConscript | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/glsl/SConscript') diff --git a/src/glsl/SConscript b/src/glsl/SConscript index f9cc823a2d..20cb91b607 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -61,9 +61,6 @@ sources = [ 'lower_vec_index_to_swizzle.cpp', 'opt_algebraic.cpp', 'opt_constant_folding.cpp', - 'opt_noop_swizzle.cpp', - 'opt_redundant_jumps.cpp', - 'opt_constant_expression.cpp', 'opt_constant_propagation.cpp', 'opt_constant_variable.cpp', 'opt_copy_propagation.cpp', @@ -72,6 +69,8 @@ sources = [ 'opt_dead_functions.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', -- cgit v1.2.3 From 1935bdca44ec1f0a980b6b0c024ff2e4c7032dfe Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Mon, 15 Nov 2010 20:54:12 -0800 Subject: glsl: Add ir_constant_expression.cpp to SConscript. This was accidentally removed in commit 32aaf89823de11e98cb59d5ec78c66cd3e74bcd4. Fixes SCons builds. --- src/glsl/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/glsl/SConscript') diff --git a/src/glsl/SConscript b/src/glsl/SConscript index 20cb91b607..4cb2d8bcb3 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -29,6 +29,7 @@ sources = [ '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', -- cgit v1.2.3 From 63684a9ae7a66f68df1f2c68cd9358e5622122a3 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 18 Nov 2010 17:54:07 -0800 Subject: glsl: Combine many instruction lowering passes into one. This should save on the overhead of tree-walking and provide a convenient place to add more instruction lowering in the future. Signed-off-by: Ian Romanick --- src/glsl/Makefile | 5 +- src/glsl/SConscript | 5 +- src/glsl/glsl_parser_extras.cpp | 2 +- src/glsl/ir_optimization.h | 10 +- src/glsl/lower_div_to_mul_rcp.cpp | 114 --------------- src/glsl/lower_explog_to_explog2.cpp | 85 ------------ src/glsl/lower_instructions.cpp | 262 +++++++++++++++++++++++++++++++++++ src/glsl/lower_mod_to_fract.cpp | 90 ------------ src/glsl/lower_sub_to_add_neg.cpp | 76 ---------- src/mesa/drivers/dri/i965/brw_fs.cpp | 10 +- src/mesa/program/ir_to_mesa.cpp | 5 +- 11 files changed, 281 insertions(+), 383 deletions(-) delete mode 100644 src/glsl/lower_div_to_mul_rcp.cpp delete mode 100644 src/glsl/lower_explog_to_explog2.cpp create mode 100644 src/glsl/lower_instructions.cpp delete mode 100644 src/glsl/lower_mod_to_fract.cpp delete mode 100644 src/glsl/lower_sub_to_add_neg.cpp (limited to 'src/glsl/SConscript') diff --git a/src/glsl/Makefile b/src/glsl/Makefile index ea4d6be5a4..f5aadc347b 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -52,14 +52,11 @@ CXX_SOURCES = \ loop_analysis.cpp \ loop_controls.cpp \ loop_unroll.cpp \ - lower_div_to_mul_rcp.cpp \ - lower_explog_to_explog2.cpp \ lower_if_to_cond_assign.cpp \ + lower_instructions.cpp \ lower_jumps.cpp \ lower_mat_op_to_vec.cpp \ - lower_mod_to_fract.cpp \ lower_noise.cpp \ - lower_sub_to_add_neg.cpp \ lower_texture_projection.cpp \ lower_variable_index_to_cond_assign.cpp \ lower_vec_index_to_cond_assign.cpp \ diff --git a/src/glsl/SConscript b/src/glsl/SConscript index 4cb2d8bcb3..f708635e53 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -49,14 +49,11 @@ sources = [ 'loop_analysis.cpp', 'loop_controls.cpp', 'loop_unroll.cpp', - 'lower_div_to_mul_rcp.cpp', - 'lower_explog_to_explog2.cpp', 'lower_if_to_cond_assign.cpp', + 'lower_instructions.cpp', 'lower_jumps.cpp', 'lower_mat_op_to_vec.cpp', - 'lower_mod_to_fract.cpp', 'lower_noise.cpp', - 'lower_sub_to_add_neg.cpp', 'lower_variable_index_to_cond_assign.cpp', 'lower_vec_index_to_cond_assign.cpp', 'lower_vec_index_to_swizzle.cpp', diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index b2c378dd85..302cfbc566 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -708,7 +708,7 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration { GLboolean progress = GL_FALSE; - progress = do_sub_to_add_neg(ir) || progress; + progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress; if (linked) { progress = do_function_inlining(ir) || progress; diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index 1f8da16bcb..fa497a4555 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -28,6 +28,13 @@ * 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 LOG_TO_LOG2 0x08 +#define MOD_TO_FRACT 0x10 + bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations); bool do_algebraic(exec_list *instructions); @@ -40,8 +47,6 @@ 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_lower_texture_projection(exec_list *instructions); @@ -56,6 +61,7 @@ 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_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); diff --git a/src/glsl/lower_div_to_mul_rcp.cpp b/src/glsl/lower_div_to_mul_rcp.cpp deleted file mode 100644 index db9d6854cd..0000000000 --- a/src/glsl/lower_div_to_mul_rcp.cpp +++ /dev/null @@ -1,114 +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 lower_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->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->made_progress = true; - - return visit_continue; -} diff --git a/src/glsl/lower_explog_to_explog2.cpp b/src/glsl/lower_explog_to_explog2.cpp deleted file mode 100644 index 8ad0262544..0000000000 --- a/src/glsl/lower_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 lower_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/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp new file mode 100644 index 0000000000..d460ba1a97 --- /dev/null +++ b/src/glsl/lower_instructions.cpp @@ -0,0 +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. + */ + +/** + * \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 + * - 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. + * + * 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_E */ +#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 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(log2f(M_E)); + + 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::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(1.0f / log2f(M_E)); + 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; + + default: + return visit_continue; + } + + return visit_continue; +} diff --git a/src/glsl/lower_mod_to_fract.cpp b/src/glsl/lower_mod_to_fract.cpp deleted file mode 100644 index ff907ae97c..0000000000 --- a/src/glsl/lower_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 lower_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/src/glsl/lower_sub_to_add_neg.cpp b/src/glsl/lower_sub_to_add_neg.cpp deleted file mode 100644 index 9e4019709b..0000000000 --- a/src/glsl/lower_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 lower_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/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index e1cb94452d..610b7e3c3e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -101,10 +101,12 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) clone_ir_list(mem_ctx, shader->ir, shader->base.ir); do_mat_op_to_vec(shader->ir); - do_mod_to_fract(shader->ir); - do_div_to_mul_rcp(shader->ir); - do_sub_to_add_neg(shader->ir); - do_explog_to_explog2(shader->ir); + lower_instructions(shader->ir, + MOD_TO_FRACT | + DIV_TO_MUL_RCP | + SUB_TO_ADD_NEG | + EXP_TO_EXP2 | + LOG_TO_LOG2); do_lower_texture_projection(shader->ir); brw_do_cubemap_normalize(shader->ir); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 1cb8183042..c7a8594f72 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2798,9 +2798,8 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) /* Lowering */ do_mat_op_to_vec(ir); - do_mod_to_fract(ir); - do_div_to_mul_rcp(ir); - do_explog_to_explog2(ir); + lower_instructions(ir, MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 + | LOG_TO_LOG2); progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; -- cgit v1.2.3 From 7aebe181f3eea51ae76f7abe200df239c7dd948a Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Fri, 19 Nov 2010 17:22:23 -0800 Subject: glsl: Add lower_vector.cpp to SConscript. --- src/glsl/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/glsl/SConscript') diff --git a/src/glsl/SConscript b/src/glsl/SConscript index f708635e53..fd22f66863 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -57,6 +57,7 @@ sources = [ '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', -- cgit v1.2.3 From 9a1d063c6d679c2155f5eb80f1cb94368d36bf2c Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 24 Nov 2010 22:02:26 -0800 Subject: glsl: Add an optimization pass to simplify discards. NOTE: This is a candidate for the 7.9 branch. --- src/glsl/Makefile | 1 + src/glsl/SConscript | 1 + src/glsl/glsl_parser_extras.cpp | 1 + src/glsl/ir_optimization.h | 1 + src/glsl/opt_discard_simplification.cpp | 180 ++++++++++++++++++++++++++++++++ 5 files changed, 184 insertions(+) create mode 100644 src/glsl/opt_discard_simplification.cpp (limited to 'src/glsl/SConscript') diff --git a/src/glsl/Makefile b/src/glsl/Makefile index f5aadc347b..83ecb7f9c0 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -70,6 +70,7 @@ CXX_SOURCES = \ 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 \ diff --git a/src/glsl/SConscript b/src/glsl/SConscript index fd22f66863..16f02e94b1 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -66,6 +66,7 @@ sources = [ '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', diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 302cfbc566..8dbe66927d 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -716,6 +716,7 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration } 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; diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index fa497a4555..05c1becc5e 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -51,6 +51,7 @@ 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 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); diff --git a/src/glsl/opt_discard_simplification.cpp b/src/glsl/opt_discard_simplification.cpp new file mode 100644 index 0000000000..0e577c478a --- /dev/null +++ b/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; +} -- cgit v1.2.3 From 940df10100d740ef27fa39026fd51c3199ed3d62 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 25 Nov 2010 01:09:26 -0800 Subject: glsl: Add a lowering pass to move discards out of if-statements. This should allow lower_if_to_cond_assign to work in the presence of discards, fixing bug #31690 and likely #31983. NOTE: This is a candidate for the 7.9 branch. --- src/glsl/Makefile | 1 + src/glsl/SConscript | 1 + src/glsl/ir_optimization.h | 1 + src/glsl/lower_discard.cpp | 198 ++++++++++++++++++++++++++++++++++++++++ src/mesa/program/ir_to_mesa.cpp | 4 +- 5 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/glsl/lower_discard.cpp (limited to 'src/glsl/SConscript') diff --git a/src/glsl/Makefile b/src/glsl/Makefile index 83ecb7f9c0..2674c6ec48 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -52,6 +52,7 @@ CXX_SOURCES = \ loop_analysis.cpp \ loop_controls.cpp \ loop_unroll.cpp \ + lower_discard.cpp \ lower_if_to_cond_assign.cpp \ lower_instructions.cpp \ lower_jumps.cpp \ diff --git a/src/glsl/SConscript b/src/glsl/SConscript index 16f02e94b1..b5b1728bee 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -49,6 +49,7 @@ sources = [ 'loop_analysis.cpp', 'loop_controls.cpp', 'loop_unroll.cpp', + 'lower_discard.cpp', 'lower_if_to_cond_assign.cpp', 'lower_instructions.cpp', 'lower_jumps.cpp', diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index 05c1becc5e..1048ff982e 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -62,6 +62,7 @@ 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, diff --git a/src/glsl/lower_discard.cpp b/src/glsl/lower_discard.cpp new file mode 100644 index 0000000000..b95313df8c --- /dev/null +++ b/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/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 5dd602fd83..d9d86b6c29 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2858,8 +2858,10 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) progress = lower_quadop_vector(ir, true) || progress; - if (options->EmitNoIfs) + if (options->EmitNoIfs) { + progress = lower_discard(ir) || progress; progress = do_if_to_cond_assign(ir) || progress; + } if (options->EmitNoNoise) progress = lower_noise(ir) || progress; -- cgit v1.2.3 From bb10e081c8ddc452bca44ba583f239219a5b9372 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 13 Dec 2010 08:41:08 -0700 Subject: glsl: new glsl_strtod() wrapper to fix decimal point interpretation We always want to use '.' as the decimal point. See http://bugs.freedesktop.org/show_bug.cgi?id=24531 NOTE: this is a candidate for the 7.10 branch. --- src/glsl/Makefile | 1 + src/glsl/SConscript | 1 + src/glsl/glsl_lexer.cpp | 443 +++++++++++++++++++++++----------------------- src/glsl/glsl_lexer.lpp | 11 +- src/glsl/s_expression.cpp | 2 +- src/glsl/s_expression.h | 1 + src/glsl/strtod.c | 56 ++++++ src/glsl/strtod.h | 43 +++++ 8 files changed, 329 insertions(+), 229 deletions(-) create mode 100644 src/glsl/strtod.c create mode 100644 src/glsl/strtod.h (limited to 'src/glsl/SConscript') diff --git a/src/glsl/Makefile b/src/glsl/Makefile index 2674c6ec48..86a577e0ae 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -16,6 +16,7 @@ GLCPP_SOURCES = \ glcpp/glcpp.c C_SOURCES = \ + strtod.c \ $(LIBGLCPP_SOURCES) CXX_SOURCES = \ diff --git a/src/glsl/SConscript b/src/glsl/SConscript index b5b1728bee..f179721d52 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -76,6 +76,7 @@ sources = [ 'opt_swizzle_swizzle.cpp', 'opt_tree_grafting.cpp', 's_expression.cpp', + 'strtod.c', ] glsl = env.ConvenienceLibrary( diff --git a/src/glsl/glsl_lexer.cpp b/src/glsl/glsl_lexer.cpp index e3d0a3cfc9..39c119001f 100644 --- a/src/glsl/glsl_lexer.cpp +++ b/src/glsl/glsl_lexer.cpp @@ -1001,6 +1001,7 @@ static yyconst flex_int16_t yy_chk[1255] = * DEALINGS IN THE SOFTWARE. */ #include +#include "strtod.h" #include "ast.h" #include "glsl_parser_extras.h" #include "glsl_parser.h" @@ -1054,7 +1055,7 @@ static yyconst flex_int16_t yy_chk[1255] = */ #define ES yyextra->es_shader -#line 1058 "glsl_lexer.cpp" +#line 1059 "glsl_lexer.cpp" #define INITIAL 0 #define PP 1 @@ -1141,10 +1142,6 @@ int _mesa_glsl_get_lineno (yyscan_t yyscanner ); void _mesa_glsl_set_lineno (int line_number ,yyscan_t yyscanner ); -int _mesa_glsl_get_column (yyscan_t yyscanner ); - -void _mesa_glsl_set_column (int column_no ,yyscan_t yyscanner ); - YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner ); void _mesa_glsl_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); @@ -1292,10 +1289,10 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 94 "glsl_lexer.lpp" +#line 95 "glsl_lexer.lpp" -#line 1299 "glsl_lexer.cpp" +#line 1296 "glsl_lexer.cpp" yylval = yylval_param; @@ -1381,7 +1378,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 96 "glsl_lexer.lpp" +#line 97 "glsl_lexer.lpp" ; YY_BREAK /* Preprocessor tokens. */ @@ -1390,17 +1387,17 @@ case 2: yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP -#line 99 "glsl_lexer.lpp" +#line 100 "glsl_lexer.lpp" ; YY_BREAK case 3: YY_RULE_SETUP -#line 100 "glsl_lexer.lpp" +#line 101 "glsl_lexer.lpp" { BEGIN PP; return VERSION; } YY_BREAK case 4: YY_RULE_SETUP -#line 101 "glsl_lexer.lpp" +#line 102 "glsl_lexer.lpp" { BEGIN PP; return EXTENSION; } YY_BREAK case 5: @@ -1408,7 +1405,7 @@ case 5: yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP -#line 102 "glsl_lexer.lpp" +#line 103 "glsl_lexer.lpp" { /* Eat characters until the first digit is * encountered @@ -1430,7 +1427,7 @@ case 6: yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP -#line 117 "glsl_lexer.lpp" +#line 118 "glsl_lexer.lpp" { /* Eat characters until the first digit is * encountered @@ -1448,7 +1445,7 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 131 "glsl_lexer.lpp" +#line 132 "glsl_lexer.lpp" { BEGIN PP; return PRAGMA_DEBUG_ON; @@ -1456,7 +1453,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 135 "glsl_lexer.lpp" +#line 136 "glsl_lexer.lpp" { BEGIN PP; return PRAGMA_DEBUG_OFF; @@ -1464,7 +1461,7 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 139 "glsl_lexer.lpp" +#line 140 "glsl_lexer.lpp" { BEGIN PP; return PRAGMA_OPTIMIZE_ON; @@ -1472,7 +1469,7 @@ YY_RULE_SETUP YY_BREAK case 10: YY_RULE_SETUP -#line 143 "glsl_lexer.lpp" +#line 144 "glsl_lexer.lpp" { BEGIN PP; return PRAGMA_OPTIMIZE_OFF; @@ -1480,38 +1477,38 @@ YY_RULE_SETUP YY_BREAK case 11: YY_RULE_SETUP -#line 147 "glsl_lexer.lpp" +#line 148 "glsl_lexer.lpp" { BEGIN PRAGMA; } YY_BREAK case 12: /* rule 12 can match eol */ YY_RULE_SETUP -#line 149 "glsl_lexer.lpp" +#line 150 "glsl_lexer.lpp" { BEGIN 0; yylineno++; yycolumn = 0; } YY_BREAK case 13: YY_RULE_SETUP -#line 150 "glsl_lexer.lpp" +#line 151 "glsl_lexer.lpp" { } YY_BREAK case 14: YY_RULE_SETUP -#line 152 "glsl_lexer.lpp" +#line 153 "glsl_lexer.lpp" { } YY_BREAK case 15: YY_RULE_SETUP -#line 153 "glsl_lexer.lpp" +#line 154 "glsl_lexer.lpp" { } YY_BREAK case 16: YY_RULE_SETUP -#line 154 "glsl_lexer.lpp" +#line 155 "glsl_lexer.lpp" return COLON; YY_BREAK case 17: YY_RULE_SETUP -#line 155 "glsl_lexer.lpp" +#line 156 "glsl_lexer.lpp" { yylval->identifier = strdup(yytext); return IDENTIFIER; @@ -1519,7 +1516,7 @@ YY_RULE_SETUP YY_BREAK case 18: YY_RULE_SETUP -#line 159 "glsl_lexer.lpp" +#line 160 "glsl_lexer.lpp" { yylval->n = strtol(yytext, NULL, 10); return INTCONSTANT; @@ -1528,388 +1525,388 @@ YY_RULE_SETUP case 19: /* rule 19 can match eol */ YY_RULE_SETUP -#line 163 "glsl_lexer.lpp" +#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 165 "glsl_lexer.lpp" +#line 166 "glsl_lexer.lpp" { yylineno++; yycolumn = 0; } YY_BREAK case 21: YY_RULE_SETUP -#line 167 "glsl_lexer.lpp" +#line 168 "glsl_lexer.lpp" return ATTRIBUTE; YY_BREAK case 22: YY_RULE_SETUP -#line 168 "glsl_lexer.lpp" +#line 169 "glsl_lexer.lpp" return CONST_TOK; YY_BREAK case 23: YY_RULE_SETUP -#line 169 "glsl_lexer.lpp" +#line 170 "glsl_lexer.lpp" return BOOL_TOK; YY_BREAK case 24: YY_RULE_SETUP -#line 170 "glsl_lexer.lpp" +#line 171 "glsl_lexer.lpp" return FLOAT_TOK; YY_BREAK case 25: YY_RULE_SETUP -#line 171 "glsl_lexer.lpp" +#line 172 "glsl_lexer.lpp" return INT_TOK; YY_BREAK case 26: YY_RULE_SETUP -#line 172 "glsl_lexer.lpp" +#line 173 "glsl_lexer.lpp" KEYWORD(130, 130, UINT_TOK); YY_BREAK case 27: YY_RULE_SETUP -#line 174 "glsl_lexer.lpp" +#line 175 "glsl_lexer.lpp" return BREAK; YY_BREAK case 28: YY_RULE_SETUP -#line 175 "glsl_lexer.lpp" +#line 176 "glsl_lexer.lpp" return CONTINUE; YY_BREAK case 29: YY_RULE_SETUP -#line 176 "glsl_lexer.lpp" +#line 177 "glsl_lexer.lpp" return DO; YY_BREAK case 30: YY_RULE_SETUP -#line 177 "glsl_lexer.lpp" +#line 178 "glsl_lexer.lpp" return WHILE; YY_BREAK case 31: YY_RULE_SETUP -#line 178 "glsl_lexer.lpp" +#line 179 "glsl_lexer.lpp" return ELSE; YY_BREAK case 32: YY_RULE_SETUP -#line 179 "glsl_lexer.lpp" +#line 180 "glsl_lexer.lpp" return FOR; YY_BREAK case 33: YY_RULE_SETUP -#line 180 "glsl_lexer.lpp" +#line 181 "glsl_lexer.lpp" return IF; YY_BREAK case 34: YY_RULE_SETUP -#line 181 "glsl_lexer.lpp" +#line 182 "glsl_lexer.lpp" return DISCARD; YY_BREAK case 35: YY_RULE_SETUP -#line 182 "glsl_lexer.lpp" +#line 183 "glsl_lexer.lpp" return RETURN; YY_BREAK case 36: YY_RULE_SETUP -#line 184 "glsl_lexer.lpp" +#line 185 "glsl_lexer.lpp" return BVEC2; YY_BREAK case 37: YY_RULE_SETUP -#line 185 "glsl_lexer.lpp" +#line 186 "glsl_lexer.lpp" return BVEC3; YY_BREAK case 38: YY_RULE_SETUP -#line 186 "glsl_lexer.lpp" +#line 187 "glsl_lexer.lpp" return BVEC4; YY_BREAK case 39: YY_RULE_SETUP -#line 187 "glsl_lexer.lpp" +#line 188 "glsl_lexer.lpp" return IVEC2; YY_BREAK case 40: YY_RULE_SETUP -#line 188 "glsl_lexer.lpp" +#line 189 "glsl_lexer.lpp" return IVEC3; YY_BREAK case 41: YY_RULE_SETUP -#line 189 "glsl_lexer.lpp" +#line 190 "glsl_lexer.lpp" return IVEC4; YY_BREAK case 42: YY_RULE_SETUP -#line 190 "glsl_lexer.lpp" +#line 191 "glsl_lexer.lpp" KEYWORD(130, 130, UVEC2); YY_BREAK case 43: YY_RULE_SETUP -#line 191 "glsl_lexer.lpp" +#line 192 "glsl_lexer.lpp" KEYWORD(130, 130, UVEC3); YY_BREAK case 44: YY_RULE_SETUP -#line 192 "glsl_lexer.lpp" +#line 193 "glsl_lexer.lpp" KEYWORD(130, 130, UVEC4); YY_BREAK case 45: YY_RULE_SETUP -#line 193 "glsl_lexer.lpp" +#line 194 "glsl_lexer.lpp" return VEC2; YY_BREAK case 46: YY_RULE_SETUP -#line 194 "glsl_lexer.lpp" +#line 195 "glsl_lexer.lpp" return VEC3; YY_BREAK case 47: YY_RULE_SETUP -#line 195 "glsl_lexer.lpp" +#line 196 "glsl_lexer.lpp" return VEC4; YY_BREAK case 48: YY_RULE_SETUP -#line 196 "glsl_lexer.lpp" +#line 197 "glsl_lexer.lpp" return MAT2X2; YY_BREAK case 49: YY_RULE_SETUP -#line 197 "glsl_lexer.lpp" +#line 198 "glsl_lexer.lpp" return MAT3X3; YY_BREAK case 50: YY_RULE_SETUP -#line 198 "glsl_lexer.lpp" +#line 199 "glsl_lexer.lpp" return MAT4X4; YY_BREAK case 51: YY_RULE_SETUP -#line 199 "glsl_lexer.lpp" +#line 200 "glsl_lexer.lpp" KEYWORD(120, 120, MAT2X2); YY_BREAK case 52: YY_RULE_SETUP -#line 200 "glsl_lexer.lpp" +#line 201 "glsl_lexer.lpp" KEYWORD(120, 120, MAT2X3); YY_BREAK case 53: YY_RULE_SETUP -#line 201 "glsl_lexer.lpp" +#line 202 "glsl_lexer.lpp" KEYWORD(120, 120, MAT2X4); YY_BREAK case 54: YY_RULE_SETUP -#line 202 "glsl_lexer.lpp" +#line 203 "glsl_lexer.lpp" KEYWORD(120, 120, MAT3X2); YY_BREAK case 55: YY_RULE_SETUP -#line 203 "glsl_lexer.lpp" +#line 204 "glsl_lexer.lpp" KEYWORD(120, 120, MAT3X3); YY_BREAK case 56: YY_RULE_SETUP -#line 204 "glsl_lexer.lpp" +#line 205 "glsl_lexer.lpp" KEYWORD(120, 120, MAT3X4); YY_BREAK case 57: YY_RULE_SETUP -#line 205 "glsl_lexer.lpp" +#line 206 "glsl_lexer.lpp" KEYWORD(120, 120, MAT4X2); YY_BREAK case 58: YY_RULE_SETUP -#line 206 "glsl_lexer.lpp" +#line 207 "glsl_lexer.lpp" KEYWORD(120, 120, MAT4X3); YY_BREAK case 59: YY_RULE_SETUP -#line 207 "glsl_lexer.lpp" +#line 208 "glsl_lexer.lpp" KEYWORD(120, 120, MAT4X4); YY_BREAK case 60: YY_RULE_SETUP -#line 209 "glsl_lexer.lpp" +#line 210 "glsl_lexer.lpp" return IN_TOK; YY_BREAK case 61: YY_RULE_SETUP -#line 210 "glsl_lexer.lpp" +#line 211 "glsl_lexer.lpp" return OUT_TOK; YY_BREAK case 62: YY_RULE_SETUP -#line 211 "glsl_lexer.lpp" +#line 212 "glsl_lexer.lpp" return INOUT_TOK; YY_BREAK case 63: YY_RULE_SETUP -#line 212 "glsl_lexer.lpp" +#line 213 "glsl_lexer.lpp" return UNIFORM; YY_BREAK case 64: YY_RULE_SETUP -#line 213 "glsl_lexer.lpp" +#line 214 "glsl_lexer.lpp" return VARYING; YY_BREAK case 65: YY_RULE_SETUP -#line 214 "glsl_lexer.lpp" +#line 215 "glsl_lexer.lpp" KEYWORD(120, 120, CENTROID); YY_BREAK case 66: YY_RULE_SETUP -#line 215 "glsl_lexer.lpp" +#line 216 "glsl_lexer.lpp" KEYWORD(120 || ES, 120 || ES, INVARIANT); YY_BREAK case 67: YY_RULE_SETUP -#line 216 "glsl_lexer.lpp" +#line 217 "glsl_lexer.lpp" KEYWORD(130 || ES, 130, FLAT); YY_BREAK case 68: YY_RULE_SETUP -#line 217 "glsl_lexer.lpp" +#line 218 "glsl_lexer.lpp" KEYWORD(130, 130, SMOOTH); YY_BREAK case 69: YY_RULE_SETUP -#line 218 "glsl_lexer.lpp" +#line 219 "glsl_lexer.lpp" KEYWORD(130, 130, NOPERSPECTIVE); YY_BREAK case 70: YY_RULE_SETUP -#line 220 "glsl_lexer.lpp" +#line 221 "glsl_lexer.lpp" return SAMPLER1D; YY_BREAK case 71: YY_RULE_SETUP -#line 221 "glsl_lexer.lpp" +#line 222 "glsl_lexer.lpp" return SAMPLER2D; YY_BREAK case 72: YY_RULE_SETUP -#line 222 "glsl_lexer.lpp" +#line 223 "glsl_lexer.lpp" return SAMPLER3D; YY_BREAK case 73: YY_RULE_SETUP -#line 223 "glsl_lexer.lpp" +#line 224 "glsl_lexer.lpp" return SAMPLERCUBE; YY_BREAK case 74: YY_RULE_SETUP -#line 224 "glsl_lexer.lpp" +#line 225 "glsl_lexer.lpp" KEYWORD(130, 130, SAMPLER1DARRAY); YY_BREAK case 75: YY_RULE_SETUP -#line 225 "glsl_lexer.lpp" +#line 226 "glsl_lexer.lpp" KEYWORD(130, 130, SAMPLER2DARRAY); YY_BREAK case 76: YY_RULE_SETUP -#line 226 "glsl_lexer.lpp" +#line 227 "glsl_lexer.lpp" return SAMPLER1DSHADOW; YY_BREAK case 77: YY_RULE_SETUP -#line 227 "glsl_lexer.lpp" +#line 228 "glsl_lexer.lpp" return SAMPLER2DSHADOW; YY_BREAK case 78: YY_RULE_SETUP -#line 228 "glsl_lexer.lpp" +#line 229 "glsl_lexer.lpp" KEYWORD(130, 130, SAMPLERCUBESHADOW); YY_BREAK case 79: YY_RULE_SETUP -#line 229 "glsl_lexer.lpp" +#line 230 "glsl_lexer.lpp" KEYWORD(130, 130, SAMPLER1DARRAYSHADOW); YY_BREAK case 80: YY_RULE_SETUP -#line 230 "glsl_lexer.lpp" +#line 231 "glsl_lexer.lpp" KEYWORD(130, 130, SAMPLER2DARRAYSHADOW); YY_BREAK case 81: YY_RULE_SETUP -#line 231 "glsl_lexer.lpp" +#line 232 "glsl_lexer.lpp" KEYWORD(130, 130, ISAMPLER1D); YY_BREAK case 82: YY_RULE_SETUP -#line 232 "glsl_lexer.lpp" +#line 233 "glsl_lexer.lpp" KEYWORD(130, 130, ISAMPLER2D); YY_BREAK case 83: YY_RULE_SETUP -#line 233 "glsl_lexer.lpp" +#line 234 "glsl_lexer.lpp" KEYWORD(130, 130, ISAMPLER3D); YY_BREAK case 84: YY_RULE_SETUP -#line 234 "glsl_lexer.lpp" +#line 235 "glsl_lexer.lpp" KEYWORD(130, 130, ISAMPLERCUBE); YY_BREAK case 85: YY_RULE_SETUP -#line 235 "glsl_lexer.lpp" +#line 236 "glsl_lexer.lpp" KEYWORD(130, 130, ISAMPLER1DARRAY); YY_BREAK case 86: YY_RULE_SETUP -#line 236 "glsl_lexer.lpp" +#line 237 "glsl_lexer.lpp" KEYWORD(130, 130, ISAMPLER2DARRAY); YY_BREAK case 87: YY_RULE_SETUP -#line 237 "glsl_lexer.lpp" +#line 238 "glsl_lexer.lpp" KEYWORD(130, 130, USAMPLER1D); YY_BREAK case 88: YY_RULE_SETUP -#line 238 "glsl_lexer.lpp" +#line 239 "glsl_lexer.lpp" KEYWORD(130, 130, USAMPLER2D); YY_BREAK case 89: YY_RULE_SETUP -#line 239 "glsl_lexer.lpp" +#line 240 "glsl_lexer.lpp" KEYWORD(130, 130, USAMPLER3D); YY_BREAK case 90: YY_RULE_SETUP -#line 240 "glsl_lexer.lpp" +#line 241 "glsl_lexer.lpp" KEYWORD(130, 130, USAMPLERCUBE); YY_BREAK case 91: YY_RULE_SETUP -#line 241 "glsl_lexer.lpp" +#line 242 "glsl_lexer.lpp" KEYWORD(130, 130, USAMPLER1DARRAY); YY_BREAK case 92: YY_RULE_SETUP -#line 242 "glsl_lexer.lpp" +#line 243 "glsl_lexer.lpp" KEYWORD(130, 130, USAMPLER2DARRAY); YY_BREAK case 93: YY_RULE_SETUP -#line 245 "glsl_lexer.lpp" +#line 246 "glsl_lexer.lpp" return STRUCT; YY_BREAK case 94: YY_RULE_SETUP -#line 246 "glsl_lexer.lpp" +#line 247 "glsl_lexer.lpp" return VOID_TOK; YY_BREAK case 95: YY_RULE_SETUP -#line 248 "glsl_lexer.lpp" +#line 249 "glsl_lexer.lpp" { if ((yyextra->language_version >= 140) || yyextra->ARB_explicit_attrib_location_enable @@ -1923,112 +1920,112 @@ YY_RULE_SETUP YY_BREAK case 96: YY_RULE_SETUP -#line 259 "glsl_lexer.lpp" +#line 260 "glsl_lexer.lpp" return INC_OP; YY_BREAK case 97: YY_RULE_SETUP -#line 260 "glsl_lexer.lpp" +#line 261 "glsl_lexer.lpp" return DEC_OP; YY_BREAK case 98: YY_RULE_SETUP -#line 261 "glsl_lexer.lpp" +#line 262 "glsl_lexer.lpp" return LE_OP; YY_BREAK case 99: YY_RULE_SETUP -#line 262 "glsl_lexer.lpp" +#line 263 "glsl_lexer.lpp" return GE_OP; YY_BREAK case 100: YY_RULE_SETUP -#line 263 "glsl_lexer.lpp" +#line 264 "glsl_lexer.lpp" return EQ_OP; YY_BREAK case 101: YY_RULE_SETUP -#line 264 "glsl_lexer.lpp" +#line 265 "glsl_lexer.lpp" return NE_OP; YY_BREAK case 102: YY_RULE_SETUP -#line 265 "glsl_lexer.lpp" +#line 266 "glsl_lexer.lpp" return AND_OP; YY_BREAK case 103: YY_RULE_SETUP -#line 266 "glsl_lexer.lpp" +#line 267 "glsl_lexer.lpp" return OR_OP; YY_BREAK case 104: YY_RULE_SETUP -#line 267 "glsl_lexer.lpp" +#line 268 "glsl_lexer.lpp" return XOR_OP; YY_BREAK case 105: YY_RULE_SETUP -#line 268 "glsl_lexer.lpp" +#line 269 "glsl_lexer.lpp" return LEFT_OP; YY_BREAK case 106: YY_RULE_SETUP -#line 269 "glsl_lexer.lpp" +#line 270 "glsl_lexer.lpp" return RIGHT_OP; YY_BREAK case 107: YY_RULE_SETUP -#line 271 "glsl_lexer.lpp" +#line 272 "glsl_lexer.lpp" return MUL_ASSIGN; YY_BREAK case 108: YY_RULE_SETUP -#line 272 "glsl_lexer.lpp" +#line 273 "glsl_lexer.lpp" return DIV_ASSIGN; YY_BREAK case 109: YY_RULE_SETUP -#line 273 "glsl_lexer.lpp" +#line 274 "glsl_lexer.lpp" return ADD_ASSIGN; YY_BREAK case 110: YY_RULE_SETUP -#line 274 "glsl_lexer.lpp" +#line 275 "glsl_lexer.lpp" return MOD_ASSIGN; YY_BREAK case 111: YY_RULE_SETUP -#line 275 "glsl_lexer.lpp" +#line 276 "glsl_lexer.lpp" return LEFT_ASSIGN; YY_BREAK case 112: YY_RULE_SETUP -#line 276 "glsl_lexer.lpp" +#line 277 "glsl_lexer.lpp" return RIGHT_ASSIGN; YY_BREAK case 113: YY_RULE_SETUP -#line 277 "glsl_lexer.lpp" +#line 278 "glsl_lexer.lpp" return AND_ASSIGN; YY_BREAK case 114: YY_RULE_SETUP -#line 278 "glsl_lexer.lpp" +#line 279 "glsl_lexer.lpp" return XOR_ASSIGN; YY_BREAK case 115: YY_RULE_SETUP -#line 279 "glsl_lexer.lpp" +#line 280 "glsl_lexer.lpp" return OR_ASSIGN; YY_BREAK case 116: YY_RULE_SETUP -#line 280 "glsl_lexer.lpp" +#line 281 "glsl_lexer.lpp" return SUB_ASSIGN; YY_BREAK case 117: YY_RULE_SETUP -#line 282 "glsl_lexer.lpp" +#line 283 "glsl_lexer.lpp" { yylval->n = strtol(yytext, NULL, 10); return IS_UINT ? UINTCONSTANT : INTCONSTANT; @@ -2036,7 +2033,7 @@ YY_RULE_SETUP YY_BREAK case 118: YY_RULE_SETUP -#line 286 "glsl_lexer.lpp" +#line 287 "glsl_lexer.lpp" { yylval->n = strtol(yytext + 2, NULL, 16); return IS_UINT ? UINTCONSTANT : INTCONSTANT; @@ -2044,7 +2041,7 @@ YY_RULE_SETUP YY_BREAK case 119: YY_RULE_SETUP -#line 290 "glsl_lexer.lpp" +#line 291 "glsl_lexer.lpp" { yylval->n = strtol(yytext, NULL, 8); return IS_UINT ? UINTCONSTANT : INTCONSTANT; @@ -2052,47 +2049,47 @@ YY_RULE_SETUP YY_BREAK case 120: YY_RULE_SETUP -#line 295 "glsl_lexer.lpp" +#line 296 "glsl_lexer.lpp" { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } YY_BREAK case 121: YY_RULE_SETUP -#line 299 "glsl_lexer.lpp" +#line 300 "glsl_lexer.lpp" { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } YY_BREAK case 122: YY_RULE_SETUP -#line 303 "glsl_lexer.lpp" +#line 304 "glsl_lexer.lpp" { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } YY_BREAK case 123: YY_RULE_SETUP -#line 307 "glsl_lexer.lpp" +#line 308 "glsl_lexer.lpp" { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } YY_BREAK case 124: YY_RULE_SETUP -#line 311 "glsl_lexer.lpp" +#line 312 "glsl_lexer.lpp" { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } YY_BREAK case 125: YY_RULE_SETUP -#line 316 "glsl_lexer.lpp" +#line 317 "glsl_lexer.lpp" { yylval->n = 1; return BOOLCONSTANT; @@ -2100,7 +2097,7 @@ YY_RULE_SETUP YY_BREAK case 126: YY_RULE_SETUP -#line 320 "glsl_lexer.lpp" +#line 321 "glsl_lexer.lpp" { yylval->n = 0; return BOOLCONSTANT; @@ -2109,409 +2106,409 @@ YY_RULE_SETUP /* Reserved words in GLSL 1.10. */ case 127: YY_RULE_SETUP -#line 327 "glsl_lexer.lpp" +#line 328 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, ASM); YY_BREAK case 128: YY_RULE_SETUP -#line 328 "glsl_lexer.lpp" +#line 329 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, CLASS); YY_BREAK case 129: YY_RULE_SETUP -#line 329 "glsl_lexer.lpp" +#line 330 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, UNION); YY_BREAK case 130: YY_RULE_SETUP -#line 330 "glsl_lexer.lpp" +#line 331 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, ENUM); YY_BREAK case 131: YY_RULE_SETUP -#line 331 "glsl_lexer.lpp" +#line 332 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, TYPEDEF); YY_BREAK case 132: YY_RULE_SETUP -#line 332 "glsl_lexer.lpp" +#line 333 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, TEMPLATE); YY_BREAK case 133: YY_RULE_SETUP -#line 333 "glsl_lexer.lpp" +#line 334 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, THIS); YY_BREAK case 134: YY_RULE_SETUP -#line 334 "glsl_lexer.lpp" +#line 335 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, PACKED_TOK); YY_BREAK case 135: YY_RULE_SETUP -#line 335 "glsl_lexer.lpp" +#line 336 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, GOTO); YY_BREAK case 136: YY_RULE_SETUP -#line 336 "glsl_lexer.lpp" +#line 337 "glsl_lexer.lpp" KEYWORD(110 || ES, 130, SWITCH); YY_BREAK case 137: YY_RULE_SETUP -#line 337 "glsl_lexer.lpp" +#line 338 "glsl_lexer.lpp" KEYWORD(110 || ES, 130, DEFAULT); YY_BREAK case 138: YY_RULE_SETUP -#line 338 "glsl_lexer.lpp" +#line 339 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, INLINE_TOK); YY_BREAK case 139: YY_RULE_SETUP -#line 339 "glsl_lexer.lpp" +#line 340 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, NOINLINE); YY_BREAK case 140: YY_RULE_SETUP -#line 340 "glsl_lexer.lpp" +#line 341 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, VOLATILE); YY_BREAK case 141: YY_RULE_SETUP -#line 341 "glsl_lexer.lpp" +#line 342 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, PUBLIC_TOK); YY_BREAK case 142: YY_RULE_SETUP -#line 342 "glsl_lexer.lpp" +#line 343 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, STATIC); YY_BREAK case 143: YY_RULE_SETUP -#line 343 "glsl_lexer.lpp" +#line 344 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, EXTERN); YY_BREAK case 144: YY_RULE_SETUP -#line 344 "glsl_lexer.lpp" +#line 345 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, EXTERNAL); YY_BREAK case 145: YY_RULE_SETUP -#line 345 "glsl_lexer.lpp" +#line 346 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, INTERFACE); YY_BREAK case 146: YY_RULE_SETUP -#line 346 "glsl_lexer.lpp" +#line 347 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, LONG_TOK); YY_BREAK case 147: YY_RULE_SETUP -#line 347 "glsl_lexer.lpp" +#line 348 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, SHORT_TOK); YY_BREAK case 148: YY_RULE_SETUP -#line 348 "glsl_lexer.lpp" +#line 349 "glsl_lexer.lpp" KEYWORD(110 || ES, 400, DOUBLE_TOK); YY_BREAK case 149: YY_RULE_SETUP -#line 349 "glsl_lexer.lpp" +#line 350 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, HALF); YY_BREAK case 150: YY_RULE_SETUP -#line 350 "glsl_lexer.lpp" +#line 351 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, FIXED_TOK); YY_BREAK case 151: YY_RULE_SETUP -#line 351 "glsl_lexer.lpp" +#line 352 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, UNSIGNED); YY_BREAK case 152: YY_RULE_SETUP -#line 352 "glsl_lexer.lpp" +#line 353 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, INPUT_TOK); YY_BREAK case 153: YY_RULE_SETUP -#line 353 "glsl_lexer.lpp" +#line 354 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, OUTPUT); YY_BREAK case 154: YY_RULE_SETUP -#line 354 "glsl_lexer.lpp" +#line 355 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, HVEC2); YY_BREAK case 155: YY_RULE_SETUP -#line 355 "glsl_lexer.lpp" +#line 356 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, HVEC3); YY_BREAK case 156: YY_RULE_SETUP -#line 356 "glsl_lexer.lpp" +#line 357 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, HVEC4); YY_BREAK case 157: YY_RULE_SETUP -#line 357 "glsl_lexer.lpp" +#line 358 "glsl_lexer.lpp" KEYWORD(110 || ES, 400, DVEC2); YY_BREAK case 158: YY_RULE_SETUP -#line 358 "glsl_lexer.lpp" +#line 359 "glsl_lexer.lpp" KEYWORD(110 || ES, 400, DVEC3); YY_BREAK case 159: YY_RULE_SETUP -#line 359 "glsl_lexer.lpp" +#line 360 "glsl_lexer.lpp" KEYWORD(110 || ES, 400, DVEC4); YY_BREAK case 160: YY_RULE_SETUP -#line 360 "glsl_lexer.lpp" +#line 361 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, FVEC2); YY_BREAK case 161: YY_RULE_SETUP -#line 361 "glsl_lexer.lpp" +#line 362 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, FVEC3); YY_BREAK case 162: YY_RULE_SETUP -#line 362 "glsl_lexer.lpp" +#line 363 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, FVEC4); YY_BREAK case 163: YY_RULE_SETUP -#line 363 "glsl_lexer.lpp" +#line 364 "glsl_lexer.lpp" return SAMPLER2DRECT; YY_BREAK case 164: YY_RULE_SETUP -#line 364 "glsl_lexer.lpp" +#line 365 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, SAMPLER3DRECT); YY_BREAK case 165: YY_RULE_SETUP -#line 365 "glsl_lexer.lpp" +#line 366 "glsl_lexer.lpp" return SAMPLER2DRECTSHADOW; YY_BREAK case 166: YY_RULE_SETUP -#line 366 "glsl_lexer.lpp" +#line 367 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, SIZEOF); YY_BREAK case 167: YY_RULE_SETUP -#line 367 "glsl_lexer.lpp" +#line 368 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, CAST); YY_BREAK case 168: YY_RULE_SETUP -#line 368 "glsl_lexer.lpp" +#line 369 "glsl_lexer.lpp" KEYWORD(110 || ES, 999, NAMESPACE); YY_BREAK case 169: YY_RULE_SETUP -#line 369 "glsl_lexer.lpp" +#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 372 "glsl_lexer.lpp" +#line 373 "glsl_lexer.lpp" KEYWORD(120, 130 || ES, LOWP); YY_BREAK case 171: YY_RULE_SETUP -#line 373 "glsl_lexer.lpp" +#line 374 "glsl_lexer.lpp" KEYWORD(120, 130 || ES, MEDIUMP); YY_BREAK case 172: YY_RULE_SETUP -#line 374 "glsl_lexer.lpp" +#line 375 "glsl_lexer.lpp" KEYWORD(120, 130 || ES, HIGHP); YY_BREAK case 173: YY_RULE_SETUP -#line 375 "glsl_lexer.lpp" +#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 378 "glsl_lexer.lpp" +#line 379 "glsl_lexer.lpp" KEYWORD(130, 130, CASE); YY_BREAK case 175: YY_RULE_SETUP -#line 379 "glsl_lexer.lpp" +#line 380 "glsl_lexer.lpp" KEYWORD(130, 999, COMMON); YY_BREAK case 176: YY_RULE_SETUP -#line 380 "glsl_lexer.lpp" +#line 381 "glsl_lexer.lpp" KEYWORD(130, 999, PARTITION); YY_BREAK case 177: YY_RULE_SETUP -#line 381 "glsl_lexer.lpp" +#line 382 "glsl_lexer.lpp" KEYWORD(130, 999, ACTIVE); YY_BREAK case 178: YY_RULE_SETUP -#line 382 "glsl_lexer.lpp" +#line 383 "glsl_lexer.lpp" KEYWORD(130 || ES, 999, SUPERP); YY_BREAK case 179: YY_RULE_SETUP -#line 383 "glsl_lexer.lpp" +#line 384 "glsl_lexer.lpp" KEYWORD(130, 140, SAMPLERBUFFER); YY_BREAK case 180: YY_RULE_SETUP -#line 384 "glsl_lexer.lpp" +#line 385 "glsl_lexer.lpp" KEYWORD(130, 999, FILTER); YY_BREAK case 181: YY_RULE_SETUP -#line 385 "glsl_lexer.lpp" +#line 386 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE1D); YY_BREAK case 182: YY_RULE_SETUP -#line 386 "glsl_lexer.lpp" +#line 387 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE2D); YY_BREAK case 183: YY_RULE_SETUP -#line 387 "glsl_lexer.lpp" +#line 388 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE3D); YY_BREAK case 184: YY_RULE_SETUP -#line 388 "glsl_lexer.lpp" +#line 389 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGECUBE); YY_BREAK case 185: YY_RULE_SETUP -#line 389 "glsl_lexer.lpp" +#line 390 "glsl_lexer.lpp" KEYWORD(130, 999, IIMAGE1D); YY_BREAK case 186: YY_RULE_SETUP -#line 390 "glsl_lexer.lpp" +#line 391 "glsl_lexer.lpp" KEYWORD(130, 999, IIMAGE2D); YY_BREAK case 187: YY_RULE_SETUP -#line 391 "glsl_lexer.lpp" +#line 392 "glsl_lexer.lpp" KEYWORD(130, 999, IIMAGE3D); YY_BREAK case 188: YY_RULE_SETUP -#line 392 "glsl_lexer.lpp" +#line 393 "glsl_lexer.lpp" KEYWORD(130, 999, IIMAGECUBE); YY_BREAK case 189: YY_RULE_SETUP -#line 393 "glsl_lexer.lpp" +#line 394 "glsl_lexer.lpp" KEYWORD(130, 999, UIMAGE1D); YY_BREAK case 190: YY_RULE_SETUP -#line 394 "glsl_lexer.lpp" +#line 395 "glsl_lexer.lpp" KEYWORD(130, 999, UIMAGE2D); YY_BREAK case 191: YY_RULE_SETUP -#line 395 "glsl_lexer.lpp" +#line 396 "glsl_lexer.lpp" KEYWORD(130, 999, UIMAGE3D); YY_BREAK case 192: YY_RULE_SETUP -#line 396 "glsl_lexer.lpp" +#line 397 "glsl_lexer.lpp" KEYWORD(130, 999, UIMAGECUBE); YY_BREAK case 193: YY_RULE_SETUP -#line 397 "glsl_lexer.lpp" +#line 398 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE1DARRAY); YY_BREAK case 194: YY_RULE_SETUP -#line 398 "glsl_lexer.lpp" +#line 399 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE2DARRAY); YY_BREAK case 195: YY_RULE_SETUP -#line 399 "glsl_lexer.lpp" +#line 400 "glsl_lexer.lpp" KEYWORD(130, 999, IIMAGE1DARRAY); YY_BREAK case 196: YY_RULE_SETUP -#line 400 "glsl_lexer.lpp" +#line 401 "glsl_lexer.lpp" KEYWORD(130, 999, IIMAGE2DARRAY); YY_BREAK case 197: YY_RULE_SETUP -#line 401 "glsl_lexer.lpp" +#line 402 "glsl_lexer.lpp" KEYWORD(130, 999, UIMAGE1DARRAY); YY_BREAK case 198: YY_RULE_SETUP -#line 402 "glsl_lexer.lpp" +#line 403 "glsl_lexer.lpp" KEYWORD(130, 999, UIMAGE2DARRAY); YY_BREAK case 199: YY_RULE_SETUP -#line 403 "glsl_lexer.lpp" +#line 404 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE1DSHADOW); YY_BREAK case 200: YY_RULE_SETUP -#line 404 "glsl_lexer.lpp" +#line 405 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE2DSHADOW); YY_BREAK case 201: YY_RULE_SETUP -#line 405 "glsl_lexer.lpp" +#line 406 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE1DARRAYSHADOW); YY_BREAK case 202: YY_RULE_SETUP -#line 406 "glsl_lexer.lpp" +#line 407 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGE2DARRAYSHADOW); YY_BREAK case 203: YY_RULE_SETUP -#line 407 "glsl_lexer.lpp" +#line 408 "glsl_lexer.lpp" KEYWORD(130, 999, IMAGEBUFFER); YY_BREAK case 204: YY_RULE_SETUP -#line 408 "glsl_lexer.lpp" +#line 409 "glsl_lexer.lpp" KEYWORD(130, 999, IIMAGEBUFFER); YY_BREAK case 205: YY_RULE_SETUP -#line 409 "glsl_lexer.lpp" +#line 410 "glsl_lexer.lpp" KEYWORD(130, 999, UIMAGEBUFFER); YY_BREAK case 206: YY_RULE_SETUP -#line 410 "glsl_lexer.lpp" +#line 411 "glsl_lexer.lpp" KEYWORD(130, 999, ROW_MAJOR); YY_BREAK case 207: YY_RULE_SETUP -#line 412 "glsl_lexer.lpp" +#line 413 "glsl_lexer.lpp" { struct _mesa_glsl_parse_state *state = yyextra; void *ctx = state; @@ -2521,15 +2518,15 @@ YY_RULE_SETUP YY_BREAK case 208: YY_RULE_SETUP -#line 419 "glsl_lexer.lpp" +#line 420 "glsl_lexer.lpp" { return yytext[0]; } YY_BREAK case 209: YY_RULE_SETUP -#line 421 "glsl_lexer.lpp" +#line 422 "glsl_lexer.lpp" ECHO; YY_BREAK -#line 2533 "glsl_lexer.cpp" +#line 2530 "glsl_lexer.cpp" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(PP): case YY_STATE_EOF(PRAGMA): @@ -3672,7 +3669,7 @@ void _mesa_glsl_free (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 421 "glsl_lexer.lpp" +#line 422 "glsl_lexer.lpp" diff --git a/src/glsl/glsl_lexer.lpp b/src/glsl/glsl_lexer.lpp index 7a3f1a67e6..15742ac363 100644 --- a/src/glsl/glsl_lexer.lpp +++ b/src/glsl/glsl_lexer.lpp @@ -22,6 +22,7 @@ * DEALINGS IN THE SOFTWARE. */ #include +#include "strtod.h" #include "ast.h" #include "glsl_parser_extras.h" #include "glsl_parser.h" @@ -293,23 +294,23 @@ layout { } [0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } \.[0-9]+([eE][+-]?[0-9]+)?[fF]? { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } [0-9]+\.([eE][+-]?[0-9]+)?[fF]? { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } [0-9]+[eE][+-]?[0-9]+[fF]? { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } [0-9]+[fF] { - yylval->real = strtod(yytext, NULL); + yylval->real = glsl_strtod(yytext, NULL); return FLOATCONSTANT; } diff --git a/src/glsl/s_expression.cpp b/src/glsl/s_expression.cpp index 4c8829fea9..e420cd6e7e 100644 --- a/src/glsl/s_expression.cpp +++ b/src/glsl/s_expression.cpp @@ -62,7 +62,7 @@ read_atom(void *ctx, const char *& src) // Check if the atom is a number. char *float_end = NULL; - double f = strtod(src, &float_end); + double f = glsl_strtod(src, &float_end); if (float_end != src) { char *int_end = NULL; int i = strtol(src, &int_end, 10); diff --git a/src/glsl/s_expression.h b/src/glsl/s_expression.h index aa22475a1b..29d800e394 100644 --- a/src/glsl/s_expression.h +++ b/src/glsl/s_expression.h @@ -26,6 +26,7 @@ #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)) \ diff --git a/src/glsl/strtod.c b/src/glsl/strtod.c new file mode 100644 index 0000000000..ff34591488 --- /dev/null +++ b/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 + +#ifdef _GNU_SOURCE +#include +#ifdef __APPLE__ +#include +#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/src/glsl/strtod.h b/src/glsl/strtod.h new file mode 100644 index 0000000000..0cf6409d42 --- /dev/null +++ b/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 -- cgit v1.2.3