summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2015-02-06 14:38:20 +0200
committerFrancisco Jerez <currojerez@riseup.net>2015-02-10 19:09:25 +0200
commitaef83957e1e13ecb96df436d53373ecc4cedeb08 (patch)
treea400b93bd0d32410407db97934d4e9a86358208f
parent64fde7b31c419685aa8ef6060828e21b9a11ef51 (diff)
i965: Handle negated unsigned immediate values in constant propagation.
Negation of UD/UW sources behaves the same as for D/W sources, taking the two's complement of the source, except for bitwise logical operations on Gen8 and up which take the one's complement. Fixes crash in a GLSL shader with subtraction of two unsigned values. Reviewed-by: Matt Turner <mattst88@gmail.com>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp6
-rw-r--r--src/mesa/drivers/dri/i965/brw_shader.cpp8
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp24
3 files changed, 19 insertions, 19 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
index 60a1b8cf463..3bc4435ac92 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -453,13 +453,15 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry)
val.type = inst->src[i].type;
if (inst->src[i].abs) {
- if (!brw_abs_immediate(val.type, &val.fixed_hw_reg)) {
+ if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+ !brw_abs_immediate(val.type, &val.fixed_hw_reg)) {
continue;
}
}
if (inst->src[i].negate) {
- if (!brw_negate_immediate(val.type, &val.fixed_hw_reg)) {
+ if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+ !brw_negate_immediate(val.type, &val.fixed_hw_reg)) {
continue;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 807b81ddd1d..d6daac0c383 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -625,9 +625,11 @@ brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg)
{
switch (type) {
case BRW_REGISTER_TYPE_D:
+ case BRW_REGISTER_TYPE_UD:
reg->dw1.d = -reg->dw1.d;
return true;
case BRW_REGISTER_TYPE_W:
+ case BRW_REGISTER_TYPE_UW:
reg->dw1.d = -(int16_t)reg->dw1.ud;
return true;
case BRW_REGISTER_TYPE_F:
@@ -639,12 +641,6 @@ brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg)
case BRW_REGISTER_TYPE_UB:
case BRW_REGISTER_TYPE_B:
unreachable("no UB/B immediates");
- case BRW_REGISTER_TYPE_UD:
- case BRW_REGISTER_TYPE_UW:
- /* Presumably the negate modifier on an unsigned source is the same as
- * on a signed source but it would be nice to confirm.
- */
- assert(!"unimplemented: negate UD/UW immediate");
case BRW_REGISTER_TYPE_UV:
case BRW_REGISTER_TYPE_V:
assert(!"unimplemented: negate UV/V immediate");
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 81567d2b295..4614e07c4ec 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
@@ -96,6 +96,15 @@ swizzle_vf_imm(unsigned vf4, unsigned swizzle)
}
static bool
+is_logic_op(enum opcode opcode)
+{
+ return (opcode == BRW_OPCODE_AND ||
+ opcode == BRW_OPCODE_OR ||
+ opcode == BRW_OPCODE_XOR ||
+ opcode == BRW_OPCODE_NOT);
+}
+
+static bool
try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
int arg, struct copy_entry *entry)
{
@@ -114,13 +123,15 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
return false;
if (inst->src[arg].abs) {
- if (!brw_abs_immediate(value.type, &value.fixed_hw_reg)) {
+ if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+ !brw_abs_immediate(value.type, &value.fixed_hw_reg)) {
return false;
}
}
if (inst->src[arg].negate) {
- if (!brw_negate_immediate(value.type, &value.fixed_hw_reg)) {
+ if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+ !brw_negate_immediate(value.type, &value.fixed_hw_reg)) {
return false;
}
}
@@ -226,15 +237,6 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
}
static bool
-is_logic_op(enum opcode opcode)
-{
- return (opcode == BRW_OPCODE_AND ||
- opcode == BRW_OPCODE_OR ||
- opcode == BRW_OPCODE_XOR ||
- opcode == BRW_OPCODE_NOT);
-}
-
-static bool
try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
int arg, struct copy_entry *entry, int reg)
{