summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/codegen
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2014-01-12 03:32:30 -0500
committerMaarten Lankhorst <[email protected]>2014-01-27 16:40:43 +0100
commit3bd40073b9803baf62f77ed5ac79979e037d2ed6 (patch)
tree47b7b3e62a7455bdcb23986b597811f1c8e1f999 /src/gallium/drivers/nouveau/codegen
parenta6cf950ba27236f8270a99288272628cf2cf00c5 (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.h8
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp1
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp60
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)