summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 *);