aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/Makefile.sources1
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y3
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp2
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h2
-rw-r--r--mesalib/src/glsl/glsl_types.cpp2
-rw-r--r--mesalib/src/glsl/ir.cpp5
-rw-r--r--mesalib/src/glsl/ir.h10
-rw-r--r--mesalib/src/glsl/ir_clone.cpp1
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp2
-rw-r--r--mesalib/src/glsl/ir_hv_accept.cpp1
-rw-r--r--mesalib/src/glsl/ir_optimization.h1
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp1
-rw-r--r--mesalib/src/glsl/ir_reader.cpp14
-rw-r--r--mesalib/src/glsl/ir_rvalue_visitor.cpp1
-rw-r--r--mesalib/src/glsl/ir_validate.cpp6
-rw-r--r--mesalib/src/glsl/linker.cpp2
-rw-r--r--mesalib/src/glsl/lower_jumps.cpp4
-rw-r--r--mesalib/src/glsl/lower_ubo_reference.cpp10
-rw-r--r--mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp103
-rw-r--r--mesalib/src/glsl/opt_tree_grafting.cpp1
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp1
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 1765cdf16..95891b595 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -282,6 +282,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;