radeonsi: add debug code for register shadowing
authorMarek Olšák <marek.olsak@amd.com>
Sun, 24 May 2020 12:34:23 +0000 (08:34 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 22 Jul 2020 16:08:33 +0000 (12:08 -0400)
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5798>

src/amd/common/ac_shadowed_regs.c
src/amd/common/ac_shadowed_regs.h
src/gallium/drivers/radeonsi/si_build_pm4.h
src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_pm4.c

index 1b7890835dec92e44919d3941cd9250023a82136..c7db0f17d450bc983a33f81de0de4849a7e94328 100644 (file)
  */
 
 #include "ac_shadowed_regs.h"
+#include "ac_debug.h"
 #include "sid.h"
 #include "util/macros.h"
+#include "util/u_debug.h"
+#include <stdio.h>
 
 static const struct ac_reg_range Gfx9UserConfigShadowRange[] = {
    {
@@ -2925,3 +2928,87 @@ void ac_emulate_clear_state(const struct radeon_info *info,
       unreachable("unimplemented");
    }
 }
+
+/* Debug helper to find if any registers are missing in the tables above.
+ * Call this in the driver whenever you set a register.
+ */
+void ac_check_shadowed_regs(enum chip_class chip_class, enum radeon_family family,
+                            unsigned reg_offset, unsigned count)
+{
+   bool found = false;
+   bool shadowed = false;
+
+   for (unsigned type = 0; type < SI_NUM_ALL_REG_RANGES && !found; type++) {
+      const struct ac_reg_range *ranges;
+      unsigned num_ranges;
+
+      ac_get_reg_ranges(chip_class, family, type, &num_ranges, &ranges);
+
+      for (unsigned i = 0; i < num_ranges; i++) {
+         unsigned end_reg_offset = reg_offset + count * 4;
+         unsigned end_range_offset = ranges[i].offset + ranges[i].size;
+
+         /* Test if the ranges interect. */
+         if (MAX2(ranges[i].offset, reg_offset) <
+             MIN2(end_range_offset, end_reg_offset)) {
+            /* Assertion: A register can be listed only once. */
+            assert(!found);
+            found = true;
+            shadowed = type != SI_REG_RANGE_NON_SHADOWED;
+         }
+      }
+   }
+
+   if (reg_offset == R_00B858_COMPUTE_DESTINATION_EN_SE0 ||
+       reg_offset == R_00B864_COMPUTE_DESTINATION_EN_SE2)
+      return;
+
+   if (!found || !shadowed) {
+      printf("register %s: ", !found ? "not found" : "not shadowed");
+      if (count > 1) {
+         printf("%s .. %s\n", ac_get_register_name(chip_class, reg_offset),
+                ac_get_register_name(chip_class, reg_offset + (count - 1) * 4));
+      } else {
+         printf("%s\n", ac_get_register_name(chip_class, reg_offset));
+      }
+   }
+}
+
+/* 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)
+{
+   if (!debug_get_bool_option("AMD_PRINT_SHADOW_REGS", false))
+      return;
+
+   for (unsigned type = 0; type < SI_NUM_SHADOWED_REG_RANGES; type++) {
+      const struct ac_reg_range *ranges;
+      unsigned num_ranges;
+
+      ac_get_reg_ranges(info->chip_class, info->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->chip_class, offset);
+            unsigned value = -1;
+            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);
+            }
+
+            printf("0x%X %s = 0x%X\n", offset, name, value);
+         }
+         printf("--------------------------------------------\n");
+      }
+   }
+}
index 616cd7467e6a7622309f967d217d5221aefb48ed..b3f61db70b280889e8383084da09a67614460ed8 100644 (file)
@@ -55,5 +55,8 @@ void ac_get_reg_ranges(enum chip_class chip_class, enum radeon_family family,
 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_check_shadowed_regs(enum chip_class chip_class, enum radeon_family family,
+                            unsigned reg_offset, unsigned count);
+void ac_print_shadowed_regs(const struct radeon_info *info);
 
 #endif
index f7f0e26d7d080e3902374cb6013ac2692e2a4863..26a80fd7eccd42e0a7647438c35214b0950a9a3d 100644 (file)
 #include "si_pipe.h"
 #include "sid.h"
 
+#if 0
+#include "ac_shadowed_regs.h"
+#define SI_CHECK_SHADOWED_REGS(reg_offset, count) ac_check_shadowed_regs(GFX10, CHIP_NAVI14, reg_offset, count)
+#else
+#define SI_CHECK_SHADOWED_REGS(reg_offset, count)
+#endif
+
 static inline void radeon_set_config_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
 {
+   SI_CHECK_SHADOWED_REGS(reg, num);
    assert(reg < SI_CONTEXT_REG_OFFSET);
    assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
    radeon_emit(cs, PKT3(PKT3_SET_CONFIG_REG, num, 0));
@@ -48,6 +56,7 @@ static inline void radeon_set_config_reg(struct radeon_cmdbuf *cs, unsigned reg,
 
 static inline void radeon_set_context_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
 {
+   SI_CHECK_SHADOWED_REGS(reg, num);
    assert(reg >= SI_CONTEXT_REG_OFFSET);
    assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
    radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, num, 0));
@@ -70,6 +79,7 @@ static inline void radeon_set_context_reg_seq_array(struct radeon_cmdbuf *cs, un
 static inline void radeon_set_context_reg_idx(struct radeon_cmdbuf *cs, unsigned reg, unsigned idx,
                                               unsigned value)
 {
+   SI_CHECK_SHADOWED_REGS(reg, 1);
    assert(reg >= SI_CONTEXT_REG_OFFSET);
    assert(cs->current.cdw + 3 <= cs->current.max_dw);
    radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, 1, 0));
@@ -79,6 +89,7 @@ static inline void radeon_set_context_reg_idx(struct radeon_cmdbuf *cs, unsigned
 
 static inline void radeon_set_sh_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
 {
+   SI_CHECK_SHADOWED_REGS(reg, num);
    assert(reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END);
    assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
    radeon_emit(cs, PKT3(PKT3_SET_SH_REG, num, 0));
@@ -93,6 +104,7 @@ static inline void radeon_set_sh_reg(struct radeon_cmdbuf *cs, unsigned reg, uns
 
 static inline void radeon_set_uconfig_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num)
 {
+   SI_CHECK_SHADOWED_REGS(reg, num);
    assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END);
    assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
    radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, num, 0));
@@ -108,6 +120,7 @@ static inline void radeon_set_uconfig_reg(struct radeon_cmdbuf *cs, unsigned reg
 static inline void radeon_set_uconfig_reg_idx(struct radeon_cmdbuf *cs, struct si_screen *screen,
                                               unsigned reg, unsigned idx, unsigned value)
 {
+   SI_CHECK_SHADOWED_REGS(reg, 1);
    assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END);
    assert(cs->current.cdw + 3 <= cs->current.max_dw);
    assert(idx != 0);
@@ -123,6 +136,7 @@ static inline void radeon_set_uconfig_reg_idx(struct radeon_cmdbuf *cs, struct s
 static inline void radeon_set_context_reg_rmw(struct radeon_cmdbuf *cs, unsigned reg,
                                               unsigned value, unsigned mask)
 {
+   SI_CHECK_SHADOWED_REGS(reg, 1);
    assert(reg >= SI_CONTEXT_REG_OFFSET);
    assert(cs->current.cdw + 4 <= cs->current.max_dw);
    radeon_emit(cs, PKT3(PKT3_CONTEXT_REG_RMW, 2, 0));
index ba03250b31e93339c8dfb96ecc328352daf70f92..bf8742d8686cece3a6c0a4e93466ac9c5692be38 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "si_build_pm4.h"
+#include "ac_debug.h"
 #include "ac_shadowed_regs.h"
 #include "util/u_memory.h"
 
index ce5eba575b77c8c06d7618f9bc83d0bc076e9ef6..c2219bf09b42e56483ff38792cfc11b96d3c62d6 100644 (file)
@@ -55,6 +55,7 @@
 
 #include "si_pipe.h"
 #include "si_compute.h"
+#include "si_build_pm4.h"
 #include "sid.h"
 #include "util/format/u_format.h"
 #include "util/hash_table.h"
@@ -2033,6 +2034,7 @@ void si_shader_change_notify(struct si_context *sctx)
 static void si_emit_shader_pointer_head(struct radeon_cmdbuf *cs, unsigned sh_offset,
                                         unsigned pointer_count)
 {
+   SI_CHECK_SHADOWED_REGS(sh_offset, pointer_count);
    radeon_emit(cs, PKT3(PKT3_SET_SH_REG, pointer_count, 0));
    radeon_emit(cs, (sh_offset - SI_SH_REG_OFFSET) >> 2);
 }
index 0e1cde2e25e0b5cc65cee734f6aa629fc9df91a6..40c7270e46ea23c92e542e2225d12a7ec9a66855 100644 (file)
@@ -33,6 +33,7 @@
 #include "si_public.h"
 #include "si_shader_internal.h"
 #include "sid.h"
+#include "ac_shadowed_regs.h"
 #include "util/disk_cache.h"
 #include "util/u_log.h"
 #include "util/u_memory.h"
@@ -1281,6 +1282,8 @@ static struct pipe_screen *radeonsi_screen_create_impl(struct radeon_winsys *ws,
                                     RADEON_DOMAIN_OA);
    }
 
+   ac_print_shadowed_regs(&sscreen->info);
+
    STATIC_ASSERT(sizeof(union si_vgt_stages_key) == 4);
    return &sscreen->b;
 }
index a7d57258591f1cf2f75ff0564804200ff8542224..f34462679706f2ee015fe359a6a8f68995f81207 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "si_pipe.h"
+#include "si_build_pm4.h"
 #include "sid.h"
 #include "util/u_memory.h"
 
@@ -50,6 +51,8 @@ void si_pm4_set_reg(struct si_pm4_state *state, unsigned reg, uint32_t val)
 {
    unsigned opcode;
 
+   SI_CHECK_SHADOWED_REGS(reg, 1);
+
    if (reg >= SI_CONFIG_REG_OFFSET && reg < SI_CONFIG_REG_END) {
       opcode = PKT3_SET_CONFIG_REG;
       reg -= SI_CONFIG_REG_OFFSET;