diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp | 9 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 22 |
3 files changed, 32 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 848e298e80e..a83a6b24dbc 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -510,6 +510,7 @@ public: int base_offset); bool try_emit_sat(ir_expression *ir); + void resolve_ud_negate(src_reg *reg); bool process_move_condition(ir_rvalue *ir); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp index a5f6f93879a..c3a9deee76b 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp @@ -205,6 +205,15 @@ try_copy_propagation(struct intel_context *intel, if (intel->gen >= 6 && inst->is_math()) return false; + /* We can't copy-propagate a UD negation into a condmod + * instruction, because the condmod ends up looking at the 33-bit + * signed accumulator value instead of the 32-bit value we wanted + */ + if (inst->conditional_mod && + value.negate && + value.type == BRW_REGISTER_TYPE_UD) + return false; + /* Don't report progress if this is a noop. */ if (value.equals(&inst->src[arg])) return false; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 0ea6d317e09..02ecdaf3c91 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -182,6 +182,9 @@ vec4_visitor::IF(src_reg src0, src_reg src1, uint32_t condition) vec4_instruction *inst; + resolve_ud_negate(&src0); + resolve_ud_negate(&src1); + inst = new(mem_ctx) vec4_instruction(this, BRW_OPCODE_IF, dst_null_d(), src0, src1); inst->conditional_mod = condition; @@ -209,6 +212,9 @@ vec4_visitor::CMP(dst_reg dst, src_reg src0, src_reg src1, uint32_t condition) dst.fixed_hw_reg.type = dst.type; } + resolve_ud_negate(&src0); + resolve_ud_negate(&src1); + inst = new(mem_ctx) vec4_instruction(this, BRW_OPCODE_CMP, dst, src0, src1); inst->conditional_mod = condition; @@ -643,6 +649,8 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir, uint32_t *predicate) for (unsigned int i = 0; i < expr->get_num_operands(); i++) { expr->operands[i]->accept(this); op[i] = this->result; + + resolve_ud_negate(&op[i]); } switch (expr->operation) { @@ -718,6 +726,8 @@ vec4_visitor::emit_bool_to_cond_code(ir_rvalue *ir, uint32_t *predicate) ir->accept(this); + resolve_ud_negate(&this->result); + if (intel->gen >= 6) { vec4_instruction *inst = emit(AND(dst_null_d(), this->result, src_reg(1))); @@ -2329,6 +2339,18 @@ vec4_visitor::move_uniform_array_access_to_pull_constants() split_uniform_registers(); } +void +vec4_visitor::resolve_ud_negate(src_reg *reg) +{ + if (reg->type != BRW_REGISTER_TYPE_UD || + !reg->negate) + return; + + src_reg temp = src_reg(this, glsl_type::uvec4_type); + emit(BRW_OPCODE_MOV, dst_reg(temp), *reg); + *reg = temp; +} + vec4_visitor::vec4_visitor(struct brw_vs_compile *c, struct gl_shader_program *prog, struct brw_shader *shader) |