Signed-off-by: Rhys Perry <pendingchao...@gmail.com> --- src/gallium/drivers/nouveau/codegen/nv50_ir.h | 4 +++ .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 34 ++++++++++++++-------- .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 3 -- .../drivers/nouveau/codegen/nv50_ir_peephole.cpp | 27 +++++++++++++++++ .../drivers/nouveau/codegen/nv50_ir_print.cpp | 17 +++++++++++ 5 files changed, 70 insertions(+), 15 deletions(-)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h index f4f3c70888..a13bc6a6bb 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h @@ -221,6 +221,10 @@ enum operation #define NV50_IR_SUBOP_SULD_ZERO 0 #define NV50_IR_SUBOP_SULD_TRAP 1 #define NV50_IR_SUBOP_SULD_SDCL 3 +// These three are only for GM107+. +#define NV50_IR_SUBOP_SULDP_RGBA (0 << 2) +#define NV50_IR_SUBOP_SULDP_RG (1 << 2) +#define NV50_IR_SUBOP_SULDP_R (2 << 2) #define NV50_IR_SUBOP_SUBFM_3D 1 #define NV50_IR_SUBOP_SUCLAMP_2D 0x10 #define NV50_IR_SUBOP_SUCLAMP_SD(r, d) (( 0 + (r)) | ((d == 2) ? 0x10 : 0)) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp index 26826d6360..f1db0674b1 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -3042,26 +3042,36 @@ void CodeEmitterGM107::emitSULDx() { const TexInstruction *insn = this->insn->asTex(); - int type = 0; emitInsn(0xeb000000); if (insn->op == OP_SULDB) emitField(0x34, 1, 1); emitSUTarget(); - switch (insn->dType) { - case TYPE_S8: type = 1; break; - case TYPE_U16: type = 2; break; - case TYPE_S16: type = 3; break; - case TYPE_U32: type = 4; break; - case TYPE_U64: type = 5; break; - case TYPE_B128: type = 6; break; - default: - assert(insn->dType == TYPE_U8); - break; + if (insn->op == OP_SULDB) { + int type = 0; + switch (insn->dType) { + case TYPE_S8: type = 1; break; + case TYPE_U16: type = 2; break; + case TYPE_S16: type = 3; break; + case TYPE_U32: type = 4; break; + case TYPE_U64: type = 5; break; + case TYPE_B128: type = 6; break; + default: + assert(insn->dType == TYPE_U8); + break; + } + emitField(0x14, 3, type); + } else { + int type = 0; + switch (insn->subOp & 0xc) { + case NV50_IR_SUBOP_SULDP_R: type = 0x1; break; + case NV50_IR_SUBOP_SULDP_RG: type = 0x3; break; + case NV50_IR_SUBOP_SULDP_RGBA: type = 0xf; break; + } + emitField(0x14, 4, type); } emitLDSTc(0x18); - emitField(0x14, 3, type); emitGPR (0x00, insn->def(0)); emitGPR (0x08, insn->src(0)); 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 29f674b451..f7ffa5627c 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -2397,9 +2397,6 @@ NVC0LoweringPass::handleSurfaceOpGM107(TexInstruction *su) { processSurfaceCoordsGM107(su); - if (su->op == OP_SULDP) - convertSurfaceFormat(su); - if (su->op == OP_SUREDP) { Value *def = su->getDef(0); diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp index 39177bd044..65db2acfa2 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp @@ -1671,6 +1671,7 @@ private: void handleCVT_EXTBF(Instruction *); void handleSUCLAMP(Instruction *); void handleNEG(Instruction *); + void handleSULDP(Instruction *); BuildUtil bld; }; @@ -2175,6 +2176,29 @@ AlgebraicOpt::handleNEG(Instruction *i) { } } +void +AlgebraicOpt::handleSULDP(Instruction *i) { + if (prog->getTarget()->getChipset() < NVISA_GM107_CHIPSET) + return; + + int max = 0; + for (int d = 0; i->defExists(d); d++) { + if (i->getDef(d)->uses.size() > 0) + max = MAX2(max, d); + } + + if (max == 0) { + i->subOp |= NV50_IR_SUBOP_SULDP_R; + i->setDef(1, NULL); + i->setDef(2, NULL); + i->setDef(3, NULL); + } else if (max == 1) { + i->subOp |= NV50_IR_SUBOP_SULDP_RG; + i->setDef(2, NULL); + i->setDef(3, NULL); + } +} + bool AlgebraicOpt::visit(BasicBlock *bb) { @@ -2215,6 +2239,9 @@ AlgebraicOpt::visit(BasicBlock *bb) case OP_NEG: handleNEG(i); break; + case OP_SULDP: + handleSULDP(i); + break; default: break; } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp index cbb21f5f72..8a9e0af4fd 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp @@ -240,6 +240,16 @@ static const char *barOpStr[] = "sync", "arrive", "red and", "red or", "red popc" }; +static const char *suldOpStr[] = +{ + "zero", "trap", "sdcl" +}; + +static const char *suldSwizzleOpStr[] = +{ + "rgba", "rg", "r" +}; + static const char *DataTypeStr[] = { "-", @@ -624,6 +634,13 @@ void Instruction::print() const if (subOp < ARRAY_SIZE(barOpStr)) PRINT("%s ", barOpStr[subOp]); break; + case OP_SULDB: + case OP_SULDP: + if ((subOp & 0x3) < ARRAY_SIZE(suldOpStr)) + PRINT("%s ", suldOpStr[subOp & 0x3]); + if (op == OP_SULDP && subOp >> 2 < (int)ARRAY_SIZE(suldSwizzleOpStr)) + PRINT("%s ", suldSwizzleOpStr[subOp >> 2]); + break; default: if (subOp) PRINT("(SUBOP:%u) ", subOp); -- 2.14.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev