nv50/ir: add support for different sampler and resource index on nve4
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 2 Mar 2013 20:00:26 +0000 (21:00 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 12 Mar 2013 11:55:36 +0000 (12:55 +0100)
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
src/gallium/drivers/nv50/codegen/nv50_ir.h
src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp

index 3c05d05b81f871bd2b4d5c9db9054abe233852db..7788e51fd0db4bed555518d13e1ea51b1c3f5370 100644 (file)
@@ -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)
 {
index 548125901e2a1a0cd4275b91033434378e6dd9cb..7862724411e799975924b58bebdc11c496421777 100644 (file)
@@ -865,6 +865,8 @@ public:
       tex.target = targ;
    }
 
+   void setIndirectR(Value *);
+   void setIndirectS(Value *);
    inline Value *getIndirectR() const;
    inline Value *getIndirectS() const;
 
index 414a503c87da18b7872cb95908098090c12fd977..cd30f63037c37935f7a169e0bed05258660cf457 100644 (file)
@@ -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) {