From f7599b2c32185535b4c215de0ba0454129fa523f Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 7 Dec 2012 22:47:40 +0100 Subject: [PATCH] nv50,nvc0: add support for cube map arrays NOTE: nv50 support not enabled, someone with nva3/8 please fix. --- src/gallium/drivers/nv50/codegen/nv50_ir.h | 3 +- .../nv50/codegen/nv50_ir_build_util.cpp | 1 + .../nv50/codegen/nv50_ir_emit_nv50.cpp | 17 ++++++++ .../nv50/codegen/nv50_ir_from_tgsi.cpp | 27 ++++++++++++- .../drivers/nv50/codegen/nv50_ir_inlines.h | 4 +- .../nv50/codegen/nv50_ir_lowering_nv50.cpp | 39 ++++++++++--------- .../drivers/nv50/codegen/nv50_ir_print.cpp | 2 +- .../drivers/nv50/codegen/nv50_ir_target.cpp | 4 +- src/gallium/drivers/nv50/nv50_blit.h | 1 + src/gallium/drivers/nv50/nv50_screen.c | 5 +++ src/gallium/drivers/nv50/nv50_surface.c | 1 + src/gallium/drivers/nv50/nv50_tex.c | 9 +++-- .../nvc0/codegen/nv50_ir_emit_gk110.cpp | 1 - .../nvc0/codegen/nv50_ir_emit_nvc0.cpp | 1 - src/gallium/drivers/nvc0/nvc0_screen.c | 1 + src/gallium/drivers/nvc0/nvc0_tex.c | 9 +++-- 16 files changed, 88 insertions(+), 37 deletions(-) diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir.h b/src/gallium/drivers/nv50/codegen/nv50_ir.h index 0b47c32527f..b951b9d8da7 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir.h +++ b/src/gallium/drivers/nv50/codegen/nv50_ir.h @@ -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; } diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp index f713e6391c6..322d6b9d34b 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp @@ -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; } diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp index 90ec9d0c74b..2ba87f30971 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_emit_nv50.cpp @@ -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); diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp index e73c8047877..cf483d0deb9 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp @@ -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: diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_inlines.h b/src/gallium/drivers/nv50/codegen/nv50_ir_inlines.h index 55a3332c727..40241b18d1c 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_inlines.h +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_inlines.h @@ -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(this); return NULL; } diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp index 3e0dc755d56..db1306151ea 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp @@ -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; } } diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp index ded4f61e728..d27a10c2b23 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_print.cpp @@ -174,7 +174,7 @@ const char *operationStr[OP_LAST + 1] = "dfdy", "rdsv", "wrsv", - "pixld", + "texprep", "quadop", "quadon", "quadpop", diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_target.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_target.cpp index 707c9e8d219..be6a276ac9b 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_target.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_target.cpp @@ -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 diff --git a/src/gallium/drivers/nv50/nv50_blit.h b/src/gallium/drivers/nv50/nv50_blit.h index 0a1c2ae6773..d409f21f615 100644 --- a/src/gallium/drivers/nv50/nv50_blit.h +++ b/src/gallium/drivers/nv50/nv50_blit.h @@ -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; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index d0a0295746f..2d6d4d63734 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -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: diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 511ee8fdbec..d9722a86b29 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -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) diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 992ac4b760c..dfc97a242b2 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -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; diff --git a/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_gk110.cpp index 6c229fddf70..c771459d514 100644 --- a/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_gk110.cpp @@ -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); diff --git a/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_nvc0.cpp index cd04f4cfb97..92496a3b6d8 100644 --- a/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nvc0/codegen/nv50_ir_emit_nvc0.cpp @@ -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); diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 3bf21913a89..08fc3b4114c 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -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; diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c index b52918e1319..2bce97b32c7 100644 --- a/src/gallium/drivers/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nvc0/nvc0_tex.c @@ -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; -- 2.30.2