diff options
author | Samuel Pitoiset <[email protected]> | 2016-04-09 17:10:30 +0200 |
---|---|---|
committer | Samuel Pitoiset <[email protected]> | 2016-04-26 19:47:49 +0200 |
commit | d64ea4e48e1da072cae51df11bfbef7d6a432cb0 (patch) | |
tree | c6a117ed20b3327afb8e435702ce018fd9d365a3 | |
parent | 7c47db359e193f21be796df3a7b5d037dd42b28f (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)
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 *); |