summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-10-03 15:31:52 -0700
committerEric Anholt <[email protected]>2011-10-20 09:51:58 -0700
commit31874f074c2eaf2a9421c57f0798c79078d296c4 (patch)
tree41905cde73ef94eec85324c18f223d1150d1d1b9 /src/mesa/drivers
parent73b0a28ba8b3e2ab917d4c729f34ddbde52c9e88 (diff)
i965/vs: Fix comparisons with uint negation.
The condmod instruction ends up generating garbage condition codes, because apparently the comparison happens on the accumulator value (33 bits for UD), not the truncated value that would be written. Fixes vs-op-neg-* Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp9
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp22
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)