amd: add a new helper that prints all non-shadowed regs
authorMarek Olšák <marek.olsak@amd.com>
Sun, 11 Jun 2023 00:45:57 +0000 (20:45 -0400)
committerMarge Bot <emma+marge@anholt.net>
Sat, 17 Jun 2023 23:42:21 +0000 (23:42 +0000)
for validating our tables against register definitions

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23687>

src/amd/common/ac_debug.c
src/amd/common/ac_debug.h
src/amd/common/ac_shadowed_regs.c
src/amd/common/ac_shadowed_regs.h
src/gallium/drivers/radeonsi/si_pipe.c

index 088ab09..6045176 100644 (file)
@@ -174,6 +174,12 @@ const char *ac_get_register_name(enum amd_gfx_level gfx_level, enum radeon_famil
    return reg ? sid_strings + reg->name_offset : "(no name)";
 }
 
+bool ac_register_exists(enum amd_gfx_level gfx_level, enum radeon_family family,
+                        unsigned offset)
+{
+   return find_register(gfx_level, family, offset) != NULL;
+}
+
 void ac_dump_reg(FILE *file, enum amd_gfx_level gfx_level, enum radeon_family family,
                  unsigned offset, uint32_t value, uint32_t field_mask)
 {
index c2af327..957b064 100644 (file)
@@ -41,6 +41,8 @@ typedef void *(*ac_debug_addr_callback)(void *data, uint64_t addr);
 
 const char *ac_get_register_name(enum amd_gfx_level gfx_level, enum radeon_family family,
                                  unsigned offset);
+bool ac_register_exists(enum amd_gfx_level gfx_level, enum radeon_family family,
+                        unsigned offset);
 void ac_dump_reg(FILE *file, enum amd_gfx_level gfx_level, enum radeon_family family,
                  unsigned offset, uint32_t value, uint32_t field_mask);
 void ac_parse_ib_chunk(FILE *f, uint32_t *ib, int num_dw, const int *trace_ids,
index 89eaaa6..5f64d01 100644 (file)
@@ -3706,45 +3706,54 @@ void ac_emulate_clear_state(const struct radeon_info *info, struct radeon_cmdbuf
    }
 }
 
-/* Debug helper to print all shadowed registers and their current values read
- * by umr. This can be used to verify whether register shadowing doesn't affect
- * apps that don't enable it, because the shadowed register tables might contain
- * registers that the driver doesn't set.
- */
-void ac_print_shadowed_regs(const struct radeon_info *info)
+static void ac_print_nonshadowed_reg(enum amd_gfx_level gfx_level, enum radeon_family family,
+                                     unsigned reg_offset)
 {
-   if (!debug_get_bool_option("AMD_PRINT_SHADOW_REGS", false))
-      return;
+   bool found = false;
 
-   for (unsigned type = 0; type < SI_NUM_REG_RANGES; type++) {
+   for (unsigned type = 0; type < SI_NUM_REG_RANGES && !found; type++) {
       const struct ac_reg_range *ranges;
       unsigned num_ranges;
 
-      ac_get_reg_ranges(info->gfx_level, info->family, type, &num_ranges, &ranges);
+      ac_get_reg_ranges(gfx_level, family, type, &num_ranges, &ranges);
 
       for (unsigned i = 0; i < num_ranges; i++) {
-         for (unsigned j = 0; j < ranges[i].size / 4; j++) {
-            unsigned offset = ranges[i].offset + j * 4;
-
-            const char *name = ac_get_register_name(info->gfx_level, info->family, offset);
-            unsigned value = -1;
-
-#ifndef _WIN32
-            char cmd[1024];
-            snprintf(cmd, sizeof(cmd), "umr -r 0x%x", offset);
-            FILE *p = popen(cmd, "r");
-            if (p) {
-               ASSERTED int r = fscanf(p, "%x", &value);
-               assert(r == 1);
-               pclose(p);
+         if (reg_offset >= ranges[i].offset && reg_offset < ranges[i].offset + ranges[i].size) {
+            /* Assertion: A register can be listed only once in the shadowed tables. */
+            if (found) {
+               printf("warning: register R_%06X_%s found multiple times in tables\n",
+                      reg_offset, ac_get_register_name(gfx_level, family, reg_offset));
             }
-#endif
-
-            printf("0x%X %s = 0x%X\n", offset, name, value);
+            found = true;
          }
-         printf("--------------------------------------------\n");
       }
    }
+
+   if (!found) {
+      printf("register R_%06X_%s not found in any tables\n", reg_offset,
+             ac_get_register_name(gfx_level, family, reg_offset));
+   }
+}
+
+void ac_print_nonshadowed_regs(enum amd_gfx_level gfx_level, enum radeon_family family)
+{
+   if (!debug_get_bool_option("AMD_PRINT_SHADOW_REGS", false))
+      return;
+
+   for (unsigned i = 0xB000; i < 0xBFFF; i += 4) {
+      if (ac_register_exists(gfx_level, family, i))
+         ac_print_nonshadowed_reg(gfx_level, family, i);
+   }
+
+   for (unsigned i = 0x28000; i < 0x28FFF; i += 4) {
+      if (ac_register_exists(gfx_level, family, i))
+         ac_print_nonshadowed_reg(gfx_level, family, i);
+   }
+
+   for (unsigned i = 0x30000; i < 0x31FFF; i += 4) {
+      if (ac_register_exists(gfx_level, family, i))
+         ac_print_nonshadowed_reg(gfx_level, family, i);
+   }
 }
 
 static void ac_build_load_reg(const struct radeon_info *info,
index c940b26..2d16755 100644 (file)
@@ -39,7 +39,7 @@ void ac_get_reg_ranges(enum amd_gfx_level gfx_level, enum radeon_family family,
                        const struct ac_reg_range **ranges);
 void ac_emulate_clear_state(const struct radeon_info *info, struct radeon_cmdbuf *cs,
                             set_context_reg_seq_array_fn set_context_reg_seq_array);
-void ac_print_shadowed_regs(const struct radeon_info *info);
+void ac_print_nonshadowed_regs(enum amd_gfx_level gfx_level, enum radeon_family family);
 
 void ac_create_shadowing_ib_preamble(const struct radeon_info *info,
                                      pm4_cmd_add_fn pm4_cmd_add, void *pm4_cmdbuf,
index 89e3068..56aa3f9 100644 (file)
@@ -1448,7 +1448,7 @@ static struct pipe_screen *radeonsi_screen_create_impl(struct radeon_winsys *ws,
                                     RADEON_DOMAIN_OA);
    }
 
-   ac_print_shadowed_regs(&sscreen->info);
+   ac_print_nonshadowed_regs(sscreen->info.gfx_level, sscreen->info.family);
 
    return &sscreen->b;
 }