mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
nvc0/ir: kepler can't do indirect shader input/output loads directly
There's a special AL2P instruction (called AFETCH in nv50 ir) which computes a "physical" value to be used with indirect addressing with ALD. Fixes tcs-input-array-*-index-rd tcs-output-array-*-index-wr varying-indexing tessellation tests on Kepler. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
22c9339abf
commit
9d60793a03
8 changed files with 75 additions and 6 deletions
|
|
@ -106,6 +106,7 @@ enum operation
|
|||
OP_MEMBAR, // memory barrier (mfence, lfence, sfence)
|
||||
OP_VFETCH, // indirection 0 in attribute space, indirection 1 is vertex base
|
||||
OP_PFETCH, // fetch base address of vertex src0 (immediate) [+ src1]
|
||||
OP_AFETCH, // fetch base address of shader input (a[%r1+0x10])
|
||||
OP_EXPORT,
|
||||
OP_LINTERP,
|
||||
OP_PINTERP,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ private:
|
|||
void emitMOV(const Instruction *);
|
||||
|
||||
void emitINTERP(const Instruction *);
|
||||
void emitAFETCH(const Instruction *);
|
||||
void emitPFETCH(const Instruction *);
|
||||
void emitVFETCH(const Instruction *);
|
||||
void emitEXPORT(const Instruction *);
|
||||
|
|
@ -1338,6 +1339,23 @@ CodeEmitterGK110::emitFlow(const Instruction *i)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGK110::emitAFETCH(const Instruction *i)
|
||||
{
|
||||
uint32_t offset = i->src(0).get()->reg.data.offset & 0x7ff;
|
||||
|
||||
code[0] = 0x00000002 | (offset << 23);
|
||||
code[1] = 0x7d000000 | (offset >> 9);
|
||||
|
||||
if (i->getSrc(0)->reg.file == FILE_SHADER_OUTPUT)
|
||||
code[1] |= 0x8;
|
||||
|
||||
emitPredicate(i);
|
||||
|
||||
defId(i->def(0), 2);
|
||||
srcId(i->src(0).getIndirect(0), 10);
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGK110::emitPFETCH(const Instruction *i)
|
||||
{
|
||||
|
|
@ -1707,6 +1725,9 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
|
|||
case OP_EXPORT:
|
||||
emitEXPORT(insn);
|
||||
break;
|
||||
case OP_AFETCH:
|
||||
emitAFETCH(insn);
|
||||
break;
|
||||
case OP_PFETCH:
|
||||
emitPFETCH(insn);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ private:
|
|||
void emitALD();
|
||||
void emitAST();
|
||||
void emitISBERD();
|
||||
void emitAL2P();
|
||||
void emitIPA();
|
||||
|
||||
void emitPIXLD();
|
||||
|
|
@ -2203,6 +2204,17 @@ CodeEmitterGM107::emitISBERD()
|
|||
emitGPR (0x00, insn->def(0));
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGM107::emitAL2P()
|
||||
{
|
||||
emitInsn (0xefa00000);
|
||||
emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
|
||||
emitO (0x20);
|
||||
emitField(0x14, 11, insn->src(0).get()->reg.data.offset);
|
||||
emitGPR (0x08, insn->src(0).getIndirect(0));
|
||||
emitGPR (0x00, insn->def(0));
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGM107::emitIPA()
|
||||
{
|
||||
|
|
@ -2759,6 +2771,9 @@ CodeEmitterGM107::emitInstruction(Instruction *i)
|
|||
case OP_PFETCH:
|
||||
emitISBERD();
|
||||
break;
|
||||
case OP_AFETCH:
|
||||
emitAL2P();
|
||||
break;
|
||||
case OP_LINTERP:
|
||||
case OP_PINTERP:
|
||||
emitIPA();
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ private:
|
|||
void emitCCTL(const Instruction *);
|
||||
|
||||
void emitINTERP(const Instruction *);
|
||||
void emitAFETCH(const Instruction *);
|
||||
void emitPFETCH(const Instruction *);
|
||||
void emitVFETCH(const Instruction *);
|
||||
void emitEXPORT(const Instruction *);
|
||||
|
|
@ -1493,6 +1494,21 @@ CodeEmitterNVC0::emitBAR(const Instruction *i)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterNVC0::emitAFETCH(const Instruction *i)
|
||||
{
|
||||
code[0] = 0x00000006;
|
||||
code[1] = 0x0c000000 | (i->src(0).get()->reg.data.offset & 0x7ff);
|
||||
|
||||
if (i->getSrc(0)->reg.file == FILE_SHADER_OUTPUT)
|
||||
code[0] |= 0x200;
|
||||
|
||||
emitPredicate(i);
|
||||
|
||||
defId(i->def(0), 14);
|
||||
srcId(i->src(0).getIndirect(0), 20);
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterNVC0::emitPFETCH(const Instruction *i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1749,6 +1749,7 @@ NVC0LoweringPass::checkPredicate(Instruction *insn)
|
|||
bool
|
||||
NVC0LoweringPass::visit(Instruction *i)
|
||||
{
|
||||
bool ret = true;
|
||||
bld.setPosition(i, false);
|
||||
|
||||
if (i->cc != CC_ALWAYS)
|
||||
|
|
@ -1780,7 +1781,8 @@ NVC0LoweringPass::visit(Instruction *i)
|
|||
case OP_SQRT:
|
||||
return handleSQRT(i);
|
||||
case OP_EXPORT:
|
||||
return handleEXPORT(i);
|
||||
ret = handleEXPORT(i);
|
||||
break;
|
||||
case OP_EMIT:
|
||||
case OP_RESTART:
|
||||
return handleOUT(i);
|
||||
|
|
@ -1843,7 +1845,20 @@ NVC0LoweringPass::visit(Instruction *i)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
/* Kepler+ has a special opcode to compute a new base address to be used
|
||||
* for indirect loads.
|
||||
*/
|
||||
if (targ->getChipset() >= NVISA_GK104_CHIPSET && !i->perPatch &&
|
||||
(i->op == OP_VFETCH || i->op == OP_EXPORT) && i->src(0).isIndirect(0)) {
|
||||
Instruction *afetch = bld.mkOp1(OP_AFETCH, TYPE_U32, bld.getSSA(),
|
||||
cloneShallow(func, i->getSrc(0)));
|
||||
afetch->setIndirect(0, 0, i->getIndirect(0, 0));
|
||||
i->src(0).get()->reg.data.offset = 0;
|
||||
i->setIndirect(0, 0, afetch->getDef(0));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ const char *operationStr[OP_LAST + 1] =
|
|||
"membar",
|
||||
"vfetch",
|
||||
"pfetch",
|
||||
"afetch",
|
||||
"export",
|
||||
"linterp",
|
||||
"pinterp",
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const uint8_t Target::operationSrcNr[] =
|
|||
0, 0, 0, 0, 0, // BRA, CALL, RET, CONT, BREAK,
|
||||
0, 0, 0, // PRERET,CONT,BREAK
|
||||
0, 0, 0, 0, 0, 0, // BRKPT, JOINAT, JOIN, DISCARD, EXIT, MEMBAR
|
||||
1, 1, 2, 1, 2, // VFETCH, PFETCH, EXPORT, LINTERP, PINTERP
|
||||
1, 1, 1, 2, 1, 2, // VFETCH, PFETCH, AFETCH, EXPORT, LINTERP, PINTERP
|
||||
1, 1, // EMIT, RESTART
|
||||
1, 1, 1, // TEX, TXB, TXL,
|
||||
1, 1, 1, 1, 1, 1, 2, // TXF, TXQ, TXD, TXG, TXLQ, TEXCSAA, TEXPREP
|
||||
|
|
@ -96,8 +96,8 @@ const OpClass Target::operationClass[] =
|
|||
OPCLASS_FLOW, OPCLASS_FLOW,
|
||||
// MEMBAR
|
||||
OPCLASS_CONTROL,
|
||||
// VFETCH, PFETCH, EXPORT
|
||||
OPCLASS_LOAD, OPCLASS_OTHER, OPCLASS_STORE,
|
||||
// VFETCH, PFETCH, AFETCH, EXPORT
|
||||
OPCLASS_LOAD, OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_STORE,
|
||||
// LINTERP, PINTERP
|
||||
OPCLASS_SFU, OPCLASS_SFU,
|
||||
// EMIT, RESTART
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void TargetNV50::initOpInfo()
|
|||
static const uint32_t shortForm[(OP_LAST + 31) / 32] =
|
||||
{
|
||||
// MOV,ADD,SUB,MUL,MAD,SAD,L/PINTERP,RCP,TEX,TXF
|
||||
0x00014e40, 0x00000040, 0x00000498, 0x00000000
|
||||
0x00014e40, 0x00000040, 0x00000930, 0x00000000
|
||||
};
|
||||
static const operation noDestList[] =
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue