[Mesa-dev] [RFC 15/24] nv50/ir: make use of OP_SUQ for surfaces query

Samuel Pitoiset samuel.pitoiset at gmail.com
Tue Apr 12 23:57:05 UTC 2016


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 <samuel.pitoiset at gmail.com>
---
 .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp  | 28 +++++++++++++++---
 .../drivers/nouveau/codegen/nv50_ir_inlines.h      |  6 ++--
 .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp      | 33 ++++++++++++++++++++--
 .../nouveau/codegen/nv50_ir_lowering_nvc0.h        |  2 +-
 4 files changed, 58 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 e56b992..ce76874 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -3435,10 +3435,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 e465f24..4c5de2e 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 60a3b4c..5920da6 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -1509,9 +1509,36 @@ 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);
+      }
+   }
+
+   bld.remove(suq);
    return true;
 }
 
@@ -2263,7 +2290,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 fd9f780..cbd26af 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.8.0



More information about the mesa-dev mailing list