diff options
6 files changed, 34 insertions, 1 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h index 857980d8279..286ac834e75 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h @@ -117,6 +117,7 @@ enum operation OP_TXQ, // texture size query OP_TXD, // texture derivatives OP_TXG, // texture gather + OP_TXLQ, // texture query lod OP_TEXCSAA, // texture op for coverage sampling OP_TEXPREP, // turn cube map array into 2d array coordinates OP_SULDB, // surface load (raw) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp index e2f93bbf5e6..9eccd9f0ccd 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp @@ -1450,6 +1450,9 @@ CodeEmitterNV50::emitTEX(const TexInstruction *i) code[0] |= 0x01000000; code[1] = 0x80000000; break; + case OP_TXLQ: + code[1] = 0x60020000; + break; default: assert(i->op == OP_TEX); break; @@ -1791,6 +1794,7 @@ CodeEmitterNV50::emitInstruction(Instruction *insn) case OP_TXL: case OP_TXF: case OP_TXG: + case OP_TXLQ: emitTEX(insn->asTex()); break; case OP_TXQ: 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 ccddb9a79fa..90820eace7e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -255,6 +255,7 @@ unsigned int Instruction::srcMask(unsigned int s) const case TGSI_OPCODE_TXD: case TGSI_OPCODE_TXL: case TGSI_OPCODE_TXP: + case TGSI_OPCODE_LODQ: { const struct tgsi_instruction_texture *tex = &insn->Texture; @@ -559,6 +560,7 @@ static nv50_ir::operation translateOpcode(uint opcode) NV50_IR_OPCODE_CASE(TXF, TXF); NV50_IR_OPCODE_CASE(TXQ, TXQ); NV50_IR_OPCODE_CASE(TG4, TXG); + NV50_IR_OPCODE_CASE(LODQ, TXLQ); NV50_IR_OPCODE_CASE(EMIT, EMIT); NV50_IR_OPCODE_CASE(ENDPRIM, RESTART); @@ -2429,6 +2431,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn) case TGSI_OPCODE_TXB: case TGSI_OPCODE_TXL: case TGSI_OPCODE_TXP: + case TGSI_OPCODE_LODQ: // R S L C Dx Dy handleTEX(dst0, 1, 1, 0x03, 0x0f, 0x00, 0x00); break; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp index 0908447e056..29f85cf70da 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nv50.cpp @@ -543,6 +543,7 @@ private: bool handleTXB(TexInstruction *); // I really bool handleTXL(TexInstruction *); // hate bool handleTXD(TexInstruction *); // these 3 + bool handleTXLQ(TexInstruction *); bool handleCALL(Instruction *); bool handlePRECONT(Instruction *); @@ -857,6 +858,26 @@ NV50LoweringPreSSA::handleTXD(TexInstruction *i) } bool +NV50LoweringPreSSA::handleTXLQ(TexInstruction *i) +{ + handleTEX(i); + bld.setPosition(i, true); + + /* The returned values are not quite what we want: + * (a) convert from s32 to f32 + * (b) multiply by 1/256 + */ + for (int def = 0; def < 2; ++def) { + if (!i->defExists(def)) + continue; + bld.mkCvt(OP_CVT, TYPE_F32, i->getDef(def), TYPE_S32, i->getDef(def)); + bld.mkOp2(OP_MUL, TYPE_F32, i->getDef(def), + i->getDef(def), bld.loadImm(NULL, 1.0f / 256)); + } + return true; +} + +bool NV50LoweringPreSSA::handleSET(Instruction *i) { if (i->dType == TYPE_F32) { @@ -1197,6 +1218,8 @@ NV50LoweringPreSSA::visit(Instruction *i) return handleTXL(i->asTex()); case OP_TXD: return handleTXD(i->asTex()); + case OP_TXLQ: + return handleTXLQ(i->asTex()); case OP_EX2: bld.mkOp1(OP_PREEX2, TYPE_F32, i->getDef(0), i->getSrc(0)); i->setSrc(0, i->getDef(0)); diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp index ae42d03d596..4093bc03893 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp @@ -147,6 +147,7 @@ const char *operationStr[OP_LAST + 1] = "texquery", "texgrad", "texgather", + "texquerylod", "texcsaa", "texprep", "suldb", diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index d706508c52e..d02806ade19 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -196,12 +196,13 @@ nv50_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 NV50_MAX_VIEWPORTS; case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: return (class_3d >= NVA3_3D_CLASS) ? 4 : 0; + case PIPE_CAP_TEXTURE_QUERY_LOD: + return class_3d >= NVA3_3D_CLASS; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); return 0; |