intel/fs: Add a parameter to speed up register spilling

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24299>
This commit is contained in:
Jason Ekstrand
2020-10-23 15:58:06 -05:00
committed by Marge Bot
parent be11fee2a7
commit 739e21fa9a
2 changed files with 33 additions and 15 deletions

View File

@@ -128,6 +128,15 @@ struct brw_compiler {
*/ */
bool use_bindless_sampler_offset; bool use_bindless_sampler_offset;
/**
* Calling the ra_allocate function after each register spill can take
* several minutes. This option speeds up shader compilation by spilling
* more registers after the ra_allocate failure. Required for
* Cyberpunk 2077, which uses a watchdog thread to terminate the process
* in case the render thread hasn't responded within 2 minutes.
*/
int spilling_rate;
struct nir_shader *clc_shader; struct nir_shader *clc_shader;
struct { struct {

View File

@@ -1308,7 +1308,7 @@ fs_reg_alloc::assign_regs(bool allow_spilling, bool spill_all)
{ {
build_interference_graph(fs->spilled_any_registers || spill_all); build_interference_graph(fs->spilled_any_registers || spill_all);
bool spilled = false; unsigned spilled = 0;
while (1) { while (1) {
/* Debug of register spilling: Go spill everything. */ /* Debug of register spilling: Go spill everything. */
if (unlikely(spill_all)) { if (unlikely(spill_all)) {
@@ -1325,24 +1325,33 @@ fs_reg_alloc::assign_regs(bool allow_spilling, bool spill_all)
if (!allow_spilling) if (!allow_spilling)
return false; return false;
/* Failed to allocate registers. Spill a reg, and the caller will /* Failed to allocate registers. Spill some regs, and the caller will
* loop back into here to try again. * loop back into here to try again.
*/ */
int reg = choose_spill_reg(); unsigned nr_spills = 1;
if (reg == -1) if (compiler->spilling_rate)
return false; nr_spills = MAX2(1, spilled / compiler->spilling_rate);
/* If we're going to spill but we've never spilled before, we need to for (unsigned j = 0; j < nr_spills; j++) {
* re-build the interference graph with MRFs enabled to allow spilling. int reg = choose_spill_reg();
if (reg == -1) {
if (j == 0)
return false; /* Nothing to spill */
break;
}
/* If we're going to spill but we've never spilled before, we need
* to re-build the interference graph with MRFs enabled to allow
* spilling.
*/ */
if (!fs->spilled_any_registers) { if (!fs->spilled_any_registers) {
discard_interference_graph(); discard_interference_graph();
build_interference_graph(true); build_interference_graph(true);
} }
spilled = true;
spill_reg(reg); spill_reg(reg);
spilled++;
}
} }
if (spilled) if (spilled)