diff options
author | Ilia Mirkin <[email protected]> | 2014-01-12 03:32:30 -0500 |
---|---|---|
committer | Maarten Lankhorst <[email protected]> | 2014-01-27 16:40:43 +0100 |
commit | 3bd40073b9803baf62f77ed5ac79979e037d2ed6 (patch) | |
tree | 47b7b3e62a7455bdcb23986b597811f1c8e1f999 /src/gallium/drivers/nouveau/codegen | |
parent | a6cf950ba27236f8270a99288272628cf2cf00c5 (diff) |
nv50: add support for texelFetch'ing MS textures, ARB_texture_multisample
Creates two areas in the AUX constbuf:
- Sample offsets for MS textures
- Per-texture MS settings
When executing a texelFetch with a MS sampler, looks up that texture's
settings and adjusts the parameters given to the texfetch instruction.
With this change, all the ARB_texture_multisample piglits pass, so turn
on PIPE_CAP_TEXTURE_MULTISAMPLE.
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen')
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp | 60 |
3 files changed, 69 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h index 6a001d3ad14..857980d8279 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h @@ -827,6 +827,14 @@ public: int isShadow() const { return descTable[target].shadow ? 1 : 0; } int isMS() const { return target == TEX_TARGET_2D_MS || target == TEX_TARGET_2D_MS_ARRAY; } + void clearMS() { + if (isMS()) { + if (isArray()) + target = TEX_TARGET_2D_ARRAY; + else + target = TEX_TARGET_2D; + } + } Target& operator=(TexTarget targ) { diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp index c73508c67c1..bef103ff00f 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp @@ -1232,6 +1232,7 @@ CodeEmitterNV50::emitCVT(const Instruction *i) case TYPE_S32: code[1] = 0x44014000; break; case TYPE_U32: code[1] = 0x44004000; break; case TYPE_F16: code[1] = 0xc4000000; break; + case TYPE_U16: code[1] = 0x44000000; break; default: assert(0); break; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp index 1d13aea98b1..984a8ca17b3 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp @@ -549,6 +549,8 @@ private: bool handleCONT(Instruction *); void checkPredicate(Instruction *); + void loadTexMsInfo(uint32_t off, Value **ms, Value **ms_x, Value **ms_y); + void loadMsInfo(Value *ms, Value *s, Value **dx, Value **dy); private: const Target *const targ; @@ -582,6 +584,41 @@ NV50LoweringPreSSA::visit(Function *f) return true; } +void NV50LoweringPreSSA::loadTexMsInfo(uint32_t off, Value **ms, + Value **ms_x, Value **ms_y) { + // This loads the texture-indexed ms setting from the constant buffer + Value *tmp = new_LValue(func, FILE_GPR); + uint8_t b = prog->driver->io.resInfoCBSlot; + off += prog->driver->io.suInfoBase; + *ms_x = bld.mkLoadv(TYPE_U32, bld.mkSymbol( + FILE_MEMORY_CONST, b, TYPE_U32, off + 0), NULL); + *ms_y = bld.mkLoadv(TYPE_U32, bld.mkSymbol( + FILE_MEMORY_CONST, b, TYPE_U32, off + 4), NULL); + *ms = bld.mkOp2v(OP_ADD, TYPE_U32, tmp, *ms_x, *ms_y); +} + +void NV50LoweringPreSSA::loadMsInfo(Value *ms, Value *s, Value **dx, Value **dy) { + // Given a MS level, and a sample id, compute the delta x/y + uint8_t b = prog->driver->io.msInfoCBSlot; + Value *off = new_LValue(func, FILE_ADDRESS), *t = new_LValue(func, FILE_GPR); + + // The required information is at mslevel * 16 * 4 + sample * 8 + // = (mslevel * 8 + sample) * 8 + bld.mkOp2(OP_SHL, + TYPE_U32, + off, + bld.mkOp2v(OP_ADD, TYPE_U32, t, + bld.mkOp2v(OP_SHL, TYPE_U32, t, ms, bld.mkImm(3)), + s), + bld.mkImm(3)); + *dx = bld.mkLoadv(TYPE_U32, bld.mkSymbol( + FILE_MEMORY_CONST, b, TYPE_U32, + prog->driver->io.msInfoBase), off); + *dy = bld.mkLoadv(TYPE_U32, bld.mkSymbol( + FILE_MEMORY_CONST, b, TYPE_U32, + prog->driver->io.msInfoBase + 4), off); +} + bool NV50LoweringPreSSA::handleTEX(TexInstruction *i) { @@ -589,6 +626,29 @@ NV50LoweringPreSSA::handleTEX(TexInstruction *i) const int dref = arg; const int lod = i->tex.target.isShadow() ? (arg + 1) : arg; + // handle MS, which means looking up the MS params for this texture, and + // adjusting the input coordinates to point at the right sample. + if (i->tex.target.isMS()) { + Value *x = i->getSrc(0); + Value *y = i->getSrc(1); + Value *s = i->getSrc(arg - 1); + Value *tx = new_LValue(func, FILE_GPR), *ty = new_LValue(func, FILE_GPR), + *ms, *ms_x, *ms_y, *dx, *dy; + + i->tex.target.clearMS(); + + loadTexMsInfo(i->tex.r * 4 * 2, &ms, &ms_x, &ms_y); + loadMsInfo(ms, s, &dx, &dy); + + bld.mkOp2(OP_SHL, TYPE_U32, tx, x, ms_x); + bld.mkOp2(OP_SHL, TYPE_U32, ty, y, ms_y); + bld.mkOp2(OP_ADD, TYPE_U32, tx, tx, dx); + bld.mkOp2(OP_ADD, TYPE_U32, ty, ty, dy); + i->setSrc(0, tx); + i->setSrc(1, ty); + i->setSrc(arg - 1, bld.loadImm(NULL, 0)); + } + // dref comes before bias/lod if (i->tex.target.isShadow()) if (i->op == OP_TXB || i->op == OP_TXL) |