nv50/ir: add support for TXQS tgsi opcode
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 11 Sep 2015 02:07:27 +0000 (22:07 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sun, 13 Sep 2015 22:24:44 +0000 (18:24 -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_from_tgsi.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp
src/gallium/drivers/nouveau/nv50/nv50_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c

index ba1b0851927150bf0ea17e696aaa1c4313ffa740..f6e93081e76cd60006c9e5385953004555d93dba 100644 (file)
@@ -824,8 +824,8 @@ private:
 
 enum TexQuery
 {
-   TXQ_DIMS,
-   TXQ_TYPE,
+   TXQ_DIMS, /* x, y, z, levels */
+   TXQ_TYPE, /* ?, ?, samples, ? */
    TXQ_SAMPLE_POSITION,
    TXQ_FILTER,
    TXQ_LOD,
index f153674e9ce43ae52b6b08e40a83ef365b19db93..c8efaf5947a84c692d65b0e0596a6acafa09ae39 100644 (file)
@@ -631,6 +631,7 @@ static nv50_ir::operation translateOpcode(uint opcode)
    NV50_IR_OPCODE_CASE(SAD, SAD);
    NV50_IR_OPCODE_CASE(TXF, TXF);
    NV50_IR_OPCODE_CASE(TXQ, TXQ);
+   NV50_IR_OPCODE_CASE(TXQS, TXQ);
    NV50_IR_OPCODE_CASE(TG4, TXG);
    NV50_IR_OPCODE_CASE(LODQ, TXLQ);
 
@@ -1324,7 +1325,7 @@ private:
    void setTexRS(TexInstruction *, unsigned int& s, int R, int S);
    void handleTEX(Value *dst0[4], int R, int S, int L, int C, int Dx, int Dy);
    void handleTXF(Value *dst0[4], int R, int L_M);
-   void handleTXQ(Value *dst0[4], enum TexQuery);
+   void handleTXQ(Value *dst0[4], enum TexQuery, int R);
    void handleLIT(Value *dst0[4]);
    void handleUserClipPlanes();
 
@@ -1795,7 +1796,7 @@ Converter::setTexRS(TexInstruction *tex, unsigned int& s, int R, int S)
 }
 
 void
-Converter::handleTXQ(Value *dst0[4], enum TexQuery query)
+Converter::handleTXQ(Value *dst0[4], enum TexQuery query, int R)
 {
    TexInstruction *tex = new_TexInstruction(func, OP_TXQ);
    tex->tex.query = query;
@@ -1807,9 +1808,12 @@ Converter::handleTXQ(Value *dst0[4], enum TexQuery query)
       tex->tex.mask |= 1 << c;
       tex->setDef(d++, dst0[c]);
    }
-   tex->setSrc((c = 0), fetchSrc(0, 0)); // mip level
+   if (query == TXQ_DIMS)
+      tex->setSrc((c = 0), fetchSrc(0, 0)); // mip level
+   else
+      tex->setSrc((c = 0), zero);
 
-   setTexRS(tex, ++c, 1, -1);
+   setTexRS(tex, ++c, R, -1);
 
    bb->insertTail(tex);
 }
@@ -2764,7 +2768,15 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
       break;
    case TGSI_OPCODE_TXQ:
    case TGSI_OPCODE_SVIEWINFO:
-      handleTXQ(dst0, TXQ_DIMS);
+      handleTXQ(dst0, TXQ_DIMS, 1);
+      break;
+   case TGSI_OPCODE_TXQS:
+      // The TXQ_TYPE query returns samples in its 3rd arg, but we need it to
+      // be in .x
+      dst0[1] = dst0[2] = dst0[3] = NULL;
+      std::swap(dst0[0], dst0[2]);
+      handleTXQ(dst0, TXQ_TYPE, 0);
+      std::swap(dst0[0], dst0[2]);
       break;
    case TGSI_OPCODE_F2I:
    case TGSI_OPCODE_F2U:
index d87cdfff851e8c71389194cb6c76b025a29514e9..eec502be79862bcc6d997706ee155ef27f5775e9 100644 (file)
@@ -617,6 +617,7 @@ private:
    bool handleTXL(TexInstruction *); // hate
    bool handleTXD(TexInstruction *); // these 3
    bool handleTXLQ(TexInstruction *);
+   bool handleTXQ(TexInstruction *);
 
    bool handleCALL(Instruction *);
    bool handlePRECONT(Instruction *);
@@ -974,6 +975,23 @@ NV50LoweringPreSSA::handleTXLQ(TexInstruction *i)
    return true;
 }
 
+bool
+NV50LoweringPreSSA::handleTXQ(TexInstruction *i)
+{
+   Value *ms, *ms_x, *ms_y;
+   if (i->tex.query == TXQ_DIMS)
+      return true;
+   assert(i->tex.query == TXQ_TYPE);
+   assert(i->tex.mask == 4);
+
+   loadTexMsInfo(i->tex.r * 4 * 2, &ms, &ms_x, &ms_y);
+   bld.mkOp2(OP_SHL, TYPE_U32, i->getDef(0), bld.loadImm(NULL, 1), ms);
+   i->bb->remove(i);
+
+   return true;
+}
+
+
 bool
 NV50LoweringPreSSA::handleSET(Instruction *i)
 {
@@ -1333,6 +1351,8 @@ NV50LoweringPreSSA::visit(Instruction *i)
       return handleTXD(i->asTex());
    case OP_TXLQ:
       return handleTXLQ(i->asTex());
+   case OP_TXQ:
+      return handleTXQ(i->asTex());
    case OP_EX2:
       bld.mkOp1(OP_PREEX2, TYPE_F32, i->getDef(0), i->getSrc(0));
       i->setSrc(0, i->getDef(0));
index 6b7f25085fe85d77fd68f3f1cd2c94c5f5850581..9068ae1afaf1ae73de317a5259d97ae7c004f2df 100644 (file)
@@ -179,6 +179,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
    case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
    case PIPE_CAP_DEPTH_BOUNDS_TEST:
+   case PIPE_CAP_TGSI_TXQS:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP:
       return 1; /* class_3d >= NVA0_3D_CLASS; */
@@ -214,7 +215,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
    case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
    case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
-   case PIPE_CAP_TGSI_TXQS:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index 220c2aab9deba6413800bdd082078bb2e20234e8..ead43f862629c39da960b7c5637334fac6a81b0c 100644 (file)
@@ -178,6 +178,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
    case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
    case PIPE_CAP_DEPTH_BOUNDS_TEST:
+   case PIPE_CAP_TGSI_TXQS:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
@@ -200,7 +201,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_VERTEXID_NOBASE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
    case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
-   case PIPE_CAP_TGSI_TXQS:
       return 0;
 
    case PIPE_CAP_VENDOR_ID: