From 2dce77c239396c5c507fddd47c63d9402e597bfc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 11 May 2022 14:48:07 +1000 Subject: [PATCH] aco/radv: provide a callback from aco shader building to build binary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This moves the radv specific code into radv, and calls back from aco into radv. This should allow easier radeonsi integration later. Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/aco_interface.cpp | 86 ++++++------------------------ src/amd/compiler/aco_interface.h | 16 +++++- src/amd/vulkan/radv_shader.c | 60 ++++++++++++++++++++- 3 files changed, 89 insertions(+), 73 deletions(-) diff --git a/src/amd/compiler/aco_interface.cpp b/src/amd/compiler/aco_interface.cpp index efb97664cdc..7759464d833 100644 --- a/src/amd/compiler/aco_interface.cpp +++ b/src/amd/compiler/aco_interface.cpp @@ -113,69 +113,13 @@ get_disasm_string(aco::Program* program, std::vector& code, return disasm; } -static void -aco_build_radv_shader_binary(struct radv_shader_binary **binary, - gl_shader_stage stage, - bool is_gs_copy_shader, - const ac_shader_config *config, - const char *llvm_ir_str, - unsigned llvm_ir_size, - const char *disasm_str, - unsigned disasm_size, - uint32_t *statistics, - uint32_t stats_size, - uint32_t exec_size, - const uint32_t *code, - uint32_t code_dw) -{ - size_t size = llvm_ir_size; - - size += disasm_size; - size += stats_size; - - size += code_dw * sizeof(uint32_t) + sizeof(radv_shader_binary_legacy); - - /* We need to calloc to prevent unintialized data because this will be used - * directly for the disk cache. Uninitialized data can appear because of - * padding in the struct or because legacy_binary->data can be at an offset - * from the start less than sizeof(radv_shader_binary_legacy). */ - radv_shader_binary_legacy *legacy_binary = (radv_shader_binary_legacy *)calloc(size, 1); - legacy_binary->base.type = RADV_BINARY_TYPE_LEGACY; - legacy_binary->base.stage = stage; - legacy_binary->base.is_gs_copy_shader = is_gs_copy_shader; - legacy_binary->base.total_size = size; - legacy_binary->base.config = *config; - - if (stats_size) - memcpy(legacy_binary->data, statistics, stats_size); - legacy_binary->stats_size = stats_size; - - memcpy(legacy_binary->data + legacy_binary->stats_size, code, - code_dw * sizeof(uint32_t)); - legacy_binary->exec_size = exec_size; - legacy_binary->code_size = code_dw * sizeof(uint32_t); - - legacy_binary->disasm_size = 0; - legacy_binary->ir_size = llvm_ir_size; - - memcpy((char*)legacy_binary->data + legacy_binary->stats_size + legacy_binary->code_size, - llvm_ir_str, llvm_ir_size); - - legacy_binary->disasm_size = disasm_size; - if (disasm_size) { - memcpy((char*)legacy_binary->data + legacy_binary->stats_size + - legacy_binary->code_size + llvm_ir_size, disasm_str, - disasm_size); - } - *binary = (radv_shader_binary*)legacy_binary; -} - void aco_compile_shader(const struct aco_compiler_options* options, const struct aco_shader_info* info, unsigned shader_count, struct nir_shader* const* shaders, const struct radv_shader_args *args, - struct radv_shader_binary** binary) + aco_callback *build_binary, + void **binary) { aco::init(); @@ -302,19 +246,19 @@ aco_compile_shader(const struct aco_compiler_options* options, if (program->collect_statistics) stats_size = aco::num_statistics * sizeof(uint32_t); - aco_build_radv_shader_binary(binary, - shaders[shader_count - 1]->info.stage, - args->is_gs_copy_shader, - &config, - llvm_ir.c_str(), - llvm_ir.size(), - disasm.c_str(), - disasm.size(), - program->statistics, - stats_size, - exec_size, - code.data(), - code.size()); + (*build_binary)(binary, + shaders[shader_count - 1]->info.stage, + args->is_gs_copy_shader, + &config, + llvm_ir.c_str(), + llvm_ir.size(), + disasm.c_str(), + disasm.size(), + program->statistics, + stats_size, + exec_size, + code.data(), + code.size()); } void diff --git a/src/amd/compiler/aco_interface.h b/src/amd/compiler/aco_interface.h index 133592b3e03..3a30929f871 100644 --- a/src/amd/compiler/aco_interface.h +++ b/src/amd/compiler/aco_interface.h @@ -43,6 +43,19 @@ struct aco_compiler_statistic_info { char desc[64]; }; +typedef void (aco_callback)(void **priv_ptr, + gl_shader_stage stage, + bool is_gs_copy_shader, + const struct ac_shader_config *config, + const char *llvm_ir_str, + unsigned llvm_ir_size, + const char *disasm_str, + unsigned disasm_size, + uint32_t *statistics, + uint32_t stats_size, + uint32_t exec_size, + const uint32_t *code, + uint32_t code_dw); extern const unsigned aco_num_statistics; extern const struct aco_compiler_statistic_info* aco_statistic_infos; @@ -50,7 +63,8 @@ void aco_compile_shader(const struct aco_compiler_options* options, const struct aco_shader_info* info, unsigned shader_count, struct nir_shader* const* shaders, const struct radv_shader_args *args, - struct radv_shader_binary** binary); + aco_callback *build_binary, + void **binary); void aco_compile_vs_prolog(const struct aco_compiler_options* options, const struct aco_shader_info* info, diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 15220d2aa1b..2f97821c88b 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -2071,6 +2071,64 @@ radv_dump_nir_shaders(struct nir_shader *const *shaders, int shader_count) return ret; } +static void +radv_aco_build_shader_binary(void **bin, + gl_shader_stage stage, + bool is_gs_copy_shader, + const struct ac_shader_config *config, + const char *llvm_ir_str, + unsigned llvm_ir_size, + const char *disasm_str, + unsigned disasm_size, + uint32_t *statistics, + uint32_t stats_size, + uint32_t exec_size, + const uint32_t *code, + uint32_t code_dw) +{ + struct radv_shader_binary **binary = (struct radv_shader_binary **)bin; + size_t size = llvm_ir_size; + + size += disasm_size; + size += stats_size; + + size += code_dw * sizeof(uint32_t) + sizeof(struct radv_shader_binary_legacy); + + /* We need to calloc to prevent unintialized data because this will be used + * directly for the disk cache. Uninitialized data can appear because of + * padding in the struct or because legacy_binary->data can be at an offset + * from the start less than sizeof(radv_shader_binary_legacy). */ + struct radv_shader_binary_legacy *legacy_binary = (struct radv_shader_binary_legacy *)calloc(size, 1); + legacy_binary->base.type = RADV_BINARY_TYPE_LEGACY; + legacy_binary->base.stage = stage; + legacy_binary->base.is_gs_copy_shader = is_gs_copy_shader; + legacy_binary->base.total_size = size; + legacy_binary->base.config = *config; + + if (stats_size) + memcpy(legacy_binary->data, statistics, stats_size); + legacy_binary->stats_size = stats_size; + + memcpy(legacy_binary->data + legacy_binary->stats_size, code, + code_dw * sizeof(uint32_t)); + legacy_binary->exec_size = exec_size; + legacy_binary->code_size = code_dw * sizeof(uint32_t); + + legacy_binary->disasm_size = 0; + legacy_binary->ir_size = llvm_ir_size; + + memcpy((char*)legacy_binary->data + legacy_binary->stats_size + legacy_binary->code_size, + llvm_ir_str, llvm_ir_size); + + legacy_binary->disasm_size = disasm_size; + if (disasm_size) { + memcpy((char*)legacy_binary->data + legacy_binary->stats_size + + legacy_binary->code_size + llvm_ir_size, disasm_str, + disasm_size); + } + *binary = (struct radv_shader_binary*)legacy_binary; +} + static struct radv_shader * shader_compile(struct radv_device *device, struct nir_shader *const *shaders, int shader_count, gl_shader_stage stage, struct radv_shader_info *info, const struct radv_shader_args *args, @@ -2116,7 +2174,7 @@ shader_compile(struct radv_device *device, struct nir_shader *const *shaders, in struct aco_compiler_options ac_opts; radv_aco_convert_opts(&ac_opts, options); radv_aco_convert_shader_info(&ac_info, info); - aco_compile_shader(&ac_opts, &ac_info, shader_count, shaders, args, &binary); + aco_compile_shader(&ac_opts, &ac_info, shader_count, shaders, args, &radv_aco_build_shader_binary, (void **)&binary); } binary->info = *info;