nv50: enable texture query lod
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 26 Feb 2014 04:13:19 +0000 (23:13 -0500)
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.h
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp
src/gallium/drivers/nouveau/nv50/nv50_screen.c

index 857980d8279a5da7ec243e835fae6be32ec0e13a..286ac834e75a6015742f87b856d6babbc16d2a31 100644 (file)
@@ -117,6 +117,7 @@ enum operation
    OP_TXQ, // texture size query
    OP_TXD, // texture derivatives
    OP_TXG, // texture gather
+   OP_TXLQ, // texture query lod
    OP_TEXCSAA, // texture op for coverage sampling
    OP_TEXPREP, // turn cube map array into 2d array coordinates
    OP_SULDB, // surface load (raw)
index e2f93bbf5e6e35c70e6cf9159a9f06980b5f438e..9eccd9f0ccd6544e56be41d4dacb7106df64889b 100644 (file)
@@ -1450,6 +1450,9 @@ CodeEmitterNV50::emitTEX(const TexInstruction *i)
       code[0] |= 0x01000000;
       code[1] = 0x80000000;
       break;
+   case OP_TXLQ:
+      code[1] = 0x60020000;
+      break;
    default:
       assert(i->op == OP_TEX);
       break;
@@ -1791,6 +1794,7 @@ CodeEmitterNV50::emitInstruction(Instruction *insn)
    case OP_TXL:
    case OP_TXF:
    case OP_TXG:
+   case OP_TXLQ:
       emitTEX(insn->asTex());
       break;
    case OP_TXQ:
index ccddb9a79fa9365ad4af5147691e20d4ae5cea93..90820eace7efab0fb5e9b85288089107e402242d 100644 (file)
@@ -255,6 +255,7 @@ unsigned int Instruction::srcMask(unsigned int s) const
    case TGSI_OPCODE_TXD:
    case TGSI_OPCODE_TXL:
    case TGSI_OPCODE_TXP:
+   case TGSI_OPCODE_LODQ:
    {
       const struct tgsi_instruction_texture *tex = &insn->Texture;
 
@@ -559,6 +560,7 @@ static nv50_ir::operation translateOpcode(uint opcode)
    NV50_IR_OPCODE_CASE(TXF, TXF);
    NV50_IR_OPCODE_CASE(TXQ, TXQ);
    NV50_IR_OPCODE_CASE(TG4, TXG);
+   NV50_IR_OPCODE_CASE(LODQ, TXLQ);
 
    NV50_IR_OPCODE_CASE(EMIT, EMIT);
    NV50_IR_OPCODE_CASE(ENDPRIM, RESTART);
@@ -2429,6 +2431,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
    case TGSI_OPCODE_TXB:
    case TGSI_OPCODE_TXL:
    case TGSI_OPCODE_TXP:
+   case TGSI_OPCODE_LODQ:
       //              R  S     L     C    Dx    Dy
       handleTEX(dst0, 1, 1, 0x03, 0x0f, 0x00, 0x00);
       break;
index 0908447e0563d818c8729912241c1bdb1abc5c6a..29f85cf70da927d1dd08d71a90fb6f9c42dd3954 100644 (file)
@@ -543,6 +543,7 @@ private:
    bool handleTXB(TexInstruction *); // I really
    bool handleTXL(TexInstruction *); // hate
    bool handleTXD(TexInstruction *); // these 3
+   bool handleTXLQ(TexInstruction *);
 
    bool handleCALL(Instruction *);
    bool handlePRECONT(Instruction *);
@@ -856,6 +857,26 @@ NV50LoweringPreSSA::handleTXD(TexInstruction *i)
    return true;
 }
 
+bool
+NV50LoweringPreSSA::handleTXLQ(TexInstruction *i)
+{
+   handleTEX(i);
+   bld.setPosition(i, true);
+
+   /* The returned values are not quite what we want:
+    * (a) convert from s32 to f32
+    * (b) multiply by 1/256
+    */
+   for (int def = 0; def < 2; ++def) {
+      if (!i->defExists(def))
+         continue;
+      bld.mkCvt(OP_CVT, TYPE_F32, i->getDef(def), TYPE_S32, i->getDef(def));
+      bld.mkOp2(OP_MUL, TYPE_F32, i->getDef(def),
+                i->getDef(def), bld.loadImm(NULL, 1.0f / 256));
+   }
+   return true;
+}
+
 bool
 NV50LoweringPreSSA::handleSET(Instruction *i)
 {
@@ -1197,6 +1218,8 @@ NV50LoweringPreSSA::visit(Instruction *i)
       return handleTXL(i->asTex());
    case OP_TXD:
       return handleTXD(i->asTex());
+   case OP_TXLQ:
+      return handleTXLQ(i->asTex());
    case OP_EX2:
       bld.mkOp1(OP_PREEX2, TYPE_F32, i->getDef(0), i->getSrc(0));
       i->setSrc(0, i->getDef(0));
index ae42d03d596be2f64c9b9f4ee2070caed60c9f8d..4093bc0389372baf5a5077d056e9ab0160ea244f 100644 (file)
@@ -147,6 +147,7 @@ const char *operationStr[OP_LAST + 1] =
    "texquery",
    "texgrad",
    "texgather",
+   "texquerylod",
    "texcsaa",
    "texprep",
    "suldb",
index d706508c52e9e211ee55318b5f6155c2eb4b4783..d02806ade19e21c511d9f0c3b111ab0c400131ea 100644 (file)
@@ -196,12 +196,13 @@ nv50_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 NV50_MAX_VIEWPORTS;
    case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
       return (class_3d >= NVA3_3D_CLASS) ? 4 : 0;
+   case PIPE_CAP_TEXTURE_QUERY_LOD:
+      return class_3d >= NVA3_3D_CLASS;
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
       return 0;