i965/fs: Properly write-mask spills
For unspills (scratch reads), we can just set WE_all all the time because we always unspill into a new GRF. For spills, we have two options: If the instruction has a 32-bit-per-channel destination and "normal" regioning, then we just do a regular write and it will interleave channels from different control-flow paths properly. If, on the other hand, the the regioning is non-normal, then we have to unspill, run the instruction, and spill afterwards. In this second case, we need to do the spill with we_ALL.
This commit is contained in:
parent
8e07f7942e
commit
9c0109a1f6
|
@ -224,7 +224,7 @@ public:
|
|||
void emit_unspill(bblock_t *block, fs_inst *inst, fs_reg reg,
|
||||
uint32_t spill_offset, int count);
|
||||
void emit_spill(bblock_t *block, fs_inst *inst, fs_reg reg,
|
||||
uint32_t spill_offset, int count);
|
||||
uint32_t spill_offset, int count, bool we_all);
|
||||
|
||||
void emit_nir_code();
|
||||
void nir_setup_inputs();
|
||||
|
|
|
@ -751,6 +751,7 @@ fs_visitor::emit_unspill(bblock_t *block, fs_inst *inst, fs_reg dst,
|
|||
dst);
|
||||
unspill_inst->offset = spill_offset;
|
||||
unspill_inst->regs_written = reg_size;
|
||||
unspill_inst->force_writemask_all = true;
|
||||
|
||||
if (!gen7_read) {
|
||||
unspill_inst->base_mrf = FIRST_SPILL_MRF(devinfo->gen) + 1;
|
||||
|
@ -764,11 +765,11 @@ fs_visitor::emit_unspill(bblock_t *block, fs_inst *inst, fs_reg dst,
|
|||
|
||||
void
|
||||
fs_visitor::emit_spill(bblock_t *block, fs_inst *inst, fs_reg src,
|
||||
uint32_t spill_offset, int count)
|
||||
uint32_t spill_offset, int count, bool we_all)
|
||||
{
|
||||
int reg_size = 1;
|
||||
int spill_base_mrf = FIRST_SPILL_MRF(devinfo->gen) + 1;
|
||||
if (dispatch_width == 16 && count % 2 == 0) {
|
||||
if (inst->exec_size == 16 && count % 2 == 0) {
|
||||
spill_base_mrf = FIRST_SPILL_MRF(devinfo->gen);
|
||||
reg_size = 2;
|
||||
}
|
||||
|
@ -784,6 +785,8 @@ fs_visitor::emit_spill(bblock_t *block, fs_inst *inst, fs_reg src,
|
|||
spill_inst->offset = spill_offset + i * reg_size * REG_SIZE;
|
||||
spill_inst->mlen = 1 + reg_size; /* header, value */
|
||||
spill_inst->base_mrf = spill_base_mrf;
|
||||
spill_inst->force_writemask_all = we_all;
|
||||
spill_inst->force_sechalf = inst->force_sechalf;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -938,12 +941,15 @@ fs_visitor::spill_reg(int spill_reg)
|
|||
* inst->regs_written(), then we need to unspill the destination
|
||||
* since we write back out all of the regs_written().
|
||||
*/
|
||||
if (inst->is_partial_write())
|
||||
bool need_unspill = inst->is_partial_write() ||
|
||||
type_sz(inst->dst.type) != 4;
|
||||
if (need_unspill)
|
||||
emit_unspill(block, inst, spill_src, subset_spill_offset,
|
||||
inst->regs_written);
|
||||
|
||||
emit_spill(block, inst, spill_src, subset_spill_offset,
|
||||
inst->regs_written);
|
||||
inst->regs_written,
|
||||
need_unspill || inst->force_writemask_all);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue