Skip to content

Commit 3224fa6

Browse files
committed
codegen: track dual-issued texture dependencies via a shared counter (Maxwell)
1 parent 5a5afc2 commit 3224fa6

1 file changed

Lines changed: 64 additions & 6 deletions

File tree

mesa-imported/codegen/nv50_ir_emit_gm107.cpp

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4312,6 +4312,7 @@ SchedDataCalculatorGM107::insertBarriers(BasicBlock *bb)
43124312
Instruction *insn, *next;
43134313
BitSet bars(6, 1);
43144314
int bar_id;
4315+
int texBar = -1; // shared texture-pipe counter barrier
43154316

43164317
for (insn = bb->getEntry(); insn != NULL; insn = next) {
43174318
Instruction *usei = NULL, *defi = NULL;
@@ -4325,7 +4326,8 @@ SchedDataCalculatorGM107::insertBarriers(BasicBlock *bb)
43254326
if (insn->serial >= it->usei->serial) {
43264327
int wr = getWrDepBar(it->insn);
43274328
emitWtDepBar(insn, wr);
4328-
bars.clr(wr); // free barrier
4329+
if (wr != texBar)
4330+
bars.clr(wr); // free barrier (texture counter stays reserved)
43294331
it = live_uses.erase(it);
43304332
continue;
43314333
}
@@ -4355,11 +4357,23 @@ SchedDataCalculatorGM107::insertBarriers(BasicBlock *bb)
43554357
// completing before this insn.
43564358
usei = findFirstUse(insn);
43574359

4358-
// Allocate and emit a new barrier.
4359-
bar_id = bars.findFreeRange(1);
4360-
if (bar_id == -1)
4361-
bar_id = 5;
4362-
bars.set(bar_id);
4360+
// Allocate and emit a new barrier. Textures share one counter barrier
4361+
// (consumers wait for it to drain) because a per-texture write barrier
4362+
// is unreliable when the texture is dual-issued.
4363+
if (targ->getOpClass(insn->op) == OPCLASS_TEXTURE) {
4364+
if (texBar == -1) {
4365+
texBar = bars.findFreeRange(1);
4366+
if (texBar == -1)
4367+
texBar = 5;
4368+
bars.set(texBar);
4369+
}
4370+
bar_id = texBar;
4371+
} else {
4372+
bar_id = bars.findFreeRange(1);
4373+
if (bar_id == -1)
4374+
bar_id = 5;
4375+
bars.set(bar_id);
4376+
}
43634377
emitWrDepBar(insn, bar_id);
43644378
if (usei)
43654379
live_uses.push_back(LiveBarUse(insn, usei));
@@ -4494,6 +4508,50 @@ SchedDataCalculatorGM107::visit(BasicBlock *bb)
44944508
#endif
44954509
}
44964510

4511+
// A barrier issued from the second dual-issue slot is not honored by the
4512+
// texture unit, so a co-issued texture must set no barrier:
4513+
// - its write (result) barrier is offloaded to the shared texture counter,
4514+
// which a following texture keeps live (textures retire in order, so the
4515+
// counter wait covers this result too);
4516+
// - its read (coordinate) barrier cannot be offloaded, so a texture that
4517+
// needs one is un-dual-issued back into its own slot.
4518+
{
4519+
Instruction *prevInsn = NULL;
4520+
for (Instruction *t = bb->getEntry(); t != NULL; prevInsn = t, t = t->next) {
4521+
if (targ->getOpClass(t->op) != OPCLASS_TEXTURE)
4522+
continue;
4523+
if (!prevInsn || getStall(prevInsn) != 0)
4524+
continue; // not the second slot of a dual-issue
4525+
4526+
// Coordinate WAR (read barrier) can't be covered from the second slot.
4527+
if (getRdDepBar(t) != 7) {
4528+
prevInsn->sched = (prevInsn->sched & ~0x1f) | 0x1; // stall 1, no yield
4529+
continue;
4530+
}
4531+
4532+
int wb = getWrDepBar(t);
4533+
if (wb == 7)
4534+
continue;
4535+
bool covered = false;
4536+
Instruction *jprev = t;
4537+
for (Instruction *j = t->next; j != NULL; jprev = j, j = j->next) {
4538+
if (getWtDepBar(j) & (1 << wb))
4539+
break; // counter drained before a covering texture
4540+
// The covering texture must keep its barrier, i.e. not be co-issued
4541+
// itself (a co-issued texture's barrier is dropped below).
4542+
if (targ->getOpClass(j->op) == OPCLASS_TEXTURE &&
4543+
getWrDepBar(j) != 7 && getStall(jprev) != 0) {
4544+
covered = true;
4545+
break;
4546+
}
4547+
}
4548+
if (covered)
4549+
t->sched |= 0xe0; // drop write dep barrier (counter covers it)
4550+
else
4551+
prevInsn->sched = (prevInsn->sched & ~0x1f) | 0x1; // no cover: own slot
4552+
}
4553+
}
4554+
44974555
if (!insn)
44984556
return true;
44994557
commitInsn(insn, cycle);

0 commit comments

Comments
 (0)