nvc0/ir: cache vertex out base so that we don't recompute again
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 29 Jul 2015 15:01:08 +0000 (11:01 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Wed, 29 Jul 2015 15:05:56 +0000 (11:05 -0400)
The global CSE pass stinks and is unable to pull this out. Easy enough
to handle it here and avoid generating unnecessary special register
loads (which can allegedly be quite slow).

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp

index 3c558e941bde8300b22e9d9604b852d3d5665204..4847a0f33557905ebdbee40c05a7f9c1e337b78b 100644 (file)
@@ -1394,6 +1394,8 @@ private:
    Value *vtxBase[5]; // base address of vertex in primitive (for TP/GP)
    uint8_t vtxBaseValid;
 
+   Value *outBase; // base address of vertex out patch (for TCP)
+
    Stack condBBs;  // fork BB, then else clause BB
    Stack joinBBs;  // fork BB, for inserting join ops on ENDIF
    Stack loopBBs;  // loop headers
@@ -1537,13 +1539,7 @@ Converter::getOutputBase(int s)
                          fetchSrc(tgsi.getSrc(s).getIndirect(1), 0, NULL),
                          offset);
       vtxBaseValid |= 1 << s;
-      vtxBase[s] = mkOp2v(
-         OP_ADD, TYPE_U32, getSSA(),
-         mkOp2v(
-            OP_SUB, TYPE_U32, getSSA(),
-            mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_LANEID, 0)),
-            mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_INVOCATION_ID, 0))),
-         offset);
+      vtxBase[s] = mkOp2v(OP_ADD, TYPE_U32, getSSA(), outBase, offset);
    }
    return vtxBase[s];
 }
@@ -3369,10 +3365,21 @@ Converter::run()
          clipVtx[c] = getScratch();
    }
 
-   if (prog->getType() == Program::TYPE_FRAGMENT) {
+   switch (prog->getType()) {
+   case Program::TYPE_TESSELLATION_CONTROL:
+      outBase = mkOp2v(
+         OP_SUB, TYPE_U32, getSSA(),
+         mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_LANEID, 0)),
+         mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_INVOCATION_ID, 0)));
+      break;
+   case Program::TYPE_FRAGMENT: {
       Symbol *sv = mkSysVal(SV_POSITION, 3);
       fragCoord[3] = mkOp1v(OP_RDSV, TYPE_F32, getSSA(), sv);
       mkOp1(OP_RCP, TYPE_F32, fragCoord[3], fragCoord[3]);
+      break;
+   }
+   default:
+      break;
    }
 
    if (info->io.viewportId >= 0)