aco/radv: provide a callback from aco shader building to build binary

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 <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16445>
This commit is contained in:
Dave Airlie
2022-05-11 14:48:07 +10:00
committed by Marge Bot
parent e5ec50b3c7
commit 2dce77c239
3 changed files with 89 additions and 73 deletions

View File

@@ -113,69 +113,13 @@ get_disasm_string(aco::Program* program, std::vector<uint32_t>& 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

View File

@@ -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,

View File

@@ -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;