From a3f647fde104ca5fdfabb2694de78bbde56093f3 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 9 Feb 2024 12:34:50 -0400 Subject: [PATCH] asahi: precompile helper program 1. avoids cluttering shaders,internal print 2. reduces screen create overhead. this cuts average "glxinfo" runtime by about 25%, and seems to shave maybe 0.5% off the CTS job. 3. enforces helper program builds successfully as a build-time assertion 4. reduces the libagx generated blob for now, since g13 binaries are more compact than serialized NIR Closes https://gitlab.freedesktop.org/asahi/mesa/-/issues/37 Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/clc/asahi_clc.c | 40 ++++++++++++++++++++++++++++++++++--- src/asahi/clc/meson.build | 2 +- src/asahi/lib/agx_scratch.c | 27 ++++--------------------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/asahi/clc/asahi_clc.c b/src/asahi/clc/asahi_clc.c index 9c21d612c5d..9e6028ad0fb 100644 --- a/src/asahi/clc/asahi_clc.c +++ b/src/asahi/clc/asahi_clc.c @@ -260,7 +260,6 @@ print_u32_data(FILE *fp, const char *prefix, const char *arr_name, const uint32_t *data, size_t len) { assert(len % 4 == 0); - fprintf(fp, "#include \n"); fprintf(fp, "static const uint32_t %s_%s[] = {", prefix, arr_name); for (unsigned i = 0; i < (len / 4); i++) { if (i % 4 == 0) @@ -489,12 +488,47 @@ main(int argc, char **argv) fprintf(fp, " *\n"); fprintf(fp, " * Autogenerated file, do not edit\n"); fprintf(fp, " */\n"); - spirv_library_to_nir_builder(fp, final_spirv.data, final_spirv.size / 4, - &spirv_options); + fprintf(fp, " #include \n"); /* Compile SPIR-V to NIR */ nir_shader *nir = compile(NULL, final_spirv.data, final_spirv.size); + { + struct util_dynarray binary; + util_dynarray_init(&binary, NULL); + + nir_builder b = nir_builder_init_simple_shader( + MESA_SHADER_COMPUTE, &agx_nir_options, "Helper shader"); + + nir_function *func = + nir_shader_get_function_for_name(nir, "libagx_helper"); + + nir_call(&b, nir_function_clone(b.shader, func)); + + UNUSED struct agx_uncompiled_shader_info info; + UNUSED struct agx_shader_info compiled_info; + struct agx_shader_key key = {.libagx = nir}; + + agx_preprocess_nir(b.shader, nir, false, &info); + agx_compile_shader_nir(b.shader, &key, NULL, &binary, &compiled_info); + + /* Pad out */ + uint8_t zero = 0; + while (binary.size % 4) { + util_dynarray_append(&binary, uint8_t, zero); + } + + print_u32_data(fp, "libagx_g13", "helper", binary.data, binary.size); + util_dynarray_fini(&binary); + ralloc_free(b.shader); + + /* Remove the NIR function, it's compiled, we don't need it at runtime */ + exec_node_remove(&func->node); + } + + spirv_library_to_nir_builder(fp, final_spirv.data, final_spirv.size / 4, + &spirv_options); + /* Serialize NIR for embedding */ struct blob blob; blob_init(&blob); diff --git a/src/asahi/clc/meson.build b/src/asahi/clc/meson.build index a8680cd00de..5db547ffde5 100644 --- a/src/asahi/clc/meson.build +++ b/src/asahi/clc/meson.build @@ -4,7 +4,7 @@ prog_asahi_clc = executable( 'asahi_clc', ['asahi_clc.c'], - link_with : [], + link_with : [libasahi_compiler], include_directories : [inc_include, inc_src], c_args : [pre_args, no_override_init_args], link_args : [ld_args_build_id], diff --git a/src/asahi/lib/agx_scratch.c b/src/asahi/lib/agx_scratch.c index 4312c069ee6..6d05e2c01bf 100644 --- a/src/asahi/lib/agx_scratch.c +++ b/src/asahi/lib/agx_scratch.c @@ -32,30 +32,11 @@ struct spill_size { struct agx_bo * agx_build_helper(struct agx_device *dev) { - struct agx_bo *bo; - struct util_dynarray binary; - - util_dynarray_init(&binary, NULL); - - nir_builder b = nir_builder_init_simple_shader( - MESA_SHADER_COMPUTE, &agx_nir_options, "Helper shader"); - - libagx_helper(&b); - - UNUSED struct agx_uncompiled_shader_info info; - UNUSED struct agx_shader_info compiled_info; - struct agx_shader_key key = {.libagx = dev->libagx}; - - agx_preprocess_nir(b.shader, dev->libagx, false, &info); - agx_compile_shader_nir(b.shader, &key, NULL, &binary, &compiled_info); - - bo = agx_bo_create(dev, binary.size, - AGX_BO_READONLY | AGX_BO_EXEC | AGX_BO_LOW_VA, - "Helper shader"); + struct agx_bo *bo = agx_bo_create( + dev, sizeof(libagx_g13_helper), + AGX_BO_READONLY | AGX_BO_EXEC | AGX_BO_LOW_VA, "Helper shader"); assert(bo); - memcpy(bo->ptr.cpu, binary.data, binary.size); - util_dynarray_fini(&binary); - ralloc_free(b.shader); + memcpy(bo->ptr.cpu, libagx_g13_helper, sizeof(libagx_g13_helper)); if (dev->debug & AGX_DBG_SCRATCH) fprintf(stderr, "Helper: 0x%" PRIx64 "\n", bo->ptr.gpu);