From eb75be66e92dd9bce01fb2c8cb78dd090cf925d2 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Fri, 27 Oct 2023 14:17:58 +0200 Subject: [PATCH] freedreno,tu: Add env vars to modify fd_dev_info We now have a lot of feature toggles in fd_dev_info. Generate env var options for all of them to quickly test whether feature misbehaves or test its impact on the performance. FD_DEV_FEATURES=%feature_name%=%value%:%feature_name%=%value%:... e.g. FD_DEV_FEATURES=has_fs_tex_prefetch=0:max_sets=4 Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/common/freedreno_dev_info.c | 15 +++- src/freedreno/common/freedreno_dev_info.h | 11 ++- src/freedreno/common/freedreno_devices.py | 72 ++++++++++++++++--- src/freedreno/computerator/a4xx.cc | 2 +- src/freedreno/computerator/a6xx.cc | 4 +- src/freedreno/decode/cffdump.c | 4 +- src/freedreno/decode/crashdec.c | 2 +- src/freedreno/decode/rdcompiler-utils.h | 2 +- src/freedreno/decode/rddecompiler.c | 4 +- src/freedreno/ds/fd_pps_driver.cc | 2 +- src/freedreno/ir3/tests/delay.c | 2 +- src/freedreno/ir3/tests/disasm.c | 4 +- src/freedreno/perfcntrs/fdperf.c | 2 +- src/freedreno/vulkan/tu_device.cc | 7 +- src/freedreno/vulkan/tu_device.h | 1 + .../drivers/freedreno/freedreno_screen.c | 7 +- .../drivers/freedreno/freedreno_screen.h | 1 + src/gallium/drivers/freedreno/gmemtool.c | 2 +- .../drivers/freedreno/ir3/ir3_cmdline.c | 2 +- 19 files changed, 112 insertions(+), 34 deletions(-) diff --git a/src/freedreno/common/freedreno_dev_info.c b/src/freedreno/common/freedreno_dev_info.c index a9bc2a5ba20..cb30c962f53 100644 --- a/src/freedreno/common/freedreno_dev_info.c +++ b/src/freedreno/common/freedreno_dev_info.c @@ -83,7 +83,7 @@ dev_id_compare(const struct fd_dev_id *ref, const struct fd_dev_id *id) } const struct fd_dev_info * -fd_dev_info(const struct fd_dev_id *id) +fd_dev_info_raw(const struct fd_dev_id *id) { for (int i = 0; i < ARRAY_SIZE(fd_dev_recs); i++) { if (dev_id_compare(&fd_dev_recs[i].id, id)) { @@ -93,6 +93,19 @@ fd_dev_info(const struct fd_dev_id *id) return NULL; } +const struct fd_dev_info +fd_dev_info(const struct fd_dev_id *id) +{ + struct fd_dev_info modified = {}; + const struct fd_dev_info *orig = fd_dev_info_raw(id); + if (orig) { + modified = *orig; + fd_dev_info_apply_dbg_options(&modified); + } + + return modified; +} + const char * fd_dev_name(const struct fd_dev_id *id) { diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h index c61274f8cba..0f33c1fcae3 100644 --- a/src/freedreno/common/freedreno_dev_info.h +++ b/src/freedreno/common/freedreno_dev_info.h @@ -233,12 +233,16 @@ fd_dev_gpu_id(const struct fd_dev_id *id) return id->gpu_id; } -const struct fd_dev_info * fd_dev_info(const struct fd_dev_id *id); +/* Unmodified dev info as defined in freedreno_devices.py */ +const struct fd_dev_info *fd_dev_info_raw(const struct fd_dev_id *id); + +/* Final dev info with dbg options and everything else applied. */ +const struct fd_dev_info fd_dev_info(const struct fd_dev_id *id); static uint8_t fd_dev_gen(const struct fd_dev_id *id) { - return fd_dev_info(id)->chip; + return fd_dev_info_raw(id)->chip; } static inline bool @@ -260,6 +264,9 @@ fd_dev_64b(const struct fd_dev_id *id) const char * fd_dev_name(const struct fd_dev_id *id); +void +fd_dev_info_apply_dbg_options(struct fd_dev_info *info); + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py index b67dc681fc4..1b6c974791f 100644 --- a/src/freedreno/common/freedreno_devices.py +++ b/src/freedreno/common/freedreno_devices.py @@ -283,19 +283,26 @@ add_gpus([ class A6XXProps(dict): - def apply_props(self, gpu_info): + unique_props = dict() + def apply_gen_props(self, gen, gpu_info): for name, val in self.items(): - if name == "magic": - continue - setattr(gpu_info.a6xx, name, val) + setattr(getattr(gpu_info, gen), name, val) + A6XXProps.unique_props[(name, gen)] = val - -class A7XXProps(dict): def apply_props(self, gpu_info): - for name, val in self.items(): - setattr(gpu_info.a7xx, name, val) + self.apply_gen_props("a6xx", gpu_info) +class A7XXProps(A6XXProps): + def apply_props(self, gpu_info): + self.apply_gen_props("a7xx", gpu_info) + + +# Props could be modified with env var: +# FD_DEV_FEATURES=%feature_name%=%value%:%feature_name%=%value%:... +# e.g. +# FD_DEV_FEATURES=has_fs_tex_prefetch=0:max_sets=4 + a6xx_base = A6XXProps( has_cp_reg_write = True, has_8bpp_ubwc = True, @@ -907,6 +914,10 @@ template = """\ */ #include "freedreno_dev_info.h" +#include "util/u_debug.h" +#include "util/log.h" + +#include /* Map python to C: */ #define True true @@ -921,7 +932,50 @@ static const struct fd_dev_rec fd_dev_recs[] = { { {${id.gpu_id}, ${hex(id.chip_id)}}, "${id.name}", &__info${s.info_index(info)} }, %endfor }; + +void +fd_dev_info_apply_dbg_options(struct fd_dev_info *info) +{ + const char *env = debug_get_option("FD_DEV_FEATURES", NULL); + if (!env || !*env) + return; + + char *features = strdup(env); + char *feature, *feature_end; + feature = strtok_r(features, ":", &feature_end); + while (feature != NULL) { + char *name, *name_end; + name = strtok_r(feature, "=", &name_end); + + if (!name) { + mesa_loge("Invalid feature \\"%s\\" in FD_DEV_FEATURES", feature); + exit(1); + } + + char *value = strtok_r(NULL, "=", &name_end); + + feature = strtok_r(NULL, ":", &feature_end); + +%for (prop, gen), val in unique_props.items(): + <% + if isinstance(val, bool): + parse_value = "debug_parse_bool_option" + else: + parse_value = "debug_parse_num_option" + %> + if (strcmp(name, "${prop}") == 0) { + info->${gen}.${prop} = ${parse_value}(value, info->${gen}.${prop}); + continue; + } +%endfor + + mesa_loge("Invalid feature \\"%s\\" in FD_DEV_FEATURES", name); + exit(1); + } + + free(features); +} """ -print(Template(template).render(s=s)) +print(Template(template).render(s=s, unique_props=A6XXProps.unique_props)) diff --git a/src/freedreno/computerator/a4xx.cc b/src/freedreno/computerator/a4xx.cc index a0b9e9debeb..6b8a69f8066 100644 --- a/src/freedreno/computerator/a4xx.cc +++ b/src/freedreno/computerator/a4xx.cc @@ -346,7 +346,7 @@ a4xx_init(struct fd_device *dev, const struct fd_dev_id *dev_id) struct ir3_compiler_options compiler_options = {}; a4xx_backend->compiler = - ir3_compiler_create(dev, dev_id, fd_dev_info(dev_id), &compiler_options); + ir3_compiler_create(dev, dev_id, fd_dev_info_raw(dev_id), &compiler_options); a4xx_backend->dev = dev; return &a4xx_backend->base; diff --git a/src/freedreno/computerator/a6xx.cc b/src/freedreno/computerator/a6xx.cc index f0b7e510355..6693e9e1ed9 100644 --- a/src/freedreno/computerator/a6xx.cc +++ b/src/freedreno/computerator/a6xx.cc @@ -611,10 +611,10 @@ a6xx_init(struct fd_device *dev, const struct fd_dev_id *dev_id) struct ir3_compiler_options compiler_options = {}; a6xx_backend->compiler = - ir3_compiler_create(dev, dev_id, fd_dev_info(dev_id), &compiler_options); + ir3_compiler_create(dev, dev_id, fd_dev_info_raw(dev_id), &compiler_options); a6xx_backend->dev = dev; - a6xx_backend->info = fd_dev_info(dev_id); + a6xx_backend->info = fd_dev_info_raw(dev_id); a6xx_backend->control_mem = fd_bo_new(dev, 0x1000, 0, "control"); diff --git a/src/freedreno/decode/cffdump.c b/src/freedreno/decode/cffdump.c index 4aed4e1d1ba..7cb183f9bf0 100644 --- a/src/freedreno/decode/cffdump.c +++ b/src/freedreno/decode/cffdump.c @@ -337,7 +337,7 @@ handle_file(const char *filename, int start, int end, int draw) options.dev_id.gpu_id = gpu_id; printl(2, "gpu_id: %d\n", options.dev_id.gpu_id); - options.info = fd_dev_info(&options.dev_id); + options.info = fd_dev_info_raw(&options.dev_id); if (!options.info) break; @@ -350,7 +350,7 @@ handle_file(const char *filename, int start, int end, int draw) options.dev_id.chip_id = parse_chip_id(ps.buf); printl(2, "chip_id: 0x%" PRIx64 "\n", options.dev_id.chip_id); - options.info = fd_dev_info(&options.dev_id); + options.info = fd_dev_info_raw(&options.dev_id); if (!options.info) break; diff --git a/src/freedreno/decode/crashdec.c b/src/freedreno/decode/crashdec.c index b2f97c20e07..e08f3da20e9 100644 --- a/src/freedreno/decode/crashdec.c +++ b/src/freedreno/decode/crashdec.c @@ -771,7 +771,7 @@ decode(void) &core, &major, &minor, &patchid); options.dev_id.chip_id = (core << 24) | (major << 16) | (minor << 8) | patchid; - options.info = fd_dev_info(&options.dev_id); + options.info = fd_dev_info_raw(&options.dev_id); if (!options.info) { printf("Unsupported device\n"); break; diff --git a/src/freedreno/decode/rdcompiler-utils.h b/src/freedreno/decode/rdcompiler-utils.h index 3db01864d42..45c4cc05c30 100644 --- a/src/freedreno/decode/rdcompiler-utils.h +++ b/src/freedreno/decode/rdcompiler-utils.h @@ -244,7 +244,7 @@ replay_context_init(struct replay_context *ctx, struct fd_dev_id *dev_id, struct ir3_compiler_options options{}; ctx->compiler = - ir3_compiler_create(NULL, dev_id, fd_dev_info(dev_id), &options); + ir3_compiler_create(NULL, dev_id, fd_dev_info_raw(dev_id), &options); ctx->compiled_shaders = _mesa_hash_table_u64_create(ctx->mem_ctx); } diff --git a/src/freedreno/decode/rddecompiler.c b/src/freedreno/decode/rddecompiler.c index db508591648..cd46987402c 100644 --- a/src/freedreno/decode/rddecompiler.c +++ b/src/freedreno/decode/rddecompiler.c @@ -589,13 +589,13 @@ handle_file(const char *filename, uint32_t submit_to_decompile) } case RD_GPU_ID: { dev_id.gpu_id = parse_gpu_id(ps.buf); - if (fd_dev_info(&dev_id)) + if (fd_dev_info_raw(&dev_id)) emit_header(); break; } case RD_CHIP_ID: { dev_id.chip_id = parse_chip_id(ps.buf); - if (fd_dev_info(&dev_id)) + if (fd_dev_info_raw(&dev_id)) emit_header(); break; } diff --git a/src/freedreno/ds/fd_pps_driver.cc b/src/freedreno/ds/fd_pps_driver.cc index 2ec20b9592c..e3d43a52b2b 100644 --- a/src/freedreno/ds/fd_pps_driver.cc +++ b/src/freedreno/ds/fd_pps_driver.cc @@ -483,7 +483,7 @@ FreedrenoDriver::init_perfcnt() for (const auto &countable : countables) countable.resolve(); - info = fd_dev_info(dev_id); + info = fd_dev_info_raw(dev_id); io = fd_dt_find_io(); if (!io) { diff --git a/src/freedreno/ir3/tests/delay.c b/src/freedreno/ir3/tests/delay.c index 25e2564db96..66e14c092a8 100644 --- a/src/freedreno/ir3/tests/delay.c +++ b/src/freedreno/ir3/tests/delay.c @@ -155,7 +155,7 @@ main(int argc, char **argv) .gpu_id = 630, }; - c = ir3_compiler_create(NULL, &dev_id, fd_dev_info(&dev_id), &(struct ir3_compiler_options){}); + c = ir3_compiler_create(NULL, &dev_id, fd_dev_info_raw(&dev_id), &(struct ir3_compiler_options){}); for (int i = 0; i < ARRAY_SIZE(tests); i++) { const struct test *test = &tests[i]; diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 56de28d7083..86b50288678 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -497,7 +497,7 @@ main(int argc, char **argv) .chip_id = test->chip_id, }; - const struct fd_dev_info *dev_info = fd_dev_info(&dev_id); + const struct fd_dev_info *dev_info = fd_dev_info_raw(&dev_id); rewind(fdisasm); memset(disasm_output, 0, output_size); @@ -537,7 +537,7 @@ main(int argc, char **argv) dev_ids[dev_info->chip].chip_id = test->chip_id; compilers[dev_info->chip] = ir3_compiler_create(NULL, &dev_ids[dev_info->chip], - fd_dev_info(&dev_ids[dev_info->chip]), + fd_dev_info_raw(&dev_ids[dev_info->chip]), &(struct ir3_compiler_options){}); } diff --git a/src/freedreno/perfcntrs/fdperf.c b/src/freedreno/perfcntrs/fdperf.c index 014580faef6..49d252f8c9f 100644 --- a/src/freedreno/perfcntrs/fdperf.c +++ b/src/freedreno/perfcntrs/fdperf.c @@ -147,7 +147,7 @@ find_device(void) dev.pipe = fd_pipe_new(dev.dev, FD_PIPE_3D); dev.dev_id = fd_pipe_dev_id(dev.pipe); - if (!fd_dev_info(dev.dev_id)) + if (!fd_dev_info_raw(dev.dev_id)) err(1, "unknown device"); printf("device: %s\n", fd_dev_name(dev.dev_id)); diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc index 8bc154c9572..eab62f8fa40 100644 --- a/src/freedreno/vulkan/tu_device.cc +++ b/src/freedreno/vulkan/tu_device.cc @@ -616,8 +616,8 @@ tu_physical_device_init(struct tu_physical_device *device, "device name alloc fail"); } - const struct fd_dev_info *info = fd_dev_info(&device->dev_id); - if (!info) { + const struct fd_dev_info info = fd_dev_info(&device->dev_id); + if (!info.chip) { result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED, "device %s is unsupported", device->name); goto fail_free_name; @@ -625,7 +625,8 @@ tu_physical_device_init(struct tu_physical_device *device, switch (fd_dev_gen(&device->dev_id)) { case 6: case 7: { - device->info = info; + device->dev_info = info; + device->info = &device->dev_info; uint32_t depth_cache_size = device->info->num_ccu * device->info->a6xx.sysmem_per_ccu_cache_size; uint32_t color_cache_size = diff --git a/src/freedreno/vulkan/tu_device.h b/src/freedreno/vulkan/tu_device.h index 074cdf769cb..e376ce5ca8b 100644 --- a/src/freedreno/vulkan/tu_device.h +++ b/src/freedreno/vulkan/tu_device.h @@ -109,6 +109,7 @@ struct tu_physical_device } memory; struct fd_dev_id dev_id; + struct fd_dev_info dev_info; const struct fd_dev_info *info; int msm_major_version; diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 6021e062bd8..6cadea8c2eb 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -1184,13 +1184,14 @@ fd_screen_create(int fd, DBG(" Chip-id: 0x%016"PRIx64, screen->chip_id); DBG(" GMEM size: 0x%08x", screen->gmemsize_bytes); - const struct fd_dev_info *info = fd_dev_info(screen->dev_id); - if (!info) { + const struct fd_dev_info info = fd_dev_info(screen->dev_id); + if (!info.chip) { mesa_loge("unsupported GPU: a%03d", screen->gpu_id); goto fail; } - screen->info = info; + screen->dev_info = info; + screen->info = &screen->dev_info; /* explicitly checking for GPU revisions that are known to work. This * may be overly conservative for a3xx, where spoofing the gpu_id with diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 48ec8812157..b23af9adf1f 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -98,6 +98,7 @@ struct fd_screen { bool enable_throttling; } driconf; + struct fd_dev_info dev_info; const struct fd_dev_info *info; uint32_t ccu_offset_gmem; uint32_t ccu_offset_bypass; diff --git a/src/gallium/drivers/freedreno/gmemtool.c b/src/gallium/drivers/freedreno/gmemtool.c index bb9ab7f41a6..96381d5eb09 100644 --- a/src/gallium/drivers/freedreno/gmemtool.c +++ b/src/gallium/drivers/freedreno/gmemtool.c @@ -170,7 +170,7 @@ main(int argc, char **argv) .gmemsize_bytes = gpu_info->gmemsize_bytes, }; - screen.info = fd_dev_info(&dev_id); + screen.info = fd_dev_info_raw(&dev_id); /* And finally run thru all the GMEM keys: */ for (int i = 0; i < ARRAY_SIZE(keys); i++) { diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index 9b97273f38e..c1a1528c67b 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -370,7 +370,7 @@ main(int argc, char **argv) struct fd_dev_id dev_id = { .gpu_id = gpu_id, }; - compiler = ir3_compiler_create(NULL, &dev_id, fd_dev_info(&dev_id), + compiler = ir3_compiler_create(NULL, &dev_id, fd_dev_info_raw(&dev_id), &(struct ir3_compiler_options) {}); if (from_tgsi) {