i965/fs: Lower LOAD_PAYLOAD instructions of unsupported width.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 20 May 2016 06:44:23 +0000 (23:44 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Sat, 28 May 2016 06:19:22 +0000 (23:19 -0700)
Only per-channel LOAD_PAYLOAD instructions can be lowered, which
should cover everything that comes in from the front-end.

LOAD_PAYLOAD instructions used to construct actual message payloads
cannot be easily lowered because they contain headers and vectors of
variable type that aren't necessarily channel-aligned -- We shouldn't
find any of them in the program at SIMD lowering time though because
they're introduced during logical send lowering.

An alternative that may be worth considering would be to re-run the
SIMD lowering pass after LOAD_PAYLOAD lowering instead of this patch.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/mesa/drivers/dri/i965/brw_fs.cpp

index c2dd9da5a4923e497c50b091a67effe3a315447e..32abe3843a3252a897ea36b11ff9c0c5f8285393 100644 (file)
@@ -4935,6 +4935,25 @@ get_lowered_simd_width(const struct brw_device_info *devinfo,
                   2 * REG_SIZE / (inst->dst.stride * type_sz(inst->dst.type)),
                   inst->exec_size);
 
+   case SHADER_OPCODE_LOAD_PAYLOAD: {
+      const unsigned reg_count =
+         DIV_ROUND_UP(inst->dst.component_size(inst->exec_size), REG_SIZE);
+
+      if (reg_count > 2) {
+         /* Only LOAD_PAYLOAD instructions with per-channel destination region
+          * can be easily lowered (which excludes headers and heterogeneous
+          * types).
+          */
+         assert(!inst->header_size);
+         for (unsigned i = 0; i < inst->sources; i++)
+            assert(type_sz(inst->dst.type) == type_sz(inst->src[i].type) ||
+                   inst->src[i].file == BAD_FILE);
+
+         return inst->exec_size / DIV_ROUND_UP(reg_count, 2);
+      } else {
+         return inst->exec_size;
+      }
+   }
    default:
       return inst->exec_size;
    }