summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2016-05-19 23:44:23 -0700
committerFrancisco Jerez <[email protected]>2016-05-27 23:19:22 -0700
commit197833caa3d684c092ee76d1e9ff3fac28576b04 (patch)
tree48c5f585c4850c496b59ee8b87a6780e7f5fce7b
parent9eea3df29f21eb7507354c3b1d85d238b671a211 (diff)
i965/fs: Lower LOAD_PAYLOAD instructions of unsupported width.
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 <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index c2dd9da5a49..32abe3843a3 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -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;
}