diff options
author | Ilia Mirkin <[email protected]> | 2014-04-03 09:43:40 -0400 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2014-04-07 01:06:18 -0400 |
commit | 423f64e83ab5b1ea7de475ae80300a8408522743 (patch) | |
tree | a549fb783b44dcc7209fd585cae5aa7e329ffbf5 /src/gallium/drivers/nouveau | |
parent | d5faf8e78603a27dbedb2e9e28b58b1b2bc32858 (diff) |
nvc0: enable texture query lod
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau')
4 files changed, 55 insertions, 1 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp index 584ae4c587e..b716d5457be 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp @@ -978,6 +978,9 @@ CodeEmitterGK110::emitTEX(const TexInstruction *i) case OP_TXD: code[1] = 0x7e000000; break; + case OP_TXLQ: + code[1] = 0x7e800000; + break; case OP_TXF: code[1] = 0x78000000; break; @@ -992,6 +995,11 @@ CodeEmitterGK110::emitTEX(const TexInstruction *i) code[1] = 0x76000000; code[1] |= i->tex.r << 9; break; + case OP_TXLQ: + code[0] = 0x00000002; + code[1] = 0x76800000; + code[1] |= i->tex.r << 9; + break; case OP_TXF: code[0] = 0x00000002; code[1] = 0x70000000; @@ -1017,6 +1025,7 @@ CodeEmitterGK110::emitTEX(const TexInstruction *i) case OP_TXF: break; case OP_TXG: break; // XXX case OP_TXD: break; + case OP_TXLQ: break; default: assert(!"invalid texture op"); break; @@ -1657,6 +1666,7 @@ CodeEmitterGK110::emitInstruction(Instruction *insn) case OP_TXL: case OP_TXD: case OP_TXF: + case OP_TXLQ: emitTEX(insn->asTex()); break; case OP_TXQ: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp index f15ca1b057d..1f624a50bb3 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp @@ -1138,6 +1138,7 @@ CodeEmitterNVC0::emitTEX(const TexInstruction *i) case OP_TXL: code[1] = 0x86000000; break; case OP_TXF: code[1] = 0x90000000; break; case OP_TXG: code[1] = 0xa0000000; break; + case OP_TXLQ: code[1] = 0xb0000000; break; case OP_TXD: code[1] = 0xe0000000; break; default: assert(!"invalid texture op"); @@ -2302,6 +2303,7 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn) case OP_TXL: case OP_TXD: case OP_TXF: + case OP_TXLQ: emitTEX(insn->asTex()); break; case OP_TXQ: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp index c0d14750ac1..382b02da50d 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -598,6 +598,7 @@ private: bool handleTXD(TexInstruction *); bool handleTXQ(TexInstruction *); bool handleManualTXD(TexInstruction *); + bool handleTXLQ(TexInstruction *); bool handleATOM(Instruction *); bool handleCasExch(Instruction *, bool needCctl); void handleSurfaceOpNVE4(TexInstruction *); @@ -860,6 +861,44 @@ NVC0LoweringPass::handleTXQ(TexInstruction *txq) } bool +NVC0LoweringPass::handleTXLQ(TexInstruction *i) +{ + /* The outputs are inverted compared to what the TGSI instruction + * expects. Take that into account in the mask. + */ + assert((i->tex.mask & ~3) == 0); + if (i->tex.mask == 1) + i->tex.mask = 2; + else if (i->tex.mask == 2) + i->tex.mask = 1; + handleTEX(i); + bld.setPosition(i, true); + + /* The returned values are not quite what we want: + * (a) convert from s16/u16 to f32 + * (b) multiply by 1/256 + */ + for (int def = 0; def < 2; ++def) { + if (!i->defExists(def)) + continue; + enum DataType type = TYPE_S16; + if (i->tex.mask == 2 || def > 0) + type = TYPE_U16; + bld.mkCvt(OP_CVT, TYPE_F32, i->getDef(def), type, i->getDef(def)); + bld.mkOp2(OP_MUL, TYPE_F32, i->getDef(def), + i->getDef(def), bld.loadImm(NULL, 1.0f / 256)); + } + if (i->tex.mask == 3) { + LValue *t = new_LValue(func, FILE_GPR); + bld.mkMov(t, i->getDef(0)); + bld.mkMov(i->getDef(0), i->getDef(1)); + bld.mkMov(i->getDef(1), t); + } + return true; +} + + +bool NVC0LoweringPass::handleATOM(Instruction *atom) { SVSemantic sv; @@ -1528,6 +1567,8 @@ NVC0LoweringPass::visit(Instruction *i) return handleTEX(i->asTex()); case OP_TXD: return handleTXD(i->asTex()); + case OP_TXLQ: + return handleTXLQ(i->asTex()); case OP_TXQ: return handleTXQ(i->asTex()); case OP_EX2: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 794ed3b5a70..fa3145eacde 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -178,10 +178,11 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_GATHER_SM5: case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: case PIPE_CAP_FAKE_SW_MSAA: - case PIPE_CAP_TEXTURE_QUERY_LOD: return 0; case PIPE_CAP_MAX_VIEWPORTS: return 1; + case PIPE_CAP_TEXTURE_QUERY_LOD: + return 1; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); return 0; |