nv50,nvc0: add support for cube map arrays
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 7 Dec 2012 21:47:40 +0000 (22:47 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 7 Dec 2012 21:48:54 +0000 (22:48 +0100)
NOTE: nv50 support not enabled, someone with nva3/8 please fix.

16 files changed:
src/gallium/drivers/nv50/codegen/nv50_ir.h
src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_inlines.h
src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_target.cpp
src/gallium/drivers/nv50/nv50_blit.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nvc0/codegen/nv50_ir_emit_gk110.cpp
src/gallium/drivers/nvc0/codegen/nv50_ir_emit_nvc0.cpp
src/gallium/drivers/nvc0/nvc0_screen.c
src/gallium/drivers/nvc0/nvc0_tex.c

index 0b47c32527f3f345ae9a0d93e8a952737741f69c..b951b9d8da7b99ab7404541e5c1869e77afa392c 100644 (file)
@@ -124,7 +124,7 @@ enum operation
    OP_DFDY,
    OP_RDSV, // read system value
    OP_WRSV, // write system value
-   OP_PIXLD,
+   OP_TEXPREP, // turn cube map array into 2d array coordinates, TODO: move
    OP_QUADOP,
    OP_QUADON,
    OP_QUADPOP,
@@ -750,6 +750,7 @@ public:
       Target& operator=(TexTarget targ)
       {
          assert(targ < TEX_TARGET_COUNT);
+         target = targ;
          return *this;
       }
 
index f713e6391c6325ed00a89148541607186da0409e..322d6b9d34b09daf1e509d1d550374bd694f83d4 100644 (file)
@@ -254,6 +254,7 @@ BuildUtil::mkTex(operation op, TexTarget targ, uint8_t tic, uint8_t tsc,
 
    tex->setTexture(targ, tic, tsc);
 
+   insert(tex);
    return tex;
 }
 
index 90ec9d0c74bd941c0671ae813e8ba3f2d7f4fa02..2ba87f30971c3b25dba66e2902a680a0ca389165 100644 (file)
@@ -116,6 +116,7 @@ private:
 
    void emitTEX(const TexInstruction *);
    void emitTXQ(const TexInstruction *);
+   void emitTEXPREP(const TexInstruction *);
 
    void emitQUADOP(const Instruction *, uint8_t lane, uint8_t quOp);
 
@@ -1429,6 +1430,19 @@ CodeEmitterNV50::emitTXQ(const TexInstruction *i)
    emitFlagsRd(i);
 }
 
+void
+CodeEmitterNV50::emitTEXPREP(const TexInstruction *i)
+{
+   code[0] = 0xf8000001 | (3 << 22) | (i->tex.s << 17) | (i->tex.r << 9);
+   code[1] = 0x60010000;
+
+   code[0] |= (i->tex.mask & 0x3) << 25;
+   code[1] |= (i->tex.mask & 0xc) << 12;
+   defId(i->def(0), 2);
+
+   emitFlagsRd(i);
+}
+
 void
 CodeEmitterNV50::emitPRERETEmu(const FlowInstruction *i)
 {
@@ -1652,6 +1666,9 @@ CodeEmitterNV50::emitInstruction(Instruction *insn)
    case OP_TXQ:
       emitTXQ(insn->asTex());
       break;
+   case OP_TEXPREP:
+      emitTEXPREP(insn->asTex());
+      break;
    case OP_EMIT:
    case OP_RESTART:
       emitOUT(insn);
index e73c80478777f843aa1c8cd2703bae10195cfbfe..cf483d0deb97f257dcccf4375ebb3f1de3062bcc 100644 (file)
@@ -237,6 +237,10 @@ unsigned int Instruction::srcMask(unsigned int s) const
       return 0x1;
    case TGSI_OPCODE_LIT:
       return 0xb;
+   case TGSI_OPCODE_TEX2:
+   case TGSI_OPCODE_TXB2:
+   case TGSI_OPCODE_TXL2:
+      return (s == 0) ? 0xf : 0x3;
    case TGSI_OPCODE_TEX:
    case TGSI_OPCODE_TXB:
    case TGSI_OPCODE_TXD:
@@ -264,6 +268,12 @@ unsigned int Instruction::srcMask(unsigned int s) const
       case TGSI_TEXTURE_RECT:
          mask &= 0xb;
          break;
+      case TGSI_TEXTURE_CUBE_ARRAY:
+      case TGSI_TEXTURE_SHADOW2D_ARRAY:
+      case TGSI_TEXTURE_SHADOWCUBE:
+      case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
+         mask |= 0x8;
+         break;
       default:
          break;
       }
@@ -343,12 +353,14 @@ static nv50_ir::TexTarget translateTexture(uint tex)
    NV50_IR_TEX_TARG_CASE(RECT, RECT);
    NV50_IR_TEX_TARG_CASE(1D_ARRAY, 1D_ARRAY);
    NV50_IR_TEX_TARG_CASE(2D_ARRAY, 2D_ARRAY);
+   NV50_IR_TEX_TARG_CASE(CUBE_ARRAY, CUBE_ARRAY);
    NV50_IR_TEX_TARG_CASE(SHADOW1D, 1D_SHADOW);
    NV50_IR_TEX_TARG_CASE(SHADOW2D, 2D_SHADOW);
-   NV50_IR_TEX_TARG_CASE(SHADOW1D_ARRAY, 1D_ARRAY_SHADOW);
-   NV50_IR_TEX_TARG_CASE(SHADOW2D_ARRAY, 2D_ARRAY_SHADOW);
    NV50_IR_TEX_TARG_CASE(SHADOWCUBE, CUBE_SHADOW);
    NV50_IR_TEX_TARG_CASE(SHADOWRECT, RECT_SHADOW);
+   NV50_IR_TEX_TARG_CASE(SHADOW1D_ARRAY, 1D_ARRAY_SHADOW);
+   NV50_IR_TEX_TARG_CASE(SHADOW2D_ARRAY, 2D_ARRAY_SHADOW);
+   NV50_IR_TEX_TARG_CASE(SHADOWCUBE_ARRAY, CUBE_ARRAY_SHADOW);
    NV50_IR_TEX_TARG_CASE(BUFFER, BUFFER);
 
    case TGSI_TEXTURE_UNKNOWN:
@@ -553,6 +565,10 @@ static nv50_ir::operation translateOpcode(uint opcode)
    NV50_IR_OPCODE_CASE(GATHER4, TXG);
    NV50_IR_OPCODE_CASE(SVIEWINFO, TXQ);
 
+   NV50_IR_OPCODE_CASE(TEX2, TEX);
+   NV50_IR_OPCODE_CASE(TXB2, TXB);
+   NV50_IR_OPCODE_CASE(TXL2, TXL);
+
    NV50_IR_OPCODE_CASE(END, EXIT);
 
    default:
@@ -2034,6 +2050,13 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
    case TGSI_OPCODE_TXD:
       handleTEX(dst0, 3, 3, 0x03, 0x0f, 0x10, 0x20);
       break;
+   case TGSI_OPCODE_TEX2:
+      handleTEX(dst0, 2, 2, 0x03, 0x10, 0x00, 0x00);
+      break;
+   case TGSI_OPCODE_TXB2:
+   case TGSI_OPCODE_TXL2:
+      handleTEX(dst0, 2, 2, 0x10, 0x11, 0x00, 0x00);
+      break;
    case TGSI_OPCODE_SAMPLE:
    case TGSI_OPCODE_SAMPLE_B:
    case TGSI_OPCODE_SAMPLE_D:
index 55a3332c7274cfbe6f2bbeefef96f6dada5ca1e4..40241b18d1c1b6ae57ad1174b5e7b9fcf8dc582f 100644 (file)
@@ -43,7 +43,7 @@ static inline bool isMemoryFile(DataFile f)
 // contrary to asTex(), this will never include SULD/SUST
 static inline bool isTextureOp(operation op)
 {
-   return (op >= OP_TEX && op <= OP_TEXCSAA);
+   return (op >= OP_TEX && op <= OP_TEXCSAA) || (op == OP_TEXPREP);
 }
 
 static inline unsigned int typeSizeof(DataType ty)
@@ -304,7 +304,7 @@ const FlowInstruction *Instruction::asFlow() const
 
 TexInstruction *Instruction::asTex()
 {
-   if (op >= OP_TEX && op <= OP_TEXCSAA)
+   if ((op >= OP_TEX && op <= OP_TEXCSAA) || (op == OP_TEXPREP))
       return static_cast<TexInstruction *>(this);
    return NULL;
 }
index 3e0dc755d5671d62a3627370f9cf6e2516aebadc..db1306151ead61a417c2fa5ff02025d359bbdb2b 100644 (file)
@@ -573,7 +573,6 @@ NV50LoweringPreSSA::visit(Function *f)
    return true;
 }
 
-// move array source to first slot, convert to u16, add indirections
 bool
 NV50LoweringPreSSA::handleTEX(TexInstruction *i)
 {
@@ -595,24 +594,26 @@ NV50LoweringPreSSA::handleTEX(TexInstruction *i)
       i->setSrc(arg - 1, src);
 
       if (i->tex.target.isCube()) {
-         // Value *face = layer;
-         Value *x, *y;
-         x = new_LValue(func, FILE_GPR);
-         y = new_LValue(func, FILE_GPR);
-         layer = new_LValue(func, FILE_GPR);
-
-         i->tex.target = TEX_TARGET_2D_ARRAY;
-
-         // TODO: use TEXPREP to convert x,y,z,face -> x,y,layer
-         bld.mkMov(x, i->getSrc(0));
-         bld.mkMov(y, i->getSrc(1));
-         bld.mkMov(layer, i->getSrc(3));
-
-         i->setSrc(0, x);
-         i->setSrc(1, y);
-         i->setSrc(2, layer);
-         i->setSrc(3, i->getSrc(4));
-         i->setSrc(4, NULL);
+         Value *acube[4], *a2d[4];
+         int c;
+
+         for (c = 0; c < 4; ++c)
+            acube[c] = i->getSrc(c);
+         for (c = 0; c < 3; ++c)
+            a2d[c] = new_LValue(func, FILE_GPR);
+         a2d[3] = NULL;
+
+         bld.mkTex(OP_TEXPREP, TEX_TARGET_CUBE_ARRAY, i->tex.r, i->tex.s,
+                   a2d, acube)->asTex()->tex.mask = 0x7;
+
+         for (c = 0; c < 3; ++c)
+            i->setSrc(c, a2d[c]);
+         i->setSrc(c, NULL);
+         for (; i->srcExists(c + 1); ++c)
+            i->setSrc(c, i->getSrc(c + 1));
+
+         i->tex.target = i->tex.target.isShadow() ?
+            TEX_TARGET_2D_ARRAY_SHADOW : TEX_TARGET_2D_ARRAY;
       }
    }
 
index ded4f61e728fd748a310d76bd91024468f8b7fb0..d27a10c2b235167179e76170a0b986b59d7b3f01 100644 (file)
@@ -174,7 +174,7 @@ const char *operationStr[OP_LAST + 1] =
    "dfdy",
    "rdsv",
    "wrsv",
-   "pixld",
+   "texprep",
    "quadop",
    "quadon",
    "quadpop",
index 707c9e8d2193a774f6b5c7f77ab1a470d66c5599..be6a276ac9b82d6d27bb7141c7521f944870c0d9 100644 (file)
@@ -47,7 +47,7 @@ const uint8_t Target::operationSrcNr[OP_LAST + 1] =
    1, 1, 1, 1, 1,          // TXF, TXQ, TXD, TXG, TEXCSAA
    1, 2,                   // SULD, SUST
    1, 1,                   // DFDX, DFDY
-   1, 2, 2, 2, 0, 0,       // RDSV, WRSV, PIXLD, QUADOP, QUADON, QUADPOP
+   1, 2, 2, 2, 0, 0,       // RDSV, WRSV, TEXPREP, QUADOP, QUADON, QUADPOP
    2, 3, 2, 0,             // POPCNT, INSBF, EXTBF, TEXBAR
    0
 };
@@ -101,7 +101,7 @@ const OpClass Target::operationClass[OP_LAST + 1] =
    OPCLASS_TEXTURE, OPCLASS_TEXTURE, OPCLASS_TEXTURE, OPCLASS_TEXTURE,
    // SULD, SUST
    OPCLASS_SURFACE, OPCLASS_SURFACE,
-   // DFDX, DFDY, RDSV, WRSV; PIXLD, QUADOP, QUADON, QUADPOP
+   // DFDX, DFDY, RDSV, WRSV; TEXPREP, QUADOP, QUADON, QUADPOP
    OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER,
    OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER, OPCLASS_OTHER,
    // POPCNT, INSBF, EXTBF
index 0a1c2ae6773e7502527aad70a747ccf81b0613c6..d409f21f615fb12c11f75f6e72fc808c7b8c246b 100644 (file)
@@ -72,6 +72,7 @@ nv50_blit_reinterpret_pipe_texture_target(enum pipe_texture_target target)
 {
    switch (target) {
    case PIPE_TEXTURE_CUBE:
+   case PIPE_TEXTURE_CUBE_ARRAY:
       return PIPE_TEXTURE_2D_ARRAY;
    case PIPE_TEXTURE_RECT:
       return PIPE_TEXTURE_2D;
index d0a0295746f5aef1b7830c102a3438663085305b..2d6d4d637340aa4f7bdbadb49bf12854333b7334 100644 (file)
@@ -111,6 +111,11 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return 0;
+   case PIPE_CAP_CUBE_MAP_ARRAY:
+      return 0;
+      /*
+      return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS;
+      */
    case PIPE_CAP_TWO_SIDED_STENCIL:
    case PIPE_CAP_DEPTH_CLIP_DISABLE:
    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
index 511ee8fdbec66d56542d6ffaceeca482d8f81649..d9722a86b296b7fde81eb42f9ab84ae56231d592 100644 (file)
@@ -959,6 +959,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
       y1 /= fv;
    }
 
+   /* XXX: multiply by 6 for cube arrays ? */
    dz = (float)info->src.box.depth / (float)info->dst.box.depth;
    z = (float)info->src.box.z;
    if (nv50_miptree(src)->layout_3d)
index 992ac4b760c4120b967caf1bd72f9a36730ac4f3..dfc97a242b24e0aba2e59589b469a20930054bc7 100644 (file)
@@ -176,10 +176,7 @@ nv50_create_texture_view(struct pipe_context *pipe,
       break;
    case PIPE_TEXTURE_CUBE:
       depth /= 6;
-      if (depth > 1)
-         tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
-      else
-         tic[2] |= NV50_TIC_2_TARGET_CUBE;
+      tic[2] |= NV50_TIC_2_TARGET_CUBE;
       break;
    case PIPE_TEXTURE_1D_ARRAY:
       tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
@@ -187,6 +184,10 @@ nv50_create_texture_view(struct pipe_context *pipe,
    case PIPE_TEXTURE_2D_ARRAY:
       tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
       break;
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      depth /= 6;
+      tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
+      break;
    case PIPE_BUFFER:
       assert(0); /* should be linear and handled above ! */
       tic[2] |= NV50_TIC_2_TARGET_BUFFER | NV50_TIC_2_LINEAR;
index 6c229fddf700c76f73cddbb178509c385cd5f94f..c771459d514725cffd44defd99ff377152cda49f 100644 (file)
@@ -110,7 +110,6 @@ private:
    void emitTEX(const TexInstruction *);
    void emitTEXCSAA(const TexInstruction *);
    void emitTXQ(const TexInstruction *);
-   void emitPIXLD(const TexInstruction *);
 
    void emitQUADOP(const Instruction *, uint8_t qOp, uint8_t laneMask);
 
index cd04f4cfb97d24f3196ad2bb79378646a9f454c4..92496a3b6d808a84e191545c9a9d8de631c3c86a 100644 (file)
@@ -110,7 +110,6 @@ private:
    void emitTEX(const TexInstruction *);
    void emitTEXCSAA(const TexInstruction *);
    void emitTXQ(const TexInstruction *);
-   void emitPIXLD(const TexInstruction *);
 
    void emitQUADOP(const Instruction *, uint8_t qOp, uint8_t laneMask);
 
index 3bf21913a89c8d149fbba2c44df2c3bcc61ff27f..08fc3b4114cb6012d91ead7c87965e81e96820b3 100644 (file)
@@ -88,6 +88,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_NPOT_TEXTURES:
    case PIPE_CAP_ANISOTROPIC_FILTER:
    case PIPE_CAP_SEAMLESS_CUBE_MAP:
+   case PIPE_CAP_CUBE_MAP_ARRAY:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
index b52918e1319f03e30b5591f433f9cccd90be3478..2bce97b32c7ce390d10625150f33bafee92e7ad3 100644 (file)
@@ -180,10 +180,7 @@ nvc0_create_texture_view(struct pipe_context *pipe,
       break;
    case PIPE_TEXTURE_CUBE:
       depth /= 6;
-      if (depth > 1)
-         tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
-      else
-         tic[2] |= NV50_TIC_2_TARGET_CUBE;
+      tic[2] |= NV50_TIC_2_TARGET_CUBE;
       break;
    case PIPE_TEXTURE_1D_ARRAY:
       tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
@@ -192,6 +189,10 @@ nvc0_create_texture_view(struct pipe_context *pipe,
    case PIPE_TEXTURE_2D_ARRAY:
       tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
       break;
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      depth /= 6;
+      tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
+      break;
    default:
       NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target);
       return FALSE;