Fix for 58dc8b7: dest regions must not use HorzStride 0 in ExecSize 1
authorKeith Packard <keithp@keithp.com>
Sat, 1 Nov 2008 21:38:19 +0000 (14:38 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 1 Nov 2008 21:38:19 +0000 (14:38 -0700)
Quoting section 11.3.10, paragraph 10.2 of the 965PRM:

10.2.  If ExecSize is 1, dst.HorzStride must not be 0. Note that this is
relaxed from rule 10.1.2. Also note that this rule for destination
horizontal stride is different from that for source as stated in
rule #7.

GM45 gets very angry when rule 10.2 is violated.

Patch 58dc8b7 (i965: support destination horiz strides in align1 access mode)
added support for additional horizontal strides in the ExecSize 1 case, but
failed to notice that mesa occasionally re-purposes a register as a
temporary destination, even though it was constructed as a repeating source
with HorzStride = 0.

While, ideally, we should probably fix the code using these register
specifications, this patch simply rewrites them to use HorzStride 1 as the
pre-58dc8b7 code did.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/mesa/drivers/dri/i965/brw_eu_emit.c

index 460521615c6e3a3f1a23a9e3809adb31c9d5ff89..58d97465d11961d25b65a53d51348caa836c1f9e 100644 (file)
@@ -64,6 +64,8 @@ static void brw_set_dest( struct brw_instruction *insn,
 
       if (insn->header.access_mode == BRW_ALIGN_1) {
         insn->bits1.da1.dest_subreg_nr = dest.subnr;
+        if (dest.hstride == BRW_HORIZONTAL_STRIDE_0)
+           dest.hstride = BRW_HORIZONTAL_STRIDE_1;
         insn->bits1.da1.dest_horiz_stride = dest.hstride;
       }
       else {
@@ -78,6 +80,8 @@ static void brw_set_dest( struct brw_instruction *insn,
        */
       if (insn->header.access_mode == BRW_ALIGN_1) {
         insn->bits1.ia1.dest_indirect_offset = dest.dw1.bits.indirect_offset;
+        if (dest.hstride == BRW_HORIZONTAL_STRIDE_0)
+           dest.hstride = BRW_HORIZONTAL_STRIDE_1;
         insn->bits1.ia1.dest_horiz_stride = dest.hstride;
       }
       else {