nv50/ir/nir: add loadFrom and storeTo helpler
[mesa.git] / src / gallium / drivers / nouveau / codegen / nv50_ir_emit_nv50.cpp
index bc8354deba1a4fa4d3738e78de0eb803c90bb777..139ff4a31dc9ef1b37bdd87d34d5ae8504bc82f8 100644 (file)
@@ -527,7 +527,8 @@ CodeEmitterNV50::emitForm_ADD(const Instruction *i)
 
    setSrcFileBits(i, NV50_OP_ENC_LONG_ALT);
    setSrc(i, 0, 0);
-   setSrc(i, 1, 2);
+   if (i->predSrc != 1)
+      setSrc(i, 1, 2);
 
    if (i->getIndirect(0, 0)) {
       assert(!i->getIndirect(1, 0));
@@ -620,7 +621,7 @@ void
 CodeEmitterNV50::emitLOAD(const Instruction *i)
 {
    DataFile sf = i->src(0).getFile();
-   int32_t offset = i->getSrc(0)->reg.data.offset;
+   MAYBE_UNUSED int32_t offset = i->getSrc(0)->reg.data.offset;
 
    switch (sf) {
    case FILE_SHADER_INPUT:
@@ -840,7 +841,7 @@ CodeEmitterNV50::emitQUADOP(const Instruction *i, uint8_t lane, uint8_t quOp)
 
    emitForm_ADD(i);
 
-   if (!i->srcExists(1))
+   if (!i->srcExists(1) || i->predSrc == 1)
       srcId(i->src(0), 32 + 14);
 }
 
@@ -881,8 +882,7 @@ CodeEmitterNV50::emitPFETCH(const Instruction *i)
 }
 
 static void
-interpApply(const InterpEntry *entry, uint32_t *code,
-      bool force_persample_interp, bool flatshade)
+interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
 {
    int ipa = entry->ipa;
    int encSize = entry->reg;
@@ -890,7 +890,7 @@ interpApply(const InterpEntry *entry, uint32_t *code,
 
    if ((ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
        (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
-      if (force_persample_interp) {
+      if (data.force_persample_interp) {
          if (encSize == 8)
             code[loc + 1] |= 1 << 16;
          else
@@ -911,6 +911,7 @@ CodeEmitterNV50::emitINTERP(const Instruction *i)
 
    defId(i->def(0), 2);
    srcAddr8(i->src(0), 16);
+   setAReg16(i, 0);
 
    if (i->encSize != 8 && i->getInterpMode() == NV50_IR_INTERP_FLAT) {
       code[0] |= 1 << 8;
@@ -1264,6 +1265,28 @@ CodeEmitterNV50::emitISAD(const Instruction *i)
    }
 }
 
+static void
+alphatestSet(const FixupEntry *entry, uint32_t *code, const FixupData& data)
+{
+   int loc = entry->loc;
+   int enc;
+
+   switch (data.alphatest) {
+   case PIPE_FUNC_NEVER: enc = 0x0; break;
+   case PIPE_FUNC_LESS: enc = 0x1; break;
+   case PIPE_FUNC_EQUAL: enc = 0x2; break;
+   case PIPE_FUNC_LEQUAL: enc = 0x3; break;
+   case PIPE_FUNC_GREATER: enc = 0x4; break;
+   case PIPE_FUNC_NOTEQUAL: enc = 0x5; break;
+   case PIPE_FUNC_GEQUAL: enc = 0x6; break;
+   default:
+   case PIPE_FUNC_ALWAYS: enc = 0xf; break;
+   }
+
+   code[loc + 1] &= ~(0x1f << 14);
+   code[loc + 1] |= enc << 14;
+}
+
 void
 CodeEmitterNV50::emitSET(const Instruction *i)
 {
@@ -1293,6 +1316,10 @@ CodeEmitterNV50::emitSET(const Instruction *i)
    if (i->src(1).mod.abs()) code[1] |= 0x00080000;
 
    emitForm_MAD(i);
+
+   if (i->subOp == 1) {
+      addInterp(0, 0, alphatestSet);
+   }
 }
 
 void
@@ -1633,7 +1660,9 @@ CodeEmitterNV50::emitTEX(const TexInstruction *i)
    code[1] |= (i->tex.mask & 0xc) << 12;
 
    if (i->tex.liveOnly)
-      code[1] |= 4;
+      code[1] |= 1 << 2;
+   if (i->tex.derivAll)
+      code[1] |= 1 << 3;
 
    defId(i->def(0), 2);
 
@@ -2110,7 +2139,7 @@ makeInstructionLong(Instruction *insn)
    insn->encSize = 8;
 
    for (int i = fn->bbCount - 1; i >= 0 && fn->bbArray[i] != insn->bb; --i) {
-      fn->bbArray[i]->binPos += 4;
+      fn->bbArray[i]->binPos += adj;
    }
    fn->binSize += adj;
    insn->bb->binSize += adj;
@@ -2162,9 +2191,16 @@ replaceExitWithModifier(Function *func)
             return;
       }
    }
-   epilogue->binSize -= 8;
-   func->binSize -= 8;
+
+   int adj = epilogue->getExit()->encSize;
+   epilogue->binSize -= adj;
+   func->binSize -= adj;
    delete_Instruction(func->getProgram(), epilogue->getExit());
+
+   // There may be BB's that are laid out after the exit block
+   for (int i = func->bbCount - 1; i >= 0 && func->bbArray[i] != epilogue; --i) {
+      func->bbArray[i]->binPos -= adj;
+   }
 }
 
 void