[Mesa-dev] [PATCH 4/5] nv50/ir: use suld.p on GM107+

Rhys Perry pendingchaos02 at gmail.com
Fri Jun 15 22:06:13 UTC 2018


Signed-off-by: Rhys Perry <pendingchaos02 at 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_print.cpp      | 17 +++++++++++
 src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp | 27 ++++++++++++++++-
 5 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
index f4f3c70888..76dd93967b 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+ and are set during register allocation
+#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_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);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
index 28e0e260ce..4a362a6c12 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp
@@ -2111,8 +2111,33 @@ RegAlloc::InsertConstraintsPass::texConstraintGM107(TexInstruction *tex)
 {
    int n, s;
 
-   if (isTextureOp(tex->op))
+   if (isTextureOp(tex->op)) {
       textureMask(tex);
+   } else
+   if (tex->op == OP_SULDP) {
+      int max = 0;
+      for (int d = 0; tex->defExists(d); d++) {
+         if (tex->getDef(d)->refCount())
+            max = d;
+      }
+
+      switch (max) {
+      case 0:
+         tex->subOp |= NV50_IR_SUBOP_SULDP_R;
+         tex->setDef(1, NULL);
+         tex->setDef(2, NULL);
+         tex->setDef(3, NULL);
+         break;
+      case 1:
+         tex->subOp |= NV50_IR_SUBOP_SULDP_RG;
+         tex->setDef(2, NULL);
+         tex->setDef(3, NULL);
+         break;
+      default:
+         tex->subOp |= NV50_IR_SUBOP_SULDP_RGBA;
+         break;
+      }
+   }
    condenseDefs(tex);
 
    if (isSurfaceOp(tex->op)) {
-- 
2.14.4



More information about the mesa-dev mailing list