diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 23 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_copy_propagation_elements.cpp | 25 |
3 files changed, 50 insertions, 4 deletions
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 1aebca40f..cde7052b0 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2010,6 +2010,29 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else var->interpolation = INTERP_QUALIFIER_NONE; + if (var->interpolation != INTERP_QUALIFIER_NONE && + !(state->target == vertex_shader && var->mode == ir_var_out) && + !(state->target == fragment_shader && var->mode == ir_var_in)) { + const char *qual_string = NULL; + switch (var->interpolation) { + case INTERP_QUALIFIER_FLAT: + qual_string = "flat"; + break; + case INTERP_QUALIFIER_NOPERSPECTIVE: + qual_string = "noperspective"; + break; + case INTERP_QUALIFIER_SMOOTH: + qual_string = "smooth"; + break; + } + + _mesa_glsl_error(loc, state, + "interpolation qualifier `%s' can only be applied to " + "vertex shader outputs and fragment shader inputs.", + qual_string); + + } + var->pixel_center_integer = qual->flags.q.pixel_center_integer; var->origin_upper_left = qual->flags.q.origin_upper_left; if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer) diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 88c81c41b..e8472d446 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1576,9 +1576,9 @@ tfeedback_decl::assign_location(struct gl_context *ctx, } else { /* Regular variable (scalar, vector, or matrix) */ if (this->is_subscripted) { - linker_error(prog, "Transform feedback varying %s found, " - "but it's an array ([] expected).", - this->orig_name); + linker_error(prog, "Transform feedback varying %s requested, " + "but %s is not an array.", + this->orig_name, this->var_name); return false; } this->location = output_var->location; diff --git a/mesalib/src/glsl/opt_copy_propagation_elements.cpp b/mesalib/src/glsl/opt_copy_propagation_elements.cpp index a91e624cb..ebfd4fd3f 100644 --- a/mesalib/src/glsl/opt_copy_propagation_elements.cpp +++ b/mesalib/src/glsl/opt_copy_propagation_elements.cpp @@ -108,6 +108,7 @@ public: virtual ir_visitor_status visit_leave(class ir_assignment *); virtual ir_visitor_status visit_enter(class ir_call *); virtual ir_visitor_status visit_enter(class ir_if *); + virtual ir_visitor_status visit_leave(class ir_swizzle *); void handle_rvalue(ir_rvalue **rvalue); @@ -179,6 +180,15 @@ ir_copy_propagation_elements_visitor::visit_leave(ir_assignment *ir) return visit_continue; } +ir_visitor_status +ir_copy_propagation_elements_visitor::visit_leave(ir_swizzle *ir) +{ + /* Don't visit the values of swizzles since they are handled while + * visiting the swizzle itself. + */ + return visit_continue; +} + /** * Replaces dereferences of ACP RHS variables with ACP LHS variables. * @@ -451,7 +461,20 @@ ir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir) swizzle[i] = orig_swizzle[j++]; } - entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, ir->write_mask, + int write_mask = ir->write_mask; + if (lhs->var == rhs->var) { + /* If this is a copy from the variable to itself, then we need + * to be sure not to include the updated channels from this + * instruction in the set of new source channels to be + * copy-propagated from. + */ + for (int i = 0; i < 4; i++) { + if (ir->write_mask & (1 << orig_swizzle[i])) + write_mask &= ~(1 << i); + } + } + + entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, write_mask, swizzle); this->acp->push_tail(entry); } |