summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2016-04-09 17:10:30 +0200
committerSamuel Pitoiset <[email protected]>2016-04-26 19:47:49 +0200
commitd64ea4e48e1da072cae51df11bfbef7d6a432cb0 (patch)
treec6a117ed20b3327afb8e435702ce018fd9d365a3
parent7c47db359e193f21be796df3a7b5d037dd42b28f (diff)
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 <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]> (v2)
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp28
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h6
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp46
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h2
4 files changed, 71 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 22a6ebc3ac1..fd88af35b77 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 e465f24845b..4c5de2e82c7 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 7b07b09f65f..03159e890fd 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,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);
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 fd9f78012b7..cbd26af362f 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 *);