Module: Mesa
Branch: staging/23.2
Commit: 42f5a922b4ea23093446df5e27eb515358abee84
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=42f5a922b4ea23093446df5e27eb515358abee84

Author: Gert Wollny <[email protected]>
Date:   Wed Jul 26 15:55:59 2023 +0200

r600/sfn: Fix use of multiple IDX with kcache

Currently we don't properly support using he two IDX registers in the
same ALU CF, so work around this by enforcing a new CF if both indices
are used.

Fixes: d21054b4bc92a1a9240841dca719f81a142fd5cc
    r600/sfn: Add pass to split addess and index register loads

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24297>
(cherry picked from commit 1d4dd664e0b35d4969622b50fda8a51c373bbea2)

---

 .pick_status.json                                            |  2 +-
 src/gallium/drivers/r600/sfn/sfn_alu_defines.h               |  1 +
 src/gallium/drivers/r600/sfn/sfn_instr.cpp                   | 12 ++++++++++++
 src/gallium/drivers/r600/sfn/sfn_scheduler.cpp               |  2 ++
 .../drivers/r600/sfn/tests/sfn_split_address_loads_test.cpp  | 12 +++++++++---
 5 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 33f6fc68eac..e107558e24e 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -23514,7 +23514,7 @@
         "description": "r600/sfn: Fix use of multiple IDX with kcache",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": "d21054b4bc92a1a9240841dca719f81a142fd5cc",
         "notes": null
diff --git a/src/gallium/drivers/r600/sfn/sfn_alu_defines.h 
b/src/gallium/drivers/r600/sfn/sfn_alu_defines.h
index aa11846b8ca..180f3f56f9e 100644
--- a/src/gallium/drivers/r600/sfn/sfn_alu_defines.h
+++ b/src/gallium/drivers/r600/sfn/sfn_alu_defines.h
@@ -471,6 +471,7 @@ struct KCacheLine {
    int bank{0};
    int addr{0};
    int len{0};
+   int index_mode{0};
    enum KCacheLockMode {
       free,
       lock_1,
diff --git a/src/gallium/drivers/r600/sfn/sfn_instr.cpp 
b/src/gallium/drivers/r600/sfn/sfn_instr.cpp
index e1ef9ccb8bc..ca726bcba82 100644
--- a/src/gallium/drivers/r600/sfn/sfn_instr.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_instr.cpp
@@ -408,6 +408,10 @@ Block::try_reserve_kcache(const UniformValue& u, 
std::array<KCacheLine, 4>& kcac
    int bank = u.kcache_bank();
    int sel = (u.sel() - 512);
    int line = sel >> 4;
+   EBufferIndexMode index_mode = bim_none;
+
+   if (auto addr = u.buf_addr())
+      index_mode = addr->sel() == AddressRegister::idx0 ?  bim_zero : bim_one;
 
    bool found = false;
 
@@ -416,6 +420,12 @@ Block::try_reserve_kcache(const UniformValue& u, 
std::array<KCacheLine, 4>& kcac
          if (kcache[i].bank < bank)
             continue;
 
+
+         if (kcache[i].bank == bank &&
+             kcache[i].index_mode != bim_none &&
+             kcache[i].index_mode != index_mode) {
+            return false;
+         }
          if ((kcache[i].bank == bank && kcache[i].addr > line + 1) ||
              kcache[i].bank > bank) {
             if (kcache[kcache_banks - 1].mode)
@@ -427,6 +437,7 @@ Block::try_reserve_kcache(const UniformValue& u, 
std::array<KCacheLine, 4>& kcac
             kcache[i].mode = KCacheLine::lock_1;
             kcache[i].bank = bank;
             kcache[i].addr = line;
+            kcache[i].index_mode = index_mode;
             return true;
          }
 
@@ -457,6 +468,7 @@ Block::try_reserve_kcache(const UniformValue& u, 
std::array<KCacheLine, 4>& kcac
          kcache[i].mode = KCacheLine::lock_1;
          kcache[i].bank = bank;
          kcache[i].addr = line;
+         kcache[i].index_mode = index_mode;
          return true;
       }
    }
diff --git a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp 
b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp
index ef42d7813db..71715039846 100644
--- a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp
@@ -650,11 +650,13 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& 
out_blocks)
          assert(!group->has_lds_group_start());
          assert(m_current_block->expected_ar_uses() == 0);
          start_new_block(out_blocks, Block::alu);
+         m_current_block->try_reserve_kcache(*group);
       }
       if (addr->sel() == AddressRegister::idx1 && m_idx1_pending) {
          assert(!group->has_lds_group_start());
          assert(m_current_block->expected_ar_uses() == 0);
          start_new_block(out_blocks, Block::alu);
+         m_current_block->try_reserve_kcache(*group);
       }
    }
 
diff --git 
a/src/gallium/drivers/r600/sfn/tests/sfn_split_address_loads_test.cpp 
b/src/gallium/drivers/r600/sfn/tests/sfn_split_address_loads_test.cpp
index 0ae71177c8f..269f8b2e0dd 100644
--- a/src/gallium/drivers/r600/sfn/tests/sfn_split_address_loads_test.cpp
+++ b/src/gallium/drivers/r600/sfn/tests/sfn_split_address_loads_test.cpp
@@ -591,17 +591,23 @@ ALU_GROUP_BEGIN
   ALU MOV S4.x@chgr : KC1[IDX0][0].x {WL}
 ALU_GROUP_END
 ALU_GROUP_BEGIN
-  ALU MOVA_INT IDX0 : S3.z@free {}
-  ALU MOV S4.y@chgr : KC1[IDX1][0].y {WL}
+  ALU MOVA_INT IDX0 : S3.z@free {L}
 ALU_GROUP_END
 BLOCK_END
 BLOCK_START
 ALU_GROUP_BEGIN
-  ALU MOVA_INT IDX1 : S3.w@free {}
   ALU MOV S4.z@chgr : KC1[IDX0][0].z {WL}
 ALU_GROUP_END
 BLOCK_END
 BLOCK_START
+ALU_GROUP_BEGIN
+  ALU MOV S4.y@chgr : KC1[IDX1][0].y {WL}
+ALU_GROUP_END
+ALU_GROUP_BEGIN
+  ALU MOVA_INT IDX1 : S3.w@free {L}
+ALU_GROUP_END
+BLOCK_END
+BLOCK_START
 ALU_GROUP_BEGIN
   ALU MOV S4.w@chgr : KC1[IDX1][0].w {WL}
 ALU_GROUP_END

Reply via email to