summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c11
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp13
2 files changed, 18 insertions, 6 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 5fb96626649..35d8039ed13 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -847,12 +847,11 @@ brw_alu2(struct brw_codegen *p, unsigned opcode,
static int
get_3src_subreg_nr(struct brw_reg reg)
{
- if (reg.vstride == BRW_VERTICAL_STRIDE_0) {
- assert(brw_is_single_value_swizzle(reg.swizzle));
- return reg.subnr / 4 + BRW_GET_SWZ(reg.swizzle, 0);
- } else {
- return reg.subnr / 4;
- }
+ /* Normally, SubRegNum is in bytes (0..31). However, 3-src instructions
+ * use 32-bit units (components 0..7). Since they only support F/D/UD
+ * types, this doesn't lose any flexibility, but uses fewer bits.
+ */
+ return reg.subnr / 4;
}
static brw_inst *
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index dd223985d1c..c6a52c5d183 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -1784,9 +1784,22 @@ vec4_visitor::convert_to_hw_regs()
case ATTR:
unreachable("not reached");
}
+
src = reg;
}
+ if (inst->is_3src()) {
+ /* 3-src instructions with scalar sources support arbitrary subnr,
+ * but don't actually use swizzles. Convert swizzle into subnr.
+ */
+ for (int i = 0; i < 3; i++) {
+ if (inst->src[i].vstride == BRW_VERTICAL_STRIDE_0) {
+ assert(brw_is_single_value_swizzle(inst->src[i].swizzle));
+ inst->src[i].subnr += 4 * BRW_GET_SWZ(inst->src[i].swizzle, 0);
+ }
+ }
+ }
+
dst_reg &dst = inst->dst;
struct brw_reg reg;