summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2013-10-29 12:46:18 -0700
committerEric Anholt <[email protected]>2013-10-30 17:51:02 -0700
commit537f183fe67e0cf9f5737106d914cdabcf5d002e (patch)
tree84889ab1e52ec7098cd774f79ae6183e0913f651 /src
parent44ec2f1751ec4a9f0ba9035f2343ffe5e16e693c (diff)
i965/fs: Exit the compile if spilling would overwrite in-use MRFs.
I believe this will never happen in SIMD8 mode, but it could for SIMD16 when we fix it. v2: Fix off-by-one in my register counting comment (caught by Paul). Reviewed-by: Paul Berry <[email protected]> (v1)
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp22
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp2
3 files changed, 25 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 50a045e4b4b..fb1da4ce781 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -466,6 +466,7 @@ public:
fs_reg shader_start_time;
int grf_used;
+ bool spilled_any_registers;
const unsigned dispatch_width; /**< 8 or 16 */
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index d86027efd81..35dae843290 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -643,6 +643,28 @@ fs_visitor::spill_reg(int spill_reg)
unsigned int spill_offset = c->last_scratch;
assert(ALIGN(spill_offset, 16) == spill_offset); /* oword read/write req. */
c->last_scratch += size * REG_SIZE;
+ int spill_base_mrf = dispatch_width > 8 ? 13 : 14;
+
+ /* Spills may use MRFs 13-15 in the SIMD16 case. Our texturing is done
+ * using up to 11 MRFs starting from either m1 or m2, and fb writes can use
+ * up to m13 (gen6+ simd16: 2 header + 8 color + 2 src0alpha + 2 omask) or
+ * m15 (gen4-5 simd16: 2 header + 8 color + 1 aads + 2 src depth + 2 dst
+ * depth), starting from m1. In summary: We may not be able to spill in
+ * SIMD16 mode, because we'd stomp the FB writes.
+ */
+ if (!spilled_any_registers) {
+ bool mrf_used[BRW_MAX_MRF];
+ get_used_mrfs(mrf_used);
+
+ for (int i = spill_base_mrf; i < BRW_MAX_MRF; i++) {
+ if (mrf_used[i]) {
+ fail("Register spilling not supported with m%d used", i);
+ return;
+ }
+ }
+
+ spilled_any_registers = true;
+ }
/* Generate spill/unspill instructions for the objects being
* spilled. Right now, we spill or unspill the whole thing to a
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 71b4bf94259..0e2dfd30016 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -2722,6 +2722,8 @@ fs_visitor::fs_visitor(struct brw_context *brw,
this->force_uncompressed_stack = 0;
this->force_sechalf_stack = 0;
+ this->spilled_any_registers = false;
+
memset(&this->param_size, 0, sizeof(this->param_size));
}