i965: Use correct VertStride on align16 instructions.
authorMatt Turner <mattst88@gmail.com>
Fri, 20 Jan 2017 21:35:33 +0000 (13:35 -0800)
committerFrancisco Jerez <currojerez@riseup.net>
Fri, 14 Apr 2017 21:56:09 +0000 (14:56 -0700)
In commit c35fa7a, we changed the "width" of DF source registers to 2,
which is conceptually fine. Unfortunately a VertStride of 2 is not
allowed by align16 instructions on IVB/BYT, and the regular VertStride
of 4 works fine in any case.

See generated_tests/spec/arb_gpu_shader_fp64/execution/built-in-functions/vs-round-double.shader_test
for example:

cmp.ge.f0(8)    g18<1>DF        g1<0>.xyxyDF    -g8<2>DF        { align16 1Q };
        ERROR: In Align16 mode, only VertStride of 0 or 4 is allowed
cmp.ge.f0(8)    g19<1>DF        g1<0>.xyxyDF    -g9<2>DF        { align16 2N };
        ERROR: In Align16 mode, only VertStride of 0 or 4 is allowed

v2:
- Add spec quote (Curro).
- Change the condition to only BRW_VERTICAL_STRIDE_2 (Curro)

Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/intel/compiler/brw_eu_emit.c

index 8637310a35aeaa789be7e61c50a236044e1996ea..231d6fdaec016cdd9e158f70fc66e1d3a0919dc4 100644 (file)
@@ -511,13 +511,25 @@ brw_set_src0(struct brw_codegen *p, brw_inst *inst, struct brw_reg reg)
          brw_inst_set_src0_da16_swiz_w(devinfo, inst,
             BRW_GET_SWZ(reg.swizzle, BRW_CHANNEL_W));
 
-        /* This is an oddity of the fact we're using the same
-         * descriptions for registers in align_16 as align_1:
-         */
-        if (reg.vstride == BRW_VERTICAL_STRIDE_8)
+         if (reg.vstride == BRW_VERTICAL_STRIDE_8) {
+            /* This is an oddity of the fact we're using the same
+             * descriptions for registers in align_16 as align_1:
+             */
+            brw_inst_set_src0_vstride(devinfo, inst, BRW_VERTICAL_STRIDE_4);
+         } else if (devinfo->gen == 7 && !devinfo->is_haswell &&
+                    reg.type == BRW_REGISTER_TYPE_DF &&
+                    reg.vstride == BRW_VERTICAL_STRIDE_2) {
+            /* From SNB PRM:
+             *
+             * "For Align16 access mode, only encodings of 0000 and 0011
+             *  are allowed. Other codes are reserved."
+             *
+             * Presumably the DevSNB behavior applies to IVB as well.
+             */
             brw_inst_set_src0_vstride(devinfo, inst, BRW_VERTICAL_STRIDE_4);
-        else
+         } else {
             brw_inst_set_src0_vstride(devinfo, inst, reg.vstride);
+         }
       }
    }
 }
@@ -593,13 +605,25 @@ brw_set_src1(struct brw_codegen *p, brw_inst *inst, struct brw_reg reg)
          brw_inst_set_src1_da16_swiz_w(devinfo, inst,
             BRW_GET_SWZ(reg.swizzle, BRW_CHANNEL_W));
 
-        /* This is an oddity of the fact we're using the same
-         * descriptions for registers in align_16 as align_1:
-         */
-        if (reg.vstride == BRW_VERTICAL_STRIDE_8)
+         if (reg.vstride == BRW_VERTICAL_STRIDE_8) {
+            /* This is an oddity of the fact we're using the same
+             * descriptions for registers in align_16 as align_1:
+             */
+            brw_inst_set_src1_vstride(devinfo, inst, BRW_VERTICAL_STRIDE_4);
+         } else if (devinfo->gen == 7 && !devinfo->is_haswell &&
+                    reg.type == BRW_REGISTER_TYPE_DF &&
+                    reg.vstride == BRW_VERTICAL_STRIDE_2) {
+            /* From SNB PRM:
+             *
+             * "For Align16 access mode, only encodings of 0000 and 0011
+             *  are allowed. Other codes are reserved."
+             *
+             * Presumably the DevSNB behavior applies to IVB as well.
+             */
             brw_inst_set_src1_vstride(devinfo, inst, BRW_VERTICAL_STRIDE_4);
-        else
+         } else {
             brw_inst_set_src1_vstride(devinfo, inst, reg.vstride);
+         }
       }
    }
 }