[Mesa-dev] [PATCH v2 14/24] nv50/ir: make use of OP_SUQ for surfaces query
Samuel Pitoiset
samuel.pitoiset at gmail.com
Mon Apr 25 20:15:02 UTC 2016
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.
v2: - load a 1 into .w for the number of samples
- divide z-dim for cube/cube arrays by 6
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
.../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 28 +++++++++++--
.../drivers/nouveau/codegen/nv50_ir_inlines.h | 6 +--
.../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 47 ++++++++++++++++++++--
.../nouveau/codegen/nv50_ir_lowering_nvc0.h | 2 +-
4 files changed, 72 insertions(+), 11 deletions(-)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index 382c3d0..6544960 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -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:
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
index e465f24..4c5de2e 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
@@ -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;
}
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index 7b07b09..bf352e1 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -1510,9 +1510,50 @@ 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 == TEX_TARGET_CUBE ||
+ suq->tex.target == TEX_TARGET_CUBE_ARRAY) {
+ 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 +2306,7 @@ NVC0LoweringPass::visit(Instruction *i)
handleSurfaceOpNVE4(i->asTex());
break;
case OP_SUQ:
- handleSUQ(i);
+ handleSUQ(i->asTex());
break;
case OP_BUFQ:
handleBUFQ(i);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
index fd9f780..cbd26af 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
@@ -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 *);
--
2.8.0
More information about the mesa-dev
mailing list