From 537f183fe67e0cf9f5737106d914cdabcf5d002e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 29 Oct 2013 12:46:18 -0700 Subject: [PATCH] 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 (v1) --- src/mesa/drivers/dri/i965/brw_fs.h | 1 + .../drivers/dri/i965/brw_fs_reg_allocate.cpp | 22 +++++++++++++++++++ src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 2 ++ 3 files changed, 25 insertions(+) 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)); } -- 2.30.2