diff --git a/src/amd/compiler/aco_interface.cpp b/src/amd/compiler/aco_interface.cpp index 7759464d833..5dde37b378f 100644 --- a/src/amd/compiler/aco_interface.cpp +++ b/src/amd/compiler/aco_interface.cpp @@ -266,7 +266,8 @@ aco_compile_vs_prolog(const struct aco_compiler_options* options, const struct aco_shader_info* info, const struct aco_vs_prolog_key* key, const struct radv_shader_args* args, - struct radv_shader_part_binary** binary) + aco_prolog_callback *build_prolog, + void **binary) { aco::init(); @@ -290,29 +291,18 @@ aco_compile_vs_prolog(const struct aco_compiler_options* options, code.reserve(align(program->blocks[0].instructions.size() * 2, 16)); unsigned exec_size = aco::emit_program(program.get(), code); - /* copy into binary */ - size_t size = code.size() * sizeof(uint32_t) + sizeof(radv_shader_part_binary); - bool get_disasm = options->dump_shader || options->record_ir; std::string disasm; - if (get_disasm) { + if (get_disasm) disasm = get_disasm_string(program.get(), code, exec_size); - size += disasm.size(); - } - radv_shader_part_binary* bin = (radv_shader_part_binary*)calloc(size, 1); - - bin->num_sgprs = config.num_sgprs; - bin->num_vgprs = config.num_vgprs; - bin->num_preserved_sgprs = num_preserved_sgprs; - bin->code_size = code.size() * sizeof(uint32_t); - memcpy(bin->data, code.data(), bin->code_size); - - if (get_disasm) { - disasm.copy((char*)bin->data + bin->code_size, disasm.size()); - bin->disasm_size = disasm.size(); - } - - *binary = bin; + (*build_prolog)(binary, + config.num_sgprs, + config.num_vgprs, + num_preserved_sgprs, + code.data(), + code.size(), + disasm.data(), + disasm.size()); } diff --git a/src/amd/compiler/aco_interface.h b/src/amd/compiler/aco_interface.h index 3a30929f871..f1b6b91c36a 100644 --- a/src/amd/compiler/aco_interface.h +++ b/src/amd/compiler/aco_interface.h @@ -56,6 +56,16 @@ typedef void (aco_callback)(void **priv_ptr, uint32_t exec_size, const uint32_t *code, uint32_t code_dw); + +typedef void (aco_prolog_callback)(void **priv_ptr, + uint32_t num_sgprs, + uint32_t num_vgprs, + uint32_t num_preserved_sgprs, + const uint32_t *code, + uint32_t code_size, + const char *disasm_str, + uint32_t disasm_size); + extern const unsigned aco_num_statistics; extern const struct aco_compiler_statistic_info* aco_statistic_infos; @@ -70,7 +80,8 @@ void aco_compile_vs_prolog(const struct aco_compiler_options* options, const struct aco_shader_info* info, const struct aco_vs_prolog_key* key, const struct radv_shader_args* args, - struct radv_shader_part_binary** binary); + aco_prolog_callback *build_prolog, + void **binary); uint64_t aco_get_codegen_flags(); diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 2f97821c88b..453f954fa7d 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -2329,6 +2329,33 @@ upload_shader_part(struct radv_device *device, struct radv_shader_part_binary *b return shader_part; } +static void radv_aco_build_prolog(void **bin, + uint32_t num_sgprs, + uint32_t num_vgprs, + uint32_t num_preserved_sgprs, + const uint32_t *code, + uint32_t code_size, + const char *disasm_str, + uint32_t disasm_size) +{ + struct radv_shader_part_binary **binary = (struct radv_shader_part_binary **)bin; + size_t size = code_size * sizeof(uint32_t) + sizeof(struct radv_shader_part_binary); + + size += disasm_size; + struct radv_shader_part_binary *prolog_binary = (struct radv_shader_part_binary *)calloc(size, 1); + + prolog_binary->num_sgprs = num_sgprs; + prolog_binary->num_vgprs = num_vgprs; + prolog_binary->num_preserved_sgprs = num_preserved_sgprs; + prolog_binary->code_size = code_size * sizeof(uint32_t); + memcpy(prolog_binary->data, code, prolog_binary->code_size); + if (disasm_size) + memcpy((char*)prolog_binary->data + prolog_binary->code_size, + disasm_str, disasm_size); + + *binary = prolog_binary; +} + struct radv_shader_part * radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_key *key) { @@ -2373,7 +2400,7 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke radv_aco_convert_shader_info(&ac_info, &info); radv_aco_convert_opts(&ac_opts, &options); radv_aco_convert_vs_prolog_key(&ac_key, key); - aco_compile_vs_prolog(&ac_opts, &ac_info, &ac_key, &args, &binary); + aco_compile_vs_prolog(&ac_opts, &ac_info, &ac_key, &args, &radv_aco_build_prolog, (void **)&binary); struct radv_shader_part *prolog = upload_shader_part(device, binary, info.wave_size); if (prolog) { prolog->nontrivial_divisors = key->state->nontrivial_divisors;