<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 16, 2016 at 9:22 PM, Francisco Jerez <span dir="ltr"><<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">And as we're at it fix the calculation to allocate a larger block of<br>
registers for 32-wide dispatch.<br>
---<br>
src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp | 54 +++++++++++++++++++----<br>
1 file changed, 45 insertions(+), 9 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp<br>
index 2347cd5..1f1bcf8 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp<br>
@@ -723,6 +723,47 @@ fs_visitor::assign_regs(bool allow_spilling)<br>
return true;<br>
}<br>
<br>
+namespace {<br>
+ /**<br>
+ * Maximum spill block size we expect to encounter in 32B units.<br>
+ *<br>
+ * This is somewhat arbitrary and doesn't necessarily limit the maximum<br>
+ * variable size that can be spilled -- A higher value will allow a<br>
+ * variable of a given size to be spilled more efficiently with a smaller<br>
+ * number of scratch messages, but will increase the likelihood of a<br>
+ * collision between the MRFs reserved for spilling and other MRFs used by<br>
+ * the program (and possibly increase GRF register pressure on platforms<br>
+ * without hardware MRFs), what could cause register allocation to fail.<br>
+ *<br>
+ * For the moment reserve just enough space so a register of 32 bit<br>
+ * component type and natural region width can be spilled without splitting<br>
+ * into multiple (force_writemask_all) scratch messages.<br>
+ */<br>
+ unsigned<br>
+ spill_max_size(const backend_shader *s)<br>
+ {<br>
+ /* FINISHME - On Gen7+ it should be possible to avoid this limit<br>
+ * altogether by spilling directly from the temporary GRF<br>
+ * allocated to hold the result of the instruction (and the<br>
+ * scratch write header).<br>
+ */<br>
+ /* FINISHME - The shader's dispatch width probably belongs in<br>
+ * backend_shader (or some nonexistent fs_shader class?)<br>
+ * rather than in the visitor class.<br></blockquote><div><br></div><div>Agreed. However, I don't think making spill_max_size take a backend_shader and then doing a static_cast is really going help when it comes time to split it up. Leaving enough of this stuff lying around may, however, annoy people into doing it?<br><br></div><div>Personally, I'd drop the cast and just pass in an fs_visitor like everyone else.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ */<br>
+ return static_cast<const fs_visitor *>(s)->dispatch_width / 8;<br>
+ }<br>
+<br>
+ /**<br>
+ * First MRF register available for spilling.<br>
+ */<br>
+ unsigned<br>
+ spill_base_mrf(const backend_shader *s)<br>
+ {<br>
+ return BRW_MAX_MRF(s->devinfo->gen) - spill_max_size(s) - 1;<br>
+ }<br>
+}<br>
+<br>
void<br>
fs_visitor::emit_unspill(bblock_t *block, fs_inst *inst, fs_reg dst,<br>
uint32_t spill_offset, int count)<br>
@@ -753,7 +794,7 @@ fs_visitor::emit_unspill(bblock_t *block, fs_inst *inst, fs_reg dst,<br>
unspill_inst->regs_written = reg_size;<br>
<br>
if (!gen7_read) {<br>
- unspill_inst->base_mrf = FIRST_SPILL_MRF(devinfo->gen) + 1;<br>
+ unspill_inst->base_mrf = spill_base_mrf(this);<br>
unspill_inst->mlen = 1; /* header contains offset */<br>
}<br>
<br>
@@ -767,11 +808,8 @@ fs_visitor::emit_spill(bblock_t *block, fs_inst *inst, fs_reg src,<br>
uint32_t spill_offset, int count)<br>
{<br>
int reg_size = 1;<br>
- int spill_base_mrf = FIRST_SPILL_MRF(devinfo->gen) + 1;<br>
- if (dispatch_width == 16 && count % 2 == 0) {<br>
- spill_base_mrf = FIRST_SPILL_MRF(devinfo->gen);<br>
+ if (dispatch_width == 16 && count % 2 == 0)<br>
reg_size = 2;<br>
- }<br>
<br>
const fs_builder ibld = bld.annotate(inst->annotation, inst->ir)<br>
.group(reg_size * 8, 0)<br>
@@ -783,7 +821,7 @@ fs_visitor::emit_spill(bblock_t *block, fs_inst *inst, fs_reg src,<br>
src.reg_offset += reg_size;<br>
spill_inst->offset = spill_offset + i * reg_size * REG_SIZE;<br>
spill_inst->mlen = 1 + reg_size; /* header, value */<br>
- spill_inst->base_mrf = spill_base_mrf;<br>
+ spill_inst->base_mrf = spill_base_mrf(this);<br>
}<br>
}<br>
<br>
@@ -869,8 +907,6 @@ fs_visitor::spill_reg(int spill_reg)<br>
int size = alloc.sizes[spill_reg];<br>
unsigned int spill_offset = last_scratch;<br>
assert(ALIGN(spill_offset, 16) == spill_offset); /* oword read/write req. */<br>
- int spill_base_mrf = dispatch_width > 8 ? FIRST_SPILL_MRF(devinfo->gen) :<br>
- FIRST_SPILL_MRF(devinfo->gen) + 1;<br>
<br>
/* Spills may use MRFs 13-15 in the SIMD16 case. Our texturing is done<br>
* using up to 11 MRFs starting from either m1 or m2, and fb writes can use<br>
@@ -883,7 +919,7 @@ fs_visitor::spill_reg(int spill_reg)<br>
bool mrf_used[BRW_MAX_MRF(devinfo->gen)];<br>
get_used_mrfs(this, mrf_used);<br>
<br>
- for (int i = spill_base_mrf; i < BRW_MAX_MRF(devinfo->gen); i++) {<br>
+ for (int i = spill_base_mrf(this); i < BRW_MAX_MRF(devinfo->gen); i++) {<br>
if (mrf_used[i]) {<br>
fail("Register spilling not supported with m%d used", i);<br>
return;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.7.3<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>