From 7a91d3a2a4c4e7851fdb46465224213ce1874c9b Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Sat, 2 Mar 2013 21:00:26 +0100 Subject: [PATCH] nv50/ir: add support for different sampler and resource index on nve4 And remove non-working code for indirect sampler/resource selection. Will be added back later. Includes code from "nv50/ir/tgsi: Resource indirect indexing" by Francisco Jerez (when mixing the R and S handles we can only specify them via a register, i.e. indirectly, unless we upload all the used handle combinations to c[] space, which we don't for now). --- src/gallium/drivers/nv50/codegen/nv50_ir.cpp | 27 +++++++++ src/gallium/drivers/nv50/codegen/nv50_ir.h | 2 + .../nvc0/codegen/nv50_ir_lowering_nvc0.cpp | 59 +++++++------------ 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp index 3c05d05b81f..7788e51fd0d 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir.cpp @@ -687,6 +687,11 @@ Instruction::moveSources(const int s, const int delta) } moveSourcesAdjustIndex(predSrc, s, delta); moveSourcesAdjustIndex(flagsSrc, s, delta); + if (asTex()) { + TexInstruction *tex = asTex(); + moveSourcesAdjustIndex(tex->tex.rIndirectSrc, s, delta); + moveSourcesAdjustIndex(tex->tex.sIndirectSrc, s, delta); + } if (delta > 0) { --k; @@ -950,6 +955,28 @@ const struct TexInstruction::Target::Desc TexInstruction::Target::descTable[] = { "BUFFER", 1, 1, false, false, false }, }; +void +TexInstruction::setIndirectR(Value *v) +{ + int p = ((tex.rIndirectSrc < 0) && v) ? srcs.size() : tex.rIndirectSrc; + if (p >= 0) { + tex.rIndirectSrc = p; + setSrc(p, v); + srcs[p].usedAsPtr = !!v; + } +} + +void +TexInstruction::setIndirectS(Value *v) +{ + int p = ((tex.sIndirectSrc < 0) && v) ? srcs.size() : tex.sIndirectSrc; + if (p >= 0) { + tex.sIndirectSrc = p; + setSrc(p, v); + srcs[p].usedAsPtr = !!v; + } +} + CmpInstruction::CmpInstruction(Function *fn, operation op) : Instruction(fn, op, TYPE_F32) { diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.h b/src/gallium/drivers/nv50/codegen/nv50_ir.h index 548125901e2..7862724411e 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir.h +++ b/src/gallium/drivers/nv50/codegen/nv50_ir.h @@ -865,6 +865,8 @@ public: tex.target = targ; } + void setIndirectR(Value *); + void setIndirectS(Value *); inline Value *getIndirectR() const; inline Value *getIndirectS() const; diff --git a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp index 414a503c87d..cd30f63037c 100644 --- a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp @@ -604,6 +604,7 @@ private: Value *loadResInfo32(Value *ptr, uint32_t off); Value *loadMsInfo32(Value *ptr, uint32_t off); + Value *loadTexHandle(Value *ptr, unsigned int slot); void adjustCoordinatesMS(TexInstruction *); void processSurfaceCoordsNVE4(TexInstruction *); @@ -645,6 +646,15 @@ NVC0LoweringPass::visit(BasicBlock *bb) return true; } +inline Value * +NVC0LoweringPass::loadTexHandle(Value *ptr, unsigned int slot) +{ + uint8_t b = prog->driver->io.resInfoCBSlot; + uint32_t off = prog->driver->io.texBindBase + slot * 4; + return bld. + mkLoadv(TYPE_U32, bld.mkSymbol(FILE_MEMORY_CONST, b, TYPE_U32, off), ptr); +} + // move array source to first slot, convert to u16, add indirections bool NVC0LoweringPass::handleTEX(TexInstruction *i) @@ -653,11 +663,22 @@ NVC0LoweringPass::handleTEX(TexInstruction *i) const int arg = i->tex.target.getArgCount(); if (prog->getTarget()->getChipset() >= NVISA_GK104_CHIPSET) { + if (i->tex.rIndirectSrc >= 0 || i->tex.sIndirectSrc >= 0) { + WARN("indirect TEX not implemented\n"); + } if (i->tex.r == i->tex.s) { i->tex.r += prog->driver->io.texBindBase / 4; i->tex.s = 0; // only a single cX[] value possible here } else { - // TODO: extract handles and use register to select TIC/TSC entries + Value *hnd = bld.getScratch(); + Value *rHnd = loadTexHandle(NULL, i->tex.r); + Value *sHnd = loadTexHandle(NULL, i->tex.s); + + bld.mkOp3(OP_INSBF, TYPE_U32, hnd, rHnd, bld.mkImm(0x1400), sHnd); + + i->tex.r = 0; // not used for indirect tex + i->tex.s = 0; + i->setIndirectR(hnd); } if (i->tex.target.isArray()) { LValue *layer = new_LValue(func, FILE_GPR); @@ -669,42 +690,6 @@ NVC0LoweringPass::handleTEX(TexInstruction *i) i->setSrc(s, i->getSrc(s - 1)); i->setSrc(0, layer); } - if (i->tex.rIndirectSrc >= 0 || i->tex.sIndirectSrc >= 0) { - Value *tmp[2]; - Symbol *bind; - Value *rRel = i->getIndirectR(); - Value *sRel = i->getIndirectS(); - Value *shCnt = bld.loadImm(NULL, 2); - - if (rRel) { - tmp[0] = bld.getScratch(); - bind = bld.mkSymbol(FILE_MEMORY_CONST, 15, TYPE_U32, i->tex.r * 4); - bld.mkOp2(OP_SHL, TYPE_U32, tmp[0], rRel, shCnt); - tmp[1] = bld.mkLoadv(TYPE_U32, bind, tmp[0]); - bld.mkOp2(OP_AND, TYPE_U32, tmp[0], tmp[1], - bld.loadImm(tmp[0], 0x00ffffffu)); - rRel = tmp[0]; - i->setSrc(i->tex.rIndirectSrc, NULL); - } - if (sRel) { - tmp[0] = bld.getScratch(); - bind = bld.mkSymbol(FILE_MEMORY_CONST, 15, TYPE_U32, i->tex.s * 4); - bld.mkOp2(OP_SHL, TYPE_U32, tmp[0], sRel, shCnt); - tmp[1] = bld.mkLoadv(TYPE_U32, bind, tmp[0]); - bld.mkOp2(OP_AND, TYPE_U32, tmp[0], tmp[1], - bld.loadImm(tmp[0], 0xff000000u)); - sRel = tmp[0]; - i->setSrc(i->tex.sIndirectSrc, NULL); - } - bld.mkOp2(OP_OR, TYPE_U32, rRel, rRel, sRel); - - int min = i->tex.rIndirectSrc; - if (min < 0 || min > i->tex.sIndirectSrc) - min = i->tex.sIndirectSrc; - for (int s = min; s >= 1; --s) - i->setSrc(s, i->getSrc(s - 1)); - i->setSrc(0, rRel); - } } else // (nvc0) generate and move the tsc/tic/array source to the front if (dim != arg || i->tex.rIndirectSrc >= 0 || i->tex.sIndirectSrc >= 0) { -- 2.30.2