diff options
Diffstat (limited to 'src')
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 *); |