aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
diff options
context:
space:
mode:
authorAlejandro Piñeiro <[email protected]>2015-09-16 10:26:55 +0200
committerAlejandro Piñeiro <[email protected]>2015-09-19 00:31:25 +0200
commit06d31dceae611b7d5c11442aa9bf8178067bcb62 (patch)
treeb963874c398c38d39153dbb5bd30775ec3705005 /src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
parentf7ca52dd6d8b4b0fcdf01d8def5edf913ece6861 (diff)
i965/vec4: Change types as needed to propagate source modifiers using current instruction
SEL and MOV instructions, as long as they don't have source modifiers, are just copying bits around. So those kind of instruction could be propagated even if there are type mismatches. This is needed because NIR generates integer SEL and MOV instructions whenever it doesn't know what else to generate. This commit adds support for copy propagation using current instruction as reference. Equivalent to commit 472ef9 but for vec4. v2: include check for saturate, as Jason Ekstrand suggested v3: check that the dst.type and the src type are the same, in order to solve (among others) the following deqp regression with v2: dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uint_vertex Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp30
1 files changed, 28 insertions, 2 deletions
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 5a15eb89766..1522eeabb1c 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
@@ -249,6 +249,18 @@ try_constant_propagate(const struct brw_device_info *devinfo,
}
static bool
+can_change_source_types(vec4_instruction *inst)
+{
+ return inst->dst.type == inst->src[0].type &&
+ !inst->src[0].abs && !inst->src[0].negate && !inst->saturate &&
+ (inst->opcode == BRW_OPCODE_MOV ||
+ (inst->opcode == BRW_OPCODE_SEL &&
+ inst->dst.type == inst->src[1].type &&
+ inst->predicate != BRW_PREDICATE_NONE &&
+ !inst->src[1].abs && !inst->src[1].negate));
+}
+
+static bool
try_copy_propagate(const struct brw_device_info *devinfo,
vec4_instruction *inst,
int arg, struct copy_entry *entry)
@@ -308,7 +320,9 @@ try_copy_propagate(const struct brw_device_info *devinfo,
value.swizzle != BRW_SWIZZLE_XYZW) && !inst->can_do_source_mods(devinfo))
return false;
- if (has_source_modifiers && value.type != inst->src[arg].type)
+ if (has_source_modifiers &&
+ value.type != inst->src[arg].type &&
+ !can_change_source_types(inst))
return false;
if (has_source_modifiers &&
@@ -362,7 +376,19 @@ try_copy_propagate(const struct brw_device_info *devinfo,
}
}
- value.type = inst->src[arg].type;
+ if (has_source_modifiers &&
+ value.type != inst->src[arg].type) {
+ /* We are propagating source modifiers from a MOV with a different
+ * type. If we got here, then we can just change the source and
+ * destination types of the instruction and keep going.
+ */
+ assert(can_change_source_types(inst));
+ for (int i = 0; i < 3; i++) {
+ inst->src[i].type = value.type;
+ }
+ inst->dst.type = value.type;
+ } else
+ value.type = inst->src[arg].type;
inst->src[arg] = value;
return true;
}