nv50/ir: make use of OP_SUQ for surfaces query

This implements RESQ for surfaces which comes from imageSize() GLSL
bultin. As the dimensions are sticked into the driver constant buffer,
this only has to be lowered with loads.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu> (v2)
This commit is contained in:
Samuel Pitoiset 2016-04-09 17:10:30 +02:00
parent 7c47db359e
commit d64ea4e48e
4 changed files with 71 additions and 11 deletions

View file

@ -3385,10 +3385,30 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
handleATOM(dst0, dstTy, tgsi::opcodeToSubOp(tgsi.getOpcode()));
break;
case TGSI_OPCODE_RESQ:
geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0],
makeSym(TGSI_FILE_BUFFER, tgsi.getSrc(0).getIndex(0), -1, 0, 0));
if (tgsi.getSrc(0).isIndirect(0))
geni->setIndirect(0, 1, fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0));
if (tgsi.getSrc(0).getFile() == TGSI_FILE_BUFFER) {
geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0],
makeSym(tgsi.getSrc(0).getFile(),
tgsi.getSrc(0).getIndex(0), -1, 0, 0));
if (tgsi.getSrc(0).isIndirect(0))
geni->setIndirect(0, 1,
fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0));
} else {
assert(tgsi.getSrc(0).getFile() == TGSI_FILE_IMAGE);
TexInstruction *texi = new_TexInstruction(func, OP_SUQ);
for (int c = 0, d = 0; c < 4; ++c) {
if (dst0[c]) {
texi->setDef(d++, dst0[c]);
texi->tex.mask |= 1 << c;
}
}
texi->tex.r = tgsi.getSrc(0).getIndex(0);
texi->tex.target = getImageTarget(code, texi->tex.r);
bb->insertTail(texi);
if (tgsi.getSrc(0).isIndirect(0))
texi->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, NULL));
}
break;
case TGSI_OPCODE_IBFE:
case TGSI_OPCODE_UBFE:

View file

@ -48,7 +48,7 @@ static inline bool isTextureOp(operation op)
static inline bool isSurfaceOp(operation op)
{
return (op >= OP_SULDB && op <= OP_SULEA);
return (op >= OP_SULDB && op <= OP_SULEA) || (op == OP_SUQ);
}
static inline unsigned int typeSizeof(DataType ty)
@ -309,14 +309,14 @@ const FlowInstruction *Instruction::asFlow() const
TexInstruction *Instruction::asTex()
{
if (op >= OP_TEX && op <= OP_SULEA)
if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)
return static_cast<TexInstruction *>(this);
return NULL;
}
const TexInstruction *Instruction::asTex() const
{
if (op >= OP_TEX && op <= OP_SULEA)
if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)
return static_cast<const TexInstruction *>(this);
return NULL;
}

View file

@ -1510,9 +1510,49 @@ static inline uint16_t getSuClampSubOp(const TexInstruction *su, int c)
}
bool
NVC0LoweringPass::handleSUQ(Instruction *suq)
NVC0LoweringPass::handleSUQ(TexInstruction *suq)
{
/* TODO: will be updated in the next commit. */
int dim = suq->tex.target.getDim();
int arg = dim + (suq->tex.target.isArray() || suq->tex.target.isCube());
uint8_t s = prog->driver->io.auxCBSlot;
Value *ind = suq->getIndirectR();
uint32_t base;
int c;
base = prog->driver->io.suInfoBase + suq->tex.r * NVE4_SU_INFO__STRIDE;
if (ind)
ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getScratch(),
ind, bld.mkImm(6));
for (c = 0; c < arg; ++c) {
if (suq->defExists(c)) {
int offset;
if (c == 1 && suq->tex.target == TEX_TARGET_1D_ARRAY) {
offset = base + NVE4_SU_INFO_SIZE(2);
} else {
offset = base + NVE4_SU_INFO_SIZE(c);
}
bld.mkLoad(TYPE_U32, suq->getDef(c),
bld.mkSymbol(FILE_MEMORY_CONST, s, TYPE_U32, offset), ind);
}
}
if (suq->tex.target.isCube()) {
if (suq->defExists(2)) {
bld.mkOp2(OP_DIV, TYPE_U32, suq->getDef(2), suq->getDef(2),
bld.loadImm(NULL, 6));
}
}
if (suq->defExists(3)) {
// .w contains the number of samples for multi-sampled images but we
// don't support them for now.
bld.mkMov(suq->getDef(3), bld.loadImm(NULL, 1));
}
bld.remove(suq);
return true;
}
@ -2265,7 +2305,7 @@ NVC0LoweringPass::visit(Instruction *i)
handleSurfaceOpNVE4(i->asTex());
break;
case OP_SUQ:
handleSUQ(i);
handleSUQ(i->asTex());
break;
case OP_BUFQ:
handleBUFQ(i);

View file

@ -101,7 +101,7 @@ protected:
bool handleTXQ(TexInstruction *);
virtual bool handleManualTXD(TexInstruction *);
bool handleTXLQ(TexInstruction *);
bool handleSUQ(Instruction *);
bool handleSUQ(TexInstruction *);
bool handleATOM(Instruction *);
bool handleCasExch(Instruction *, bool needCctl);
void handleSurfaceOpNVE4(TexInstruction *);