summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2017-01-02 00:48:51 -0500
committerIlia Mirkin <imirkin@alum.mit.edu>2017-01-16 21:13:09 -0500
commit5ba380c226b127cbfad00dd647471e1518ba2cb2 (patch)
tree6c00e7e1945ab525057bc915ddcf409a8dd0e32e /src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
parent6b7511c2f123014fe469a11d0b46fbff357335e4 (diff)
nvc0: enable FBFETCH with a special slot for color buffer 0
We don't need to support all the color buffers for advanced blend, just cb0. For Fermi, we use the special binding slots so that we don't overlap with user textures, while Kepler+ gets a dedicated position for the fb handle in the driver constbuf. This logic is only triggered when a FBFETCH is actually present so it should be a no-op most of the time. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index 6b38d5f0fa9..64bfd084326 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -1459,6 +1459,9 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
if (insn.getOpcode() == TGSI_OPCODE_BARRIER)
info->numBarriers = 1;
+ if (insn.getOpcode() == TGSI_OPCODE_FBFETCH)
+ info->prop.fp.readsFramebuffer = true;
+
if (insn.dstCount()) {
Instruction::DstRegister dst = insn.getDst(0);
@@ -1574,6 +1577,7 @@ private:
void handleTEX(Value *dst0[4], int R, int S, int L, int C, int Dx, int Dy);
void handleTXF(Value *dst0[4], int R, int L_M);
void handleTXQ(Value *dst0[4], enum TexQuery, int R);
+ void handleFBFETCH(Value *dst0[4]);
void handleLIT(Value *dst0[4]);
void handleUserClipPlanes();
@@ -2283,6 +2287,40 @@ Converter::handleTXF(Value *dst[4], int R, int L_M)
}
void
+Converter::handleFBFETCH(Value *dst[4])
+{
+ TexInstruction *texi = new_TexInstruction(func, OP_TXF);
+ unsigned int c, d;
+
+ texi->tex.target = TEX_TARGET_2D_MS_ARRAY;
+ texi->tex.levelZero = 1;
+ texi->tex.useOffsets = 0;
+
+ for (c = 0, d = 0; c < 4; ++c) {
+ if (dst[c]) {
+ texi->setDef(d++, dst[c]);
+ texi->tex.mask |= 1 << c;
+ }
+ }
+
+ Value *x = mkOp1v(OP_RDSV, TYPE_F32, getScratch(), mkSysVal(SV_POSITION, 0));
+ Value *y = mkOp1v(OP_RDSV, TYPE_F32, getScratch(), mkSysVal(SV_POSITION, 1));
+ Value *z = mkOp1v(OP_RDSV, TYPE_U32, getScratch(), mkSysVal(SV_LAYER, 0));
+ Value *ms = mkOp1v(OP_RDSV, TYPE_U32, getScratch(), mkSysVal(SV_SAMPLE_INDEX, 0));
+
+ mkCvt(OP_CVT, TYPE_U32, x, TYPE_F32, x)->rnd = ROUND_Z;
+ mkCvt(OP_CVT, TYPE_U32, y, TYPE_F32, y)->rnd = ROUND_Z;
+ texi->setSrc(0, x);
+ texi->setSrc(1, y);
+ texi->setSrc(2, z);
+ texi->setSrc(3, ms);
+
+ texi->tex.r = texi->tex.s = -1;
+
+ bb->insertTail(texi);
+}
+
+void
Converter::handleLIT(Value *dst0[4])
{
Value *val0 = NULL;
@@ -3323,6 +3361,9 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
handleTXQ(dst0, TXQ_TYPE, 0);
std::swap(dst0[0], dst0[2]);
break;
+ case TGSI_OPCODE_FBFETCH:
+ handleFBFETCH(dst0);
+ break;
case TGSI_OPCODE_F2I:
case TGSI_OPCODE_F2U:
FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi)