aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp10
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp2
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp41
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.c3
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;