nvc0/ir: lower atomics in s[]
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 22 Feb 2013 19:46:28 +0000 (20:46 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 12 Mar 2013 11:55:35 +0000 (12:55 +0100)
src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp

index 9cea061..04b88dd 100644 (file)
@@ -598,6 +598,7 @@ private:
    bool handleTXD(TexInstruction *);
    bool handleTXQ(TexInstruction *);
    bool handleManualTXD(TexInstruction *);
+   bool handleATOM(Instruction *);
 
    void checkPredicate(Instruction *);
 
@@ -837,6 +838,35 @@ NVC0LoweringPass::handleTXQ(TexInstruction *txq)
 }
 
 bool
+NVC0LoweringPass::handleATOM(Instruction *atom)
+{
+   SVSemantic sv;
+
+   switch (atom->src(0).getFile()) {
+   case FILE_MEMORY_LOCAL:
+      sv = SV_LBASE;
+      break;
+   case FILE_MEMORY_SHARED:
+      sv = SV_SBASE;
+      break;
+   default:
+      assert(atom->src(0).getFile() == FILE_MEMORY_GLOBAL);
+      return true;
+   }
+   Value *base =
+      bld.mkOp1v(OP_RDSV, TYPE_U32, bld.getScratch(), bld.mkSysVal(sv, 0));
+   Value *ptr = atom->getIndirect(0, 0);
+
+   atom->setSrc(0, cloneShallow(func, atom->getSrc(0)));
+   atom->getSrc(0)->reg.file = FILE_MEMORY_GLOBAL;
+   if (ptr)
+      base = bld.mkOp2v(OP_ADD, TYPE_U32, base, base, ptr);
+   atom->setIndirect(0, 0, base);
+
+   return true;
+}
+
+bool
 NVC0LoweringPass::handleWRSV(Instruction *i)
 {
    Instruction *st;
@@ -1094,6 +1124,9 @@ NVC0LoweringPass::visit(Instruction *i)
          assert(prog->getType() != Program::TYPE_FRAGMENT);
       }
       break;
+   case OP_ATOM:
+      handleATOM(i);
+      break;
    default:
       break;
    }