From 9145873b152e8d0e361399f6b05347c0ec6c361d Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Tue, 18 Oct 2016 22:46:36 -0400 Subject: [PATCH] nvc0/ir: use levelZero flag when the lod is set to 0 Signed-off-by: Ilia Mirkin Reviewed-by: Samuel Pitoiset --- .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 48 ++++++++++++++++--- .../nouveau/codegen/nv50_ir_lowering_nvc0.h | 1 + 2 files changed, 43 insertions(+), 6 deletions(-) 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 68f2b1544cb..fe18f4718de 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -115,6 +115,38 @@ NVC0LegalizeSSA::handleFTZ(Instruction *i) i->ftz = true; } +void +NVC0LegalizeSSA::handleTEXLOD(TexInstruction *i) +{ + if (i->tex.target.isMS()) + return; + + ImmediateValue lod; + + // The LOD argument comes right after the coordinates (before depth bias, + // offsets, etc). + int arg = i->tex.target.getArgCount(); + + // SM30+ stores the indirect handle as a separate arg, which comes before + // the LOD. + if (prog->getTarget()->getChipset() >= NVISA_GK104_CHIPSET && + i->tex.rIndirectSrc >= 0) + arg++; + // SM20 stores indirect handle combined with array coordinate + if (prog->getTarget()->getChipset() < NVISA_GK104_CHIPSET && + !i->tex.target.isArray() && + i->tex.rIndirectSrc >= 0) + arg++; + + if (!i->src(arg).getImmediate(lod) || !lod.isInteger(0)) + return; + + if (i->op == OP_TXL) + i->op = OP_TEX; + i->tex.levelZero = true; + i->moveSources(arg + 1, -1); +} + bool NVC0LegalizeSSA::visit(Function *fn) { @@ -128,21 +160,25 @@ NVC0LegalizeSSA::visit(BasicBlock *bb) Instruction *next; for (Instruction *i = bb->getEntry(); i; i = next) { next = i->next; - if (i->sType == TYPE_F32) { - if (prog->getType() != Program::TYPE_COMPUTE) - handleFTZ(i); - continue; - } + + if (i->sType == TYPE_F32 && prog->getType() != Program::TYPE_COMPUTE) + handleFTZ(i); + switch (i->op) { case OP_DIV: case OP_MOD: - handleDIV(i); + if (i->sType != TYPE_F32) + handleDIV(i); break; case OP_RCP: case OP_RSQ: if (i->dType == TYPE_F64) handleRCPRSQ(i); break; + case OP_TXL: + case OP_TXF: + handleTEXLOD(i->asTex()); + break; default: break; } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h index 6f4da8ca99c..d91b6aa1c72 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h @@ -35,6 +35,7 @@ private: void handleDIV(Instruction *); // integer division, modulus void handleRCPRSQ(Instruction *); // double precision float recip/rsqrt void handleFTZ(Instruction *); + void handleTEXLOD(TexInstruction *); protected: BuildUtil bld; -- 2.30.2