From 95c9048591c6d3ccf597f73dfcde09028c7330c5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 24 May 2020 08:34:23 -0400 Subject: [PATCH] radeonsi: add debug code for register shadowing Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/amd/common/ac_shadowed_regs.c | 87 +++++++++++++++++++ src/amd/common/ac_shadowed_regs.h | 3 + src/gallium/drivers/radeonsi/si_build_pm4.h | 14 +++ .../drivers/radeonsi/si_cp_reg_shadowing.c | 1 + src/gallium/drivers/radeonsi/si_descriptors.c | 2 + src/gallium/drivers/radeonsi/si_pipe.c | 3 + src/gallium/drivers/radeonsi/si_pm4.c | 3 + 7 files changed, 113 insertions(+) diff --git a/src/amd/common/ac_shadowed_regs.c b/src/amd/common/ac_shadowed_regs.c index 1b7890835de..c7db0f17d45 100644 --- a/src/amd/common/ac_shadowed_regs.c +++ b/src/amd/common/ac_shadowed_regs.c @@ -28,8 +28,11 @@ */ #include "ac_shadowed_regs.h" +#include "ac_debug.h" #include "sid.h" #include "util/macros.h" +#include "util/u_debug.h" +#include 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"); + } + } +} diff --git a/src/amd/common/ac_shadowed_regs.h b/src/amd/common/ac_shadowed_regs.h index 616cd7467e6..b3f61db70b2 100644 --- a/src/amd/common/ac_shadowed_regs.h +++ b/src/amd/common/ac_shadowed_regs.h @@ -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 diff --git a/src/gallium/drivers/radeonsi/si_build_pm4.h b/src/gallium/drivers/radeonsi/si_build_pm4.h index f7f0e26d7d0..26a80fd7ecc 100644 --- a/src/gallium/drivers/radeonsi/si_build_pm4.h +++ b/src/gallium/drivers/radeonsi/si_build_pm4.h @@ -32,8 +32,16 @@ #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)); diff --git a/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c b/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c index ba03250b31e..bf8742d8686 100644 --- a/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c +++ b/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c @@ -23,6 +23,7 @@ */ #include "si_build_pm4.h" +#include "ac_debug.h" #include "ac_shadowed_regs.h" #include "util/u_memory.h" diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index ce5eba575b7..c2219bf09b4 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -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); } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 0e1cde2e25e..40c7270e46e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -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; } diff --git a/src/gallium/drivers/radeonsi/si_pm4.c b/src/gallium/drivers/radeonsi/si_pm4.c index a7d57258591..f3446267970 100644 --- a/src/gallium/drivers/radeonsi/si_pm4.c +++ b/src/gallium/drivers/radeonsi/si_pm4.c @@ -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; -- 2.30.2