nvc0: enable texture query lod
authorIlia Mirkin <imirkin@alum.mit.edu>
Thu, 3 Apr 2014 13:43:40 +0000 (09:43 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Mon, 7 Apr 2014 05:06:18 +0000 (01:06 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c

index 584ae4c587e7840267915ef5b8bd0712d9bc7125..b716d5457be9f94c4d726741bcd786e2a9d071b3 100644 (file)
@@ -978,6 +978,9 @@ CodeEmitterGK110::emitTEX(const TexInstruction *i)
       case OP_TXD:
          code[1] = 0x7e000000;
          break;
+      case OP_TXLQ:
+         code[1] = 0x7e800000;
+         break;
       case OP_TXF:
          code[1] = 0x78000000;
          break;
@@ -992,6 +995,11 @@ CodeEmitterGK110::emitTEX(const TexInstruction *i)
          code[1] = 0x76000000;
          code[1] |= i->tex.r << 9;
          break;
+      case OP_TXLQ:
+         code[0] = 0x00000002;
+         code[1] = 0x76800000;
+         code[1] |= i->tex.r << 9;
+         break;
       case OP_TXF:
          code[0] = 0x00000002;
          code[1] = 0x70000000;
@@ -1017,6 +1025,7 @@ CodeEmitterGK110::emitTEX(const TexInstruction *i)
    case OP_TXF: break;
    case OP_TXG: break; // XXX
    case OP_TXD: break;
+   case OP_TXLQ: break;
    default:
       assert(!"invalid texture op");
       break;
@@ -1657,6 +1666,7 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
    case OP_TXL:
    case OP_TXD:
    case OP_TXF:
+   case OP_TXLQ:
       emitTEX(insn->asTex());
       break;
    case OP_TXQ:
index f15ca1b057d759b0eb283a6be16475fffe4edbaf..1f624a50bb385685560fff50c813a8fcce22f1b3 100644 (file)
@@ -1138,6 +1138,7 @@ CodeEmitterNVC0::emitTEX(const TexInstruction *i)
    case OP_TXL: code[1] = 0x86000000; break;
    case OP_TXF: code[1] = 0x90000000; break;
    case OP_TXG: code[1] = 0xa0000000; break;
+   case OP_TXLQ: code[1] = 0xb0000000; break;
    case OP_TXD: code[1] = 0xe0000000; break;
    default:
       assert(!"invalid texture op");
@@ -2302,6 +2303,7 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
    case OP_TXL:
    case OP_TXD:
    case OP_TXF:
+   case OP_TXLQ:
       emitTEX(insn->asTex());
       break;
    case OP_TXQ:
index c0d14750ac14c1f720d59c24fb42325ffa079f86..382b02da50dc5bdc2b1efcb275eea5c298727a19 100644 (file)
@@ -598,6 +598,7 @@ private:
    bool handleTXD(TexInstruction *);
    bool handleTXQ(TexInstruction *);
    bool handleManualTXD(TexInstruction *);
+   bool handleTXLQ(TexInstruction *);
    bool handleATOM(Instruction *);
    bool handleCasExch(Instruction *, bool needCctl);
    void handleSurfaceOpNVE4(TexInstruction *);
@@ -859,6 +860,44 @@ NVC0LoweringPass::handleTXQ(TexInstruction *txq)
    return true;
 }
 
+bool
+NVC0LoweringPass::handleTXLQ(TexInstruction *i)
+{
+   /* The outputs are inverted compared to what the TGSI instruction
+    * expects. Take that into account in the mask.
+    */
+   assert((i->tex.mask & ~3) == 0);
+   if (i->tex.mask == 1)
+      i->tex.mask = 2;
+   else if (i->tex.mask == 2)
+      i->tex.mask = 1;
+   handleTEX(i);
+   bld.setPosition(i, true);
+
+   /* The returned values are not quite what we want:
+    * (a) convert from s16/u16 to f32
+    * (b) multiply by 1/256
+    */
+   for (int def = 0; def < 2; ++def) {
+      if (!i->defExists(def))
+         continue;
+      enum DataType type = TYPE_S16;
+      if (i->tex.mask == 2 || def > 0)
+         type = TYPE_U16;
+      bld.mkCvt(OP_CVT, TYPE_F32, i->getDef(def), type, i->getDef(def));
+      bld.mkOp2(OP_MUL, TYPE_F32, i->getDef(def),
+                i->getDef(def), bld.loadImm(NULL, 1.0f / 256));
+   }
+   if (i->tex.mask == 3) {
+      LValue *t = new_LValue(func, FILE_GPR);
+      bld.mkMov(t, i->getDef(0));
+      bld.mkMov(i->getDef(0), i->getDef(1));
+      bld.mkMov(i->getDef(1), t);
+   }
+   return true;
+}
+
+
 bool
 NVC0LoweringPass::handleATOM(Instruction *atom)
 {
@@ -1528,6 +1567,8 @@ NVC0LoweringPass::visit(Instruction *i)
       return handleTEX(i->asTex());
    case OP_TXD:
       return handleTXD(i->asTex());
+   case OP_TXLQ:
+      return handleTXLQ(i->asTex());
    case OP_TXQ:
      return handleTXQ(i->asTex());
    case OP_EX2:
index 794ed3b5a70886cc53095f1a92cf8f8eaa938484..fa3145eacde63e09ca684a181536e5415e5d5d8a 100644 (file)
@@ -178,10 +178,11 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_GATHER_SM5:
    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
    case PIPE_CAP_FAKE_SW_MSAA:
-   case PIPE_CAP_TEXTURE_QUERY_LOD:
       return 0;
    case PIPE_CAP_MAX_VIEWPORTS:
       return 1;
+   case PIPE_CAP_TEXTURE_QUERY_LOD:
+      return 1;
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
       return 0;