diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/Makefile.sources | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ast.h | 12 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 9 | ||||
-rw-r--r-- | mesalib/src/glsl/builtin_variables.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.yy | 20 | ||||
-rw-r--r-- | mesalib/src/glsl/ir.h | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_builder.cpp | 183 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_builder.h | 105 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_clone.cpp | 4 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_set_program_inouts.cpp | 4 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 13 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_if_simplification.cpp | 8 |
12 files changed, 359 insertions, 7 deletions
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index 15f5e1f50..5621e42b2 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -26,6 +26,7 @@ LIBGLSL_CXX_FILES := \ glsl_symbol_table.cpp \ hir_field_selection.cpp \ ir_basic_block.cpp \ + ir_builder.cpp \ ir_clone.cpp \ ir_constant_expression.cpp \ ir.cpp \ diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h index 8439ed961..b800c1108 100644 --- a/mesalib/src/glsl/ast.h +++ b/mesalib/src/glsl/ast.h @@ -367,6 +367,11 @@ struct ast_type_qualifier { * qualifier is used. */ unsigned explicit_location:1; + /** + * Flag set if GL_ARB_explicit_attrib_location "index" layout + * qualifier is used. + */ + unsigned explicit_index:1; /** \name Layout qualifiers for GL_AMD_conservative_depth */ /** \{ */ @@ -390,6 +395,13 @@ struct ast_type_qualifier { * This field is only valid if \c explicit_location is set. */ int location; + /** + * Index specified via GL_ARB_explicit_attrib_location layout + * + * \note + * This field is only valid if \c explicit_index is set. + */ + int index; /** * Return true if and only if an interpolation qualifier is present. diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index f4dfc4ce3..820c86c5e 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2092,14 +2092,21 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } else { var->location = qual->location; } + if (qual->flags.q.explicit_index) { + var->explicit_index = true; + var->index = qual->index; + } } + } else if (qual->flags.q.explicit_index) { + _mesa_glsl_error(loc, state, + "explicit index requires explicit location\n"); } /* Does the declaration use the 'layout' keyword? */ const bool uses_layout = qual->flags.q.pixel_center_integer || qual->flags.q.origin_upper_left - || qual->flags.q.explicit_location; + || qual->flags.q.explicit_location; /* no need for index since it relies on location */ /* Does the declaration use the deprecated 'attribute' or 'varying' * keywords? diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index 516a69caf..03b64c931 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -408,6 +408,7 @@ add_variable(exec_list *instructions, glsl_symbol_table *symtab, var->location = slot; var->explicit_location = (slot >= 0); + var->explicit_index = 0; /* Once the variable is created an initialized, add it to the symbol table * and add the declaration to the IR stream. diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 920213c30..5753acf3c 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -1103,8 +1103,14 @@ layout_qualifier_id_list: if ($1.flags.q.explicit_location) $$.location = $1.location; + if ($1.flags.q.explicit_index) + $$.index = $1.index; + if ($3.flags.q.explicit_location) $$.location = $3.location; + + if ($3.flags.q.explicit_index) + $$.index = $3.index; } ; @@ -1191,6 +1197,20 @@ layout_qualifier_id: YYERROR; } } + + if (strcmp("index", $1) == 0) { + got_one = true; + + $$.flags.q.explicit_index = 1; + + if ($3 >= 0) { + $$.index = $3; + } else { + _mesa_glsl_error(& @3, state, + "invalid index %d specified\n", $3); + YYERROR; + } + } } /* If the identifier didn't match any known layout identifiers, diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index b1ae6db74..d6c6a607a 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -386,6 +386,7 @@ public: * no effect). */ unsigned explicit_location:1; + unsigned explicit_index:1; /** * Does this variable have an initializer? @@ -421,6 +422,11 @@ public: int location; /** + * output index for dual source blending. + */ + int index; + + /** * Built-in state that backs this uniform * * Once set at variable creation, \c state_slots must remain invariant. diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp new file mode 100644 index 000000000..9a16c90e5 --- /dev/null +++ b/mesalib/src/glsl/ir_builder.cpp @@ -0,0 +1,183 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "ir_builder.h" +#include "program/prog_instruction.h" + +using namespace ir_builder; + +namespace ir_builder { + +void +ir_factory::emit(ir_instruction *ir) +{ + instructions->push_tail(ir); +} + +ir_variable * +ir_factory::make_temp(const glsl_type *type, const char *name) +{ + ir_variable *var; + + var = new(mem_ctx) ir_variable(type, name, ir_var_temporary); + emit(var); + + return var; +} + +ir_assignment * +assign(deref lhs, operand rhs, int writemask) +{ + void *mem_ctx = ralloc_parent(lhs.val); + + ir_assignment *assign = new(mem_ctx) ir_assignment(lhs.val, + rhs.val, + NULL, writemask); + + return assign; +} + +ir_assignment * +assign(deref lhs, operand rhs) +{ + return assign(lhs, rhs, (1 << lhs.val->type->vector_elements) - 1); +} + +ir_swizzle * +swizzle(operand a, int swizzle, int components) +{ + void *mem_ctx = ralloc_parent(a.val); + + return new(mem_ctx) ir_swizzle(a.val, + GET_SWZ(swizzle, 0), + GET_SWZ(swizzle, 1), + GET_SWZ(swizzle, 2), + GET_SWZ(swizzle, 3), + components); +} + +ir_swizzle * +swizzle_xxxx(operand a) +{ + return swizzle(a, SWIZZLE_XXXX, 4); +} + +ir_swizzle * +swizzle_yyyy(operand a) +{ + return swizzle(a, SWIZZLE_YYYY, 4); +} + +ir_swizzle * +swizzle_zzzz(operand a) +{ + return swizzle(a, SWIZZLE_ZZZZ, 4); +} + +ir_swizzle * +swizzle_wwww(operand a) +{ + return swizzle(a, SWIZZLE_WWWW, 4); +} + +ir_swizzle * +swizzle_x(operand a) +{ + return swizzle(a, SWIZZLE_XXXX, 1); +} + +ir_swizzle * +swizzle_y(operand a) +{ + return swizzle(a, SWIZZLE_YYYY, 1); +} + +ir_swizzle * +swizzle_z(operand a) +{ + return swizzle(a, SWIZZLE_ZZZZ, 1); +} + +ir_swizzle * +swizzle_w(operand a) +{ + return swizzle(a, SWIZZLE_WWWW, 1); +} + +ir_swizzle * +swizzle_xy(operand a) +{ + return swizzle(a, SWIZZLE_XYZW, 2); +} + +ir_swizzle * +swizzle_xyz(operand a) +{ + return swizzle(a, SWIZZLE_XYZW, 3); +} + +ir_swizzle * +swizzle_xyzw(operand a) +{ + return swizzle(a, SWIZZLE_XYZW, 4); +} + +ir_expression * +expr(ir_expression_operation op, operand a, operand b) +{ + void *mem_ctx = ralloc_parent(a.val); + + return new(mem_ctx) ir_expression(op, a.val, b.val); +} + +ir_expression *add(operand a, operand b) +{ + return expr(ir_binop_add, a, b); +} + +ir_expression *sub(operand a, operand b) +{ + return expr(ir_binop_sub, a, b); +} + +ir_expression *mul(operand a, operand b) +{ + return expr(ir_binop_mul, a, b); +} + +ir_expression *dot(operand a, operand b) +{ + return expr(ir_binop_dot, a, b); +} + +ir_expression * +saturate(operand a) +{ + void *mem_ctx = ralloc_parent(a.val); + + return expr(ir_binop_max, + expr(ir_binop_min, a, new(mem_ctx) ir_constant(1.0f)), + new(mem_ctx) ir_constant(0.0f)); +} + +} /* namespace ir_builder */ diff --git a/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h new file mode 100644 index 000000000..0ebcbab95 --- /dev/null +++ b/mesalib/src/glsl/ir_builder.h @@ -0,0 +1,105 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "ir.h" + +namespace ir_builder { + +/** + * This little class exists to let the helper expression generators + * take either an ir_rvalue * or an ir_variable * to be automatically + * dereferenced, while still providing compile-time type checking. + * + * You don't have to explicitly call the constructor -- C++ will see + * that you passed an ir_variable, and silently call the + * operand(ir_variable *var) constructor behind your back. + */ +class operand { +public: + operand(ir_rvalue *val) + : val(val) + { + } + + operand(ir_variable *var) + { + void *mem_ctx = ralloc_parent(var); + val = new(mem_ctx) ir_dereference_variable(var); + } + + ir_rvalue *val; +}; + +/** Automatic generator for ir_dereference_variable on assignment LHS. + * + * \sa operand + */ +class deref { +public: + deref(ir_dereference *val) + : val(val) + { + } + + deref(ir_variable *var) + { + void *mem_ctx = ralloc_parent(var); + val = new(mem_ctx) ir_dereference_variable(var); + } + + + ir_dereference *val; +}; + +class ir_factory { +public: + void emit(ir_instruction *ir); + ir_variable *make_temp(const glsl_type *type, const char *name); + + exec_list *instructions; + void *mem_ctx; +}; + +ir_assignment *assign(deref lhs, operand rhs); +ir_assignment *assign(deref lhs, operand rhs, int writemask); + +ir_expression *expr(ir_expression_operation op, operand a, operand b); +ir_expression *add(operand a, operand b); +ir_expression *sub(operand a, operand b); +ir_expression *mul(operand a, operand b); +ir_expression *dot(operand a, operand b); +ir_expression *saturate(operand a); + +ir_swizzle *swizzle_xxxx(operand a); +ir_swizzle *swizzle_yyyy(operand a); +ir_swizzle *swizzle_zzzz(operand a); +ir_swizzle *swizzle_wwww(operand a); +ir_swizzle *swizzle_x(operand a); +ir_swizzle *swizzle_y(operand a); +ir_swizzle *swizzle_z(operand a); +ir_swizzle *swizzle_w(operand a); +ir_swizzle *swizzle_xy(operand a); +ir_swizzle *swizzle_xyz(operand a); +ir_swizzle *swizzle_xyzw(operand a); + +} /* namespace ir_builder */ diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index 26b0d8f5f..5a7a71cf6 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -57,6 +57,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const var->origin_upper_left = this->origin_upper_left; var->pixel_center_integer = this->pixel_center_integer; var->explicit_location = this->explicit_location; + var->explicit_index = this->explicit_index; var->has_initializer = this->has_initializer; var->depth_layout = this->depth_layout; @@ -74,6 +75,9 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const if (this->explicit_location) var->location = this->location; + if (this->explicit_index) + var->index = this->index; + if (this->constant_value) var->constant_value = this->constant_value->clone(mem_ctx, ht); diff --git a/mesalib/src/glsl/ir_set_program_inouts.cpp b/mesalib/src/glsl/ir_set_program_inouts.cpp index 8c2bc30d6..8f3edb969 100644 --- a/mesalib/src/glsl/ir_set_program_inouts.cpp +++ b/mesalib/src/glsl/ir_set_program_inouts.cpp @@ -81,12 +81,12 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, */ for (int i = 0; i < len; i++) { - GLbitfield64 bitfield = BITFIELD64_BIT(var->location + offset + i); + GLbitfield64 bitfield = BITFIELD64_BIT(var->location + var->index + offset + i); if (var->mode == ir_var_in) { prog->InputsRead |= bitfield; if (is_fragment_shader) { gl_fragment_program *fprog = (gl_fragment_program *) prog; - fprog->InterpQualifier[var->location + offset + i] = + fprog->InterpQualifier[var->location + var->index + offset + i] = (glsl_interp_qualifier) var->interpolation; } } else if (var->mode == ir_var_system_value) { diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 49b6b8f4a..6ba297237 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1274,10 +1274,15 @@ assign_attribute_or_color_locations(gl_shader_program *prog, } } else if (target_index == MESA_SHADER_FRAGMENT) { unsigned binding; + unsigned index; if (prog->FragDataBindings->get(binding, var->name)) { assert(binding >= FRAG_RESULT_DATA0); var->location = binding; + + if (prog->FragDataIndexBindings->get(index, var->name)) { + var->index = index; + } } } @@ -1288,7 +1293,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog, */ const unsigned slots = count_attribute_slots(var->type); if (var->location != -1) { - if (var->location >= generic_base) { + if (var->location >= generic_base && var->index < 1) { /* From page 61 of the OpenGL 4.0 spec: * * "LinkProgram will fail if the attribute bindings assigned @@ -1333,8 +1338,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog, ? "vertex shader input" : "fragment shader output"; linker_error(prog, "insufficient contiguous locations " - "available for %s `%s'", string, - var->name); + "available for %s `%s' %d %d %d", string, + var->name, used_locations, use_mask, attr); return false; } @@ -2321,7 +2326,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) goto done; } - if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) { + if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, MAX2(ctx->Const.MaxDrawBuffers, ctx->Const.MaxDualSourceDrawBuffers))) { goto done; } diff --git a/mesalib/src/glsl/opt_if_simplification.cpp b/mesalib/src/glsl/opt_if_simplification.cpp index 940dd08d5..7e88208f7 100644 --- a/mesalib/src/glsl/opt_if_simplification.cpp +++ b/mesalib/src/glsl/opt_if_simplification.cpp @@ -66,6 +66,14 @@ do_if_simplification(exec_list *instructions) ir_visitor_status ir_if_simplification_visitor::visit_leave(ir_if *ir) { + /* If the if statement has nothing on either side, remove it. */ + if (ir->then_instructions.is_empty() && + ir->else_instructions.is_empty()) { + ir->remove(); + this->made_progress = true; + return visit_continue; + } + /* FINISHME: Ideally there would be a way to note that the condition results * FINISHME: in a constant before processing both of the other subtrees. * FINISHME: This can probably be done with some flags, but it would take |