From d64ea4e48e1da072cae51df11bfbef7d6a432cb0 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Sat, 9 Apr 2016 17:10:30 +0200 Subject: [PATCH] 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 Reviewed-by: Ilia Mirkin (v2) --- .../nouveau/codegen/nv50_ir_from_tgsi.cpp | 28 +++++++++-- .../drivers/nouveau/codegen/nv50_ir_inlines.h | 6 +-- .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 46 +++++++++++++++++-- .../nouveau/codegen/nv50_ir_lowering_nvc0.h | 2 +- 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(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(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 *); -- 2.30.2