summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2014-08-31 11:27:40 -0700
committerMatt Turner <[email protected]>2014-09-05 10:22:06 -0700
commite8df6a6b32aae7695ce010f18588c51cb7d18978 (patch)
tree12eb645c98713922cac2f0438d633d39123cba3d
parent1ee1d8ab468cafd25cfcc513319f3f046492947f (diff)
i965/vec4: Add ability to reswizzle arbitrary swizzles.
Before commit 04895f5c we would only reswizzle dot product instructions (since they wrote the same value into all channels, and we didn't have to think about anything else). That commit extended reswizzling to cases when the swizzle was single valued -- i.e., writing the same result into all channels. But allowing reswizzling of arbitrary things is actually really easy and is even less code. (Why didn't we do this in the first place?!) total instructions in shared programs: 4266079 -> 4261000 (-0.12%) instructions in affected programs: 351933 -> 346854 (-1.44%) Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp74
1 files changed, 18 insertions, 56 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index dcfa5940f9a..3ace1bdf5f5 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -943,30 +943,10 @@ vec4_instruction::can_reswizzle(int dst_writemask,
if (dst.writemask & ~swizzle_mask)
return false;
- switch (opcode) {
- default:
- if (!brw_is_single_value_swizzle(swizzle)) {
- /* Check if there happens to be no reswizzling required. */
- for (int c = 0; c < 4; c++) {
- int bit = 1 << BRW_GET_SWZ(swizzle, c);
- /* Skip components of the swizzle not used by the dst. */
- if (!(dst_writemask & (1 << c)))
- continue;
+ if (inst->mlen > 0)
+ return false;
- /* We don't do the reswizzling yet, so just sanity check that we
- * don't have to.
- */
- if (bit != (1 << c))
- return false;
- }
- return true;
- }
- /* fallthrough */
- case BRW_OPCODE_DP4:
- case BRW_OPCODE_DP3:
- case BRW_OPCODE_DP2:
- return true;
- }
+ return true;
}
/**
@@ -982,22 +962,9 @@ vec4_instruction::reswizzle(int dst_writemask, int swizzle)
int new_writemask = 0;
int new_swizzle[4] = { 0 };
- switch (opcode) {
- default:
- if (!brw_is_single_value_swizzle(swizzle)) {
- for (int c = 0; c < 4; c++) {
- /* Skip components of the swizzle not used by the dst. */
- if (!(dst_writemask & (1 << c)))
- continue;
-
- /* We don't do the reswizzling yet, so just sanity check that we
- * don't have to.
- */
- assert((1 << BRW_GET_SWZ(swizzle, c)) == (1 << c));
- }
- break;
- }
-
+ /* Dot product instructions write a single result into all channels. */
+ if (opcode != BRW_OPCODE_DP4 && opcode != BRW_OPCODE_DPH &&
+ opcode != BRW_OPCODE_DP3 && opcode != BRW_OPCODE_DP2) {
for (int i = 0; i < 3; i++) {
if (src[i].file == BAD_FILE || src[i].file == IMM)
continue;
@@ -1009,25 +976,20 @@ vec4_instruction::reswizzle(int dst_writemask, int swizzle)
src[i].swizzle = BRW_SWIZZLE4(new_swizzle[0], new_swizzle[1],
new_swizzle[2], new_swizzle[3]);
}
+ }
- /* fallthrough */
- case BRW_OPCODE_DP4:
- case BRW_OPCODE_DP3:
- case BRW_OPCODE_DP2:
- for (int c = 0; c < 4; c++) {
- int bit = 1 << BRW_GET_SWZ(swizzle, c);
- /* Skip components of the swizzle not used by the dst. */
- if (!(dst_writemask & (1 << c)))
- continue;
- /* If we were populating this component, then populate the
- * corresponding channel of the new dst.
- */
- if (dst.writemask & bit)
- new_writemask |= (1 << c);
- }
- dst.writemask = new_writemask;
- break;
+ for (int c = 0; c < 4; c++) {
+ int bit = 1 << BRW_GET_SWZ(swizzle, c);
+ /* Skip components of the swizzle not used by the dst. */
+ if (!(dst_writemask & (1 << c)))
+ continue;
+ /* If we were populating this component, then populate the
+ * corresponding channel of the new dst.
+ */
+ if (dst.writemask & bit)
+ new_writemask |= (1 << c);
}
+ dst.writemask = new_writemask;
}
/*