i965/fs: Exit the compile if spilling would overwrite in-use MRFs.
authorEric Anholt <eric@anholt.net>
Tue, 29 Oct 2013 19:46:18 +0000 (12:46 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 31 Oct 2013 00:51:02 +0000 (17:51 -0700)
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 <stereotype441@gmail.com> (v1)
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index 50a045e4b4ba4d443db96a906e4c803cda9fbe9f..fb1da4ce781369c985d84ce3a25db176fb050c10 100644 (file)
@@ -466,6 +466,7 @@ public:
    fs_reg shader_start_time;
 
    int grf_used;
+   bool spilled_any_registers;
 
    const unsigned dispatch_width; /**< 8 or 16 */
 
index d86027efd81b11ee2f64ff3142eaf2b0820526bf..35dae8432906600b4efc5ecc51390b83380d6b4f 100644 (file)
@@ -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
index 71b4bf9425957fcc29d3cb52389a7adf9fb7750e..0e2dfd30016bc7ef2da2ee7a54eff1ef16f79cff 100644 (file)
@@ -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));
 }