diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/Makefile.sources | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/glcpp/glcpp-parse.y | 3 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.h | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_types.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/ir.cpp | 5 | ||||
-rw-r--r-- | mesalib/src/glsl/ir.h | 10 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_clone.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_constant_expression.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_hv_accept.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_optimization.h | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_print_visitor.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_reader.cpp | 14 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_rvalue_visitor.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_validate.cpp | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/lower_jumps.cpp | 4 | ||||
-rw-r--r-- | mesalib/src/glsl/lower_ubo_reference.cpp | 10 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp | 103 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_tree_grafting.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/standalone_scaffolding.cpp | 1 |
21 files changed, 155 insertions, 18 deletions
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index c294aa429..b5282a604 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -80,6 +80,7 @@ LIBGLSL_FILES = \ $(GLSL_SRCDIR)/opt_dead_code.cpp \ $(GLSL_SRCDIR)/opt_dead_code_local.cpp \ $(GLSL_SRCDIR)/opt_dead_functions.cpp \ + $(GLSL_SRCDIR)/opt_flatten_nested_if_blocks.cpp \ $(GLSL_SRCDIR)/opt_function_inlining.cpp \ $(GLSL_SRCDIR)/opt_if_simplification.cpp \ $(GLSL_SRCDIR)/opt_noop_swizzle.cpp \ diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index d6afe8814..00edbbfbd 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1233,6 +1233,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_texture_multisample) add_builtin_define(parser, "GL_ARB_texture_multisample", 1); + + if (extensions->ARB_texture_query_lod) + add_builtin_define(parser, "GL_ARB_texture_query_lod", 1); } } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 56082f761..099229410 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -467,6 +467,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array), EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing), EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample), + EXT(ARB_texture_query_lod, false, false, true, true, false, ARB_texture_query_lod), }; #undef EXT @@ -1217,6 +1218,7 @@ do_common_optimization(exec_list *ir, bool linked, progress = do_structure_splitting(ir) || progress; } progress = do_if_simplification(ir) || progress; + progress = opt_flatten_nested_if_blocks(ir) || progress; progress = do_copy_propagation(ir) || progress; progress = do_copy_propagation_elements(ir) || progress; if (linked) diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index ad296f0ea..37a47cf9a 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -286,6 +286,8 @@ struct _mesa_glsl_parse_state { bool ARB_shading_language_packing_warn; bool ARB_texture_multisample_enable; bool ARB_texture_multisample_warn; + bool ARB_texture_query_lod_enable; + bool ARB_texture_query_lod_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 8b0a24805..419761a7d 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -476,6 +476,8 @@ const glsl_type *glsl_type::get_scalar_type() const return int_type; case GLSL_TYPE_FLOAT: return float_type; + case GLSL_TYPE_BOOL: + return bool_type; default: /* Handle everything else */ return type; diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 60ef8b95a..05b77da2c 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1307,7 +1307,7 @@ ir_dereference::is_lvalue() const } -static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs" }; +static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod" }; const char *ir_texture::opcode_string() { @@ -1338,6 +1338,9 @@ ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type) if (this->op == ir_txs) { assert(type->base_type == GLSL_TYPE_INT); + } else if (this->op == ir_lod) { + assert(type->vector_elements == 2); + assert(type->base_type == GLSL_TYPE_FLOAT); } else { assert(sampler->type->sampler_type == (int) type->base_type); if (sampler->type->sampler_shadow) diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index bbfec695f..0c3e39979 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -120,6 +120,7 @@ public: 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_dereference_record *as_dereference_record() { 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; } @@ -1425,7 +1426,8 @@ enum ir_texture_opcode { ir_txd, /**< Texture look-up with partial derivatvies */ ir_txf, /**< Texel fetch with explicit LOD */ ir_txf_ms, /**< Multisample texture fetch */ - ir_txs /**< Texture size */ + ir_txs, /**< Texture size */ + ir_lod /**< Texture lod query */ }; @@ -1449,6 +1451,7 @@ enum ir_texture_opcode { * (txf_ms * <type> <sampler> <coordinate> <sample_index>) * (txs <type> <sampler> <lod>) + * (lod <type> <sampler> <coordinate>) */ class ir_texture : public ir_rvalue { public: @@ -1738,6 +1741,11 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_dereference_record *as_dereference_record() + { + return this; + } + /** * Get the variable that is ultimately referenced by an r-value */ diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index 4797451d7..5b42935f8 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -243,6 +243,7 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const switch (this->op) { case ir_tex: + case ir_lod: break; case ir_txb: new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht); diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index c2d0dc46c..c09e56a3d 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -1398,7 +1398,7 @@ ir_dereference_array::constant_referenced(struct hash_table *variable_context, return; } - const glsl_type *vt = substore->type; + const glsl_type *vt = array->type; if (vt->is_array()) { store = substore->get_array_element(index); offset = 0; diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp index 5fa75011e..559b71af3 100644 --- a/mesalib/src/glsl/ir_hv_accept.cpp +++ b/mesalib/src/glsl/ir_hv_accept.cpp @@ -213,6 +213,7 @@ ir_texture::accept(ir_hierarchical_visitor *v) switch (this->op) { case ir_tex: + case ir_lod: break; case ir_txb: s = this->lod_info.bias->accept(v); diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h index 2454bbe6f..a8885d722 100644 --- a/mesalib/src/glsl/ir_optimization.h +++ b/mesalib/src/glsl/ir_optimization.h @@ -82,6 +82,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 opt_flatten_nested_if_blocks(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); diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 3bdea9bbc..597d2813f 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -278,6 +278,7 @@ void ir_print_visitor::visit(ir_texture *ir) switch (ir->op) { case ir_tex: + case ir_lod: break; case ir_txb: ir->lod_info.bias->accept(this); diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index 22ce03b0d..16fdc41b4 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -917,6 +917,8 @@ ir_reader::read_texture(s_expression *expr) s_pattern tex_pattern[] = { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow }; + s_pattern lod_pattern[] = + { "lod", s_type, s_sampler, s_coord }; s_pattern txf_pattern[] = { "txf", s_type, s_sampler, s_coord, s_offset, s_lod }; s_pattern txf_ms_pattern[] = @@ -926,7 +928,9 @@ ir_reader::read_texture(s_expression *expr) s_pattern other_pattern[] = { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod }; - if (MATCH(expr, tex_pattern)) { + if (MATCH(expr, lod_pattern)) { + op = ir_lod; + } else if (MATCH(expr, tex_pattern)) { op = ir_tex; } else if (MATCH(expr, txf_pattern)) { op = ir_txf; @@ -939,7 +943,7 @@ ir_reader::read_texture(s_expression *expr) if (op == -1) return NULL; } else { - ir_read_error(NULL, "unexpected texture pattern"); + ir_read_error(NULL, "unexpected texture pattern %s", tag->value()); return NULL; } @@ -971,7 +975,7 @@ ir_reader::read_texture(s_expression *expr) return NULL; } - if (op != ir_txf_ms) { + if (op != ir_txf_ms && op != ir_lod) { // Read texel offset - either 0 or an rvalue. s_int *si_offset = SX_AS_INT(s_offset); if (si_offset == NULL || si_offset->value() != 0) { @@ -984,7 +988,7 @@ ir_reader::read_texture(s_expression *expr) } } - if (op != ir_txf && op != ir_txf_ms && op != ir_txs) { + if (op != ir_txf && op != ir_txf_ms && op != ir_txs && op != ir_lod) { s_int *proj_as_int = SX_AS_INT(s_proj); if (proj_as_int && proj_as_int->value() == 1) { tex->projector = NULL; @@ -1054,7 +1058,7 @@ ir_reader::read_texture(s_expression *expr) break; } default: - // tex doesn't have any extra parameters. + // tex and lod don't have any extra parameters. break; }; return tex; diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp index 543c54496..3504a4dda 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.cpp +++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp @@ -57,6 +57,7 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir) switch (ir->op) { case ir_tex: + case ir_lod: break; case ir_txb: handle_rvalue(&ir->lod_info.bias); diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 24ea506dc..699c192cd 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -701,6 +701,11 @@ check_node_type(ir_instruction *ir, void *data) void validate_ir_tree(exec_list *instructions) { + /* We shouldn't have any reason to validate IR in a release build, + * and it's half composed of assert()s anyway which wouldn't do + * anything. + */ +#ifdef DEBUG ir_validate v; v.run(instructions); @@ -710,4 +715,5 @@ validate_ir_tree(exec_list *instructions) visit_tree(ir, check_node_type, NULL); } +#endif } diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 29856b080..2b30d2b65 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1067,13 +1067,11 @@ link_intrastage_shaders(void *mem_ctx, free(linking_shaders); -#ifdef DEBUG /* At this point linked should contain all of the linked IR, so * validate it to make sure nothing went wrong. */ if (linked) validate_ir_tree(linked->ir); -#endif /* Make a pass over all variable declarations to ensure that arrays with * unspecified sizes have a size specified. The size is inferred from the diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp index 92813f567..bfc8c013b 100644 --- a/mesalib/src/glsl/lower_jumps.cpp +++ b/mesalib/src/glsl/lower_jumps.cpp @@ -1002,10 +1002,12 @@ do_lower_jumps(exec_list *instructions, bool pull_out_jumps, bool lower_sub_retu v.lower_sub_return = lower_sub_return; v.lower_main_return = lower_main_return; + bool progress_ever = false; do { v.progress = false; visit_exec_list(instructions, &v); + progress_ever = v.progress || progress_ever; } while (v.progress); - return v.progress; + return progress_ever; } diff --git a/mesalib/src/glsl/lower_ubo_reference.cpp b/mesalib/src/glsl/lower_ubo_reference.cpp index 026197df7..aade203e7 100644 --- a/mesalib/src/glsl/lower_ubo_reference.cpp +++ b/mesalib/src/glsl/lower_ubo_reference.cpp @@ -356,18 +356,14 @@ lower_ubo_reference_visitor::emit_ubo_loads(ir_dereference *deref, unsigned matrix_stride = 16; for (unsigned i = 0; i < deref->type->vector_elements; i++) { - ir_rvalue *chan = new(mem_ctx) ir_constant((int)i); - ir_dereference *deref_chan = - new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL), - chan); - ir_rvalue *chan_offset = add(base_offset, new(mem_ctx) ir_constant(deref_offset + i * matrix_stride)); - base_ir->insert_before(assign(deref_chan, + base_ir->insert_before(assign(deref->clone(mem_ctx, NULL), ubo_load(glsl_type::float_type, - chan_offset))); + chan_offset), + (1U << i))); } } } diff --git a/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp b/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp new file mode 100644 index 000000000..c70210204 --- /dev/null +++ b/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp @@ -0,0 +1,103 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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_flatten_nested_if_blocks.cpp + * + * Flattens nested if blocks such as: + * + * if (x) { + * if (y) { + * ... + * } + * } + * + * into a single if block with a combined condition: + * + * if (x && y) { + * ... + * } + */ + +#include "ir.h" +#include "ir_builder.h" + +using namespace ir_builder; + +namespace { + +class nested_if_flattener : public ir_hierarchical_visitor { +public: + nested_if_flattener() + { + progress = false; + } + + ir_visitor_status visit_leave(ir_if *); + ir_visitor_status visit_enter(ir_assignment *); + + bool progress; +}; + +} /* unnamed namespace */ + +/* We only care about the top level "if" instructions, so don't + * descend into expressions. + */ +ir_visitor_status +nested_if_flattener::visit_enter(ir_assignment *ir) +{ + (void) ir; + return visit_continue_with_parent; +} + +bool +opt_flatten_nested_if_blocks(exec_list *instructions) +{ + nested_if_flattener v; + + v.run(instructions); + return v.progress; +} + + +ir_visitor_status +nested_if_flattener::visit_leave(ir_if *ir) +{ + /* Only handle a single ir_if within the then clause of an ir_if. No extra + * instructions, no else clauses, nothing. + */ + if (ir->then_instructions.is_empty() || !ir->else_instructions.is_empty()) + return visit_continue; + + ir_if *inner = ((ir_instruction *) ir->then_instructions.head)->as_if(); + if (!inner || !inner->next->is_tail_sentinel() || + !inner->else_instructions.is_empty()) + return visit_continue; + + ir->condition = logic_and(ir->condition, inner->condition); + inner->then_instructions.move_nodes_to(&ir->then_instructions); + + progress = true; + return visit_continue; +} diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp index 985540196..9aceb134d 100644 --- a/mesalib/src/glsl/opt_tree_grafting.cpp +++ b/mesalib/src/glsl/opt_tree_grafting.cpp @@ -274,6 +274,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir) switch (ir->op) { case ir_tex: + case ir_lod: break; case ir_txb: if (do_graft(&ir->lod_info.bias)) diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index b5ef768bd..0c1f52f48 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -103,6 +103,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->Extensions.OES_standard_derivatives = true; ctx->Extensions.ARB_texture_cube_map_array = true; ctx->Extensions.ARB_texture_multisample = true; + ctx->Extensions.ARB_texture_query_lod = true; ctx->Const.GLSLVersion = 120; |