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())); handleATOM(dst0, dstTy, tgsi::opcodeToSubOp(tgsi.getOpcode()));
break; break;
case TGSI_OPCODE_RESQ: case TGSI_OPCODE_RESQ:
geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0], if (tgsi.getSrc(0).getFile() == TGSI_FILE_BUFFER) {
makeSym(TGSI_FILE_BUFFER, tgsi.getSrc(0).getIndex(0), -1, 0, 0)); geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0],
if (tgsi.getSrc(0).isIndirect(0)) makeSym(tgsi.getSrc(0).getFile(),
geni->setIndirect(0, 1, fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0)); 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; break;
case TGSI_OPCODE_IBFE: case TGSI_OPCODE_IBFE:
case TGSI_OPCODE_UBFE: case TGSI_OPCODE_UBFE:

View file

@ -48,7 +48,7 @@ static inline bool isTextureOp(operation op)
static inline bool isSurfaceOp(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) static inline unsigned int typeSizeof(DataType ty)
@ -309,14 +309,14 @@ const FlowInstruction *Instruction::asFlow() const
TexInstruction *Instruction::asTex() 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 static_cast<TexInstruction *>(this);
return NULL; return NULL;
} }
const TexInstruction *Instruction::asTex() const 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 static_cast<const TexInstruction *>(this);
return NULL; return NULL;
} }

View file

@ -1510,9 +1510,49 @@ static inline uint16_t getSuClampSubOp(const TexInstruction *su, int c)
} }
bool 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; return true;
} }
@ -2265,7 +2305,7 @@ NVC0LoweringPass::visit(Instruction *i)
handleSurfaceOpNVE4(i->asTex()); handleSurfaceOpNVE4(i->asTex());
break; break;
case OP_SUQ: case OP_SUQ:
handleSUQ(i); handleSUQ(i->asTex());
break; break;
case OP_BUFQ: case OP_BUFQ:
handleBUFQ(i); handleBUFQ(i);

View file

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