i965/vec4: don't copy ATTR into 3src instructions with complex swizzles
authorMatt Turner <mattst88@gmail.com>
Mon, 18 Jan 2016 01:30:14 +0000 (20:30 -0500)
committerMatt Turner <mattst88@gmail.com>
Fri, 5 Feb 2016 17:33:19 +0000 (09:33 -0800)
The vec4 backend, at the end, does this:

    if (inst->is_3src()) {
       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));

So make sure that we use the same conditions when trying to
copy-propagate. UNIFORMs will be converted to vstride 0 in
convert_to_hw_regs, but so will ATTRs when interleaved (as will happen
in a GS with multiple attributes). Since the vstride is not set at
copy-prop time, infer it by inspecting dispatch_mode and reject ATTRs if
they have non-scalar swizzles and are interleaved.

Fixes assertion errors in dolphin-generated geometry shaders (or
misrendering on opt builds) on Sandybridge or on IVB/HSW with
INTEL_DEBUG=nodualobj.

Co-authored-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93418
Cc: "11.0 11.1" <mesa-stable@lists.freedesktop.org>
src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp

index c6f0b0d8a2a36add1e3f62d986da97cbb092c134..6bd992882b80227a944e4fa88322efb2da0af901 100644 (file)
@@ -254,8 +254,8 @@ try_constant_propagate(const struct brw_device_info *devinfo,
 
 static bool
 try_copy_propagate(const struct brw_device_info *devinfo,
-                   vec4_instruction *inst,
-                   int arg, struct copy_entry *entry)
+                   vec4_instruction *inst, int arg,
+                   struct copy_entry *entry, int attributes_per_reg)
 {
    /* Build up the value we are propagating as if it were the source of a
     * single MOV
@@ -320,7 +320,8 @@ try_copy_propagate(const struct brw_device_info *devinfo,
    unsigned composed_swizzle = brw_compose_swizzle(inst->src[arg].swizzle,
                                                    value.swizzle);
    if (inst->is_3src() &&
-       value.file == UNIFORM &&
+       (value.file == UNIFORM ||
+        (value.file == ATTR && attributes_per_reg != 1)) &&
        !brw_is_single_value_swizzle(composed_swizzle))
       return false;
 
@@ -395,6 +396,11 @@ try_copy_propagate(const struct brw_device_info *devinfo,
 bool
 vec4_visitor::opt_copy_propagation(bool do_constant_prop)
 {
+   /* If we are in dual instanced or single mode, then attributes are going
+    * to be interleaved, so one register contains two attribute slots.
+    */
+   const int attributes_per_reg =
+      prog_data->dispatch_mode == DISPATCH_MODE_4X2_DUAL_OBJECT ? 1 : 2;
    bool progress = false;
    struct copy_entry entries[alloc.total_size];
 
@@ -465,7 +471,7 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop)
          if (do_constant_prop && try_constant_propagate(devinfo, inst, i, &entry))
             progress = true;
 
-        if (try_copy_propagate(devinfo, inst, i, &entry))
+         if (try_copy_propagate(devinfo, inst, i, &entry, attributes_per_reg))
            progress = true;
       }