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 <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27616>
This commit is contained in:

committed by
Marge Bot

parent
e1644a2307
commit
a3f647fde1
@@ -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 <stdint.h>\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 <stdint.h>\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);
|
||||
|
@@ -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],
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user