Module: Mesa
Branch: main
Commit: 7e111268f12fa5b8abda8c3297211a25387592cb
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=7e111268f12fa5b8abda8c3297211a25387592cb

Author: Lionel Landwerlin <lionel.g.landwer...@intel.com>
Date:   Sun Jan 14 10:57:29 2024 +0200

intel/hang_viewer: add aux-tt view

Allows you to visualize the AUX-TT.

Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com>
Reviewed-by: Tapani Pälli <tapani.pa...@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27058>

---

 src/intel/tools/intel_hang_viewer.cpp | 145 ++++++++++++++++++++++++++++------
 1 file changed, 121 insertions(+), 24 deletions(-)

diff --git a/src/intel/tools/intel_hang_viewer.cpp 
b/src/intel/tools/intel_hang_viewer.cpp
index 680e771b122..eca20044ef6 100644
--- a/src/intel/tools/intel_hang_viewer.cpp
+++ b/src/intel/tools/intel_hang_viewer.cpp
@@ -118,6 +118,9 @@ static struct Context {
    /* Map hang file in RW for edition */
    bool edit = false;
 
+   /* AUX-TT */
+   uint64_t aux_tt_addr = 0;
+
    struct intel_device_info devinfo;
    struct intel_spec *spec = NULL;
    struct brw_isa_info isa;
@@ -142,6 +145,15 @@ static struct Context {
 
 thread_local ImGuiContext* __MesaImGui;
 
+hang_bo *find_bo(uint64_t addr)
+{
+   for (auto &bo : context.bos) {
+      if (addr >= bo.offset && addr < (bo.offset + bo.size))
+         return &bo;
+   }
+   return NULL;
+}
+
 /**/
 
 static uint8_t
@@ -204,21 +216,19 @@ public:
       snprintf(m_name, sizeof(m_name),
                "%s (0x%" PRIx64 ")##%p", m_description.c_str(), m_address, 
this);
 
-      for (auto &bo : context.bos) {
-         if (address >= bo.offset &&
-             address < (bo.offset + bo.size)) {
-            char *shader_txt = NULL;
-            size_t shader_txt_size = 0;
-            FILE *f = open_memstream(&shader_txt, &shader_txt_size);
-            if (f) {
-               intel_disassemble(&context.isa,
-                                 (const uint8_t *) bo.map +
-                                 (address - bo.offset), 0, f);
-               fclose(f);
-            }
-
-            m_shader = std::string(shader_txt);
+      hang_bo *bo = find_bo(address);
+      if (bo != NULL) {
+         char *shader_txt = NULL;
+         size_t shader_txt_size = 0;
+         FILE *f = open_memstream(&shader_txt, &shader_txt_size);
+         if (f) {
+            intel_disassemble(&context.isa,
+                              (const uint8_t *) bo->map +
+                              (address - bo->offset), 0, f);
+            fclose(f);
          }
+
+         m_shader = std::string(shader_txt);
       }
    }
 
@@ -232,6 +242,86 @@ public:
    void destroy() {}
 };
 
+class aux_tt_window : public window {
+public:
+   aux_tt_window(uint64_t l3_addr)
+      : m_l3_addr(l3_addr)
+      , m_bo(find_bo(l3_addr)) {
+      snprintf(m_name, sizeof(m_name), "AUX TT##%p", this);
+   }
+
+   void display() {
+      ImGui::BeginChild(ImGui::GetID("##toplevel"));
+      if (m_bo != NULL)
+         display_level(3, m_l3_addr, 0);
+      else
+         ImGui::Text("AUX table buffer not found: 0x%" PRIx64,
+                     m_l3_addr);
+      ImGui::EndChild();
+   }
+
+   void destroy() {}
+
+private:
+   void display_level(int level, uint64_t table_addr, uint64_t base_addr) {
+      assert(level >= 1 && level <= 3);
+
+      const hang_bo *bo =
+         table_addr == m_l3_addr ? m_bo : find_bo(table_addr);
+      if (bo == NULL) {
+         ImGui::Text("level %u not found addr=0x%016" PRIx64,
+                     level, table_addr);
+         return;
+      }
+
+      static struct {
+         uint32_t top;
+         uint32_t bottom;
+      } levels[4] = {
+         {  0,  0, },
+         { 23, 16, },
+         { 35, 24, },
+         { 47, 36, },
+      };
+
+      const uint64_t *entries =
+         (const uint64_t *)((const uint8_t *)bo->map + (table_addr - 
bo->offset));
+
+      if (level == 1) {
+         uint32_t n_entries = context.devinfo.verx10 == 125 ? 16 : 256;
+         for (uint32_t i = 0; i < n_entries; i++) {
+            uint64_t addr = entries[i] & 0xffffffffff00ull;
+            ImGui::Text("entry%04u: addr=0x%012" PRIx64 " entry=0x%012" PRIx64
+                        " range=0x%012" PRIx64 "-0x%012" PRIx64,
+                        i, addr, entries[i],
+                        base_addr + (uint64_t)i << levels[level].bottom,
+                        base_addr + (uint64_t)i << levels[level].bottom);
+         }
+      } else {
+         for (uint32_t i = 0; i < 4096; i++) {
+            uint64_t entry_addr = base_addr + (uint64_t)i << 
levels[level].bottom;
+            uint64_t addr = entries[i] & 0xffffffff8000ull;
+            bool valid = (entries[i] & 0x1) != 0;
+            if (valid &&
+                ImGui::TreeNodeEx(
+                   (void *)&entries[i],
+                   ImGuiTreeNodeFlags_Framed,
+                   "entry%04u: addr=0x%012" PRIx64 " entry=0x%012" PRIx64
+                   " range=0x%012" PRIx64 "-0x%012" PRIx64,
+                   i, addr, entries[i],
+                   entry_addr, entry_addr)) {
+               if (valid)
+                  display_level(level - 1, addr, entry_addr);
+               ImGui::TreePop();
+            }
+         }
+      }
+   }
+
+   uint64_t m_l3_addr;
+   const hang_bo *m_bo;
+};
+
 static struct intel_batch_decode_bo
 batch_get_bo(void *user_data, bool ppgtt, uint64_t address)
 {
@@ -402,8 +492,9 @@ display_hang_stats()
    ImGui::BeginChild(ImGui::GetID("BO list:"));
    for (const auto &bo : context.bos) {
       char bo_name[80];
-      snprintf(bo_name, sizeof(bo_name), "BO 0x%012" PRIx64 " size=%" PRIu64 
"(%s) %s",
-               bo.offset, bo.size, human_size(bo.size),
+      snprintf(bo_name, sizeof(bo_name),
+               "BO 0x%012" PRIx64 "-0x%012" PRIx64 " size=%" PRIu64 "(%s) %s",
+               bo.offset, bo.offset + bo.size - 1, bo.size, 
human_size(bo.size),
                bo.offset == exec_buf_addr ? "BATCH BUFFER" : "");
 
       if (ImGui::Selectable(bo_name, false))
@@ -411,6 +502,8 @@ display_hang_stats()
    }
    if (context.hw_image.size != 0 && ImGui::Selectable("HW IMAGE", false))
       context.windows.push_back(std::shared_ptr<window>(new 
batch_window(context.hw_image)));
+   if (context.aux_tt_addr != 0 && ImGui::Selectable("AUX-TT", false))
+      context.windows.push_back(std::shared_ptr<window>(new 
aux_tt_window(context.aux_tt_addr)));
    ImGui::EndChild();
 
    ImGui::End();
@@ -518,6 +611,7 @@ print_help(const char *progname, FILE *file)
            "\n"
            "    -p, --platform platform    platform to use for decoding\n"
            "    -e, --edit                 map the hang file read/write for 
edition\n"
+           "    -x, --aux-tt                 map the hang file read/write for 
edition\n"
            , progname);
 }
 
@@ -632,32 +726,35 @@ int
 main(int argc, char *argv[])
 {
    int c, i;
-   bool help = false, edit = false;
+   bool help = false;
    const char *platform = NULL;
    const struct option aubinator_opts[] = {
-      { "platform",      required_argument, NULL,                          0   
 },
-      { "edit",          no_argument,       (int *) &edit,                 
true },
+      { "platform",      required_argument, NULL,                          'p' 
 },
+      { "aux-tt",        required_argument, NULL,                          'x' 
 },
+      { "edit",          no_argument,       NULL,                          'e' 
 },
       { "help",          no_argument,       (int *) &help,                 
true },
       { NULL,            0,                 NULL,                          0   
 },
    };
 
+   context = {};
+
    i = 0;
-   while ((c = getopt_long(argc, argv, "p:e", aubinator_opts, &i)) != -1) {
+   while ((c = getopt_long(argc, argv, "p:ex:", aubinator_opts, &i)) != -1) {
       switch (c) {
       case 'p':
          platform = optarg;
          break;
       case 'e':
-         edit = true;
+         context.edit = true;
+         break;
+      case 'x':
+         context.aux_tt_addr = strtoll(optarg, NULL, 16);
          break;
       default:
          break;
       }
    }
 
-   context = {};
-   context.edit = edit;
-
    const char *filename = NULL;
    if (optind < argc)
       filename = argv[optind];

Reply via email to