diff options
author | Ilia Mirkin <imirkin@alum.mit.edu> | 2017-01-02 00:48:51 -0500 |
---|---|---|
committer | Ilia Mirkin <imirkin@alum.mit.edu> | 2017-01-16 21:13:09 -0500 |
commit | 5ba380c226b127cbfad00dd647471e1518ba2cb2 (patch) | |
tree | 6c00e7e1945ab525057bc915ddcf409a8dd0e32e /src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | |
parent | 6b7511c2f123014fe469a11d0b46fbff357335e4 (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.cpp | 41 |
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) |