NOTE: nv50 support not enabled, someone with nva3/8 please fix.
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,
Target& operator=(TexTarget targ)
{
assert(targ < TEX_TARGET_COUNT);
+ target = targ;
return *this;
}
tex->setTexture(targ, tic, tsc);
+ insert(tex);
return tex;
}
void emitTEX(const TexInstruction *);
void emitTXQ(const TexInstruction *);
+ void emitTEXPREP(const TexInstruction *);
void emitQUADOP(const Instruction *, uint8_t lane, uint8_t quOp);
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)
{
case OP_TXQ:
emitTXQ(insn->asTex());
break;
+ case OP_TEXPREP:
+ emitTEXPREP(insn->asTex());
+ break;
case OP_EMIT:
case OP_RESTART:
emitOUT(insn);
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:
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;
}
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:
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:
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:
// 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)
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;
}
return true;
}
-// move array source to first slot, convert to u16, add indirections
bool
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;
}
}
"dfdy",
"rdsv",
"wrsv",
- "pixld",
+ "texprep",
"quadop",
"quadon",
"quadpop",
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
};
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
{
switch (target) {
case PIPE_TEXTURE_CUBE:
+ case PIPE_TEXTURE_CUBE_ARRAY:
return PIPE_TEXTURE_2D_ARRAY;
case PIPE_TEXTURE_RECT:
return PIPE_TEXTURE_2D;
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:
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)
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;
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;
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);
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);
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;
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;
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;