radv: add a helper function to upload a shader binary
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13690>
This commit is contained in:
committed by
Marge Bot
parent
dd66de6017
commit
ff61b36ba2
@@ -1567,12 +1567,99 @@ radv_postprocess_config(const struct radv_device *device, const struct ac_shader
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
radv_open_rtld_binary(struct radv_device *device, const struct radv_shader *shader,
|
||||
const struct radv_shader_binary *binary, struct ac_rtld_binary *rtld_binary)
|
||||
{
|
||||
const char *elf_data = (const char *)((struct radv_shader_binary_rtld *)binary)->data;
|
||||
size_t elf_size = ((struct radv_shader_binary_rtld *)binary)->elf_size;
|
||||
struct ac_rtld_symbol lds_symbols[2];
|
||||
unsigned num_lds_symbols = 0;
|
||||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9 &&
|
||||
(binary->stage == MESA_SHADER_GEOMETRY || binary->info.is_ngg) &&
|
||||
!binary->is_gs_copy_shader) {
|
||||
struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
|
||||
sym->name = "esgs_ring";
|
||||
sym->size = binary->info.ngg_info.esgs_ring_size;
|
||||
sym->align = 64 * 1024;
|
||||
}
|
||||
|
||||
if (binary->info.is_ngg && binary->stage == MESA_SHADER_GEOMETRY) {
|
||||
struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
|
||||
sym->name = "ngg_emit";
|
||||
sym->size = binary->info.ngg_info.ngg_emit_size * 4;
|
||||
sym->align = 4;
|
||||
}
|
||||
|
||||
struct ac_rtld_open_info open_info = {
|
||||
.info = &device->physical_device->rad_info,
|
||||
.shader_type = binary->stage,
|
||||
.wave_size = binary->info.wave_size,
|
||||
.num_parts = 1,
|
||||
.elf_ptrs = &elf_data,
|
||||
.elf_sizes = &elf_size,
|
||||
.num_shared_lds_symbols = num_lds_symbols,
|
||||
.shared_lds_symbols = lds_symbols,
|
||||
};
|
||||
|
||||
return ac_rtld_open(rtld_binary, open_info);
|
||||
}
|
||||
|
||||
static bool
|
||||
radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_binary *binary,
|
||||
struct radv_shader *shader)
|
||||
{
|
||||
void *dest_ptr;
|
||||
|
||||
dest_ptr = radv_alloc_shader_memory(device, shader);
|
||||
if (!dest_ptr) {
|
||||
free(shader);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (binary->type == RADV_BINARY_TYPE_RTLD) {
|
||||
struct ac_rtld_binary rtld_binary = {0};
|
||||
|
||||
if (!radv_open_rtld_binary(device, shader, binary, &rtld_binary)) {
|
||||
free(shader);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct ac_rtld_upload_info info = {
|
||||
.binary = &rtld_binary,
|
||||
.rx_va = radv_shader_get_va(shader),
|
||||
.rx_ptr = dest_ptr,
|
||||
};
|
||||
|
||||
if (!ac_rtld_upload(&info)) {
|
||||
radv_shader_destroy(device, shader);
|
||||
ac_rtld_close(&rtld_binary);
|
||||
return false;
|
||||
}
|
||||
|
||||
shader->code_ptr = dest_ptr;
|
||||
ac_rtld_close(&rtld_binary);
|
||||
} else {
|
||||
struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
|
||||
memcpy(dest_ptr, bin->data + bin->stats_size, bin->code_size);
|
||||
|
||||
/* Add end-of-code markers for the UMR disassembler. */
|
||||
uint32_t *ptr32 = (uint32_t *)dest_ptr + bin->code_size / 4;
|
||||
for (unsigned i = 0; i < DEBUGGER_NUM_MARKERS; i++)
|
||||
ptr32[i] = DEBUGGER_END_OF_CODE_MARKER;
|
||||
|
||||
shader->code_ptr = dest_ptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct radv_shader *
|
||||
radv_shader_create(struct radv_device *device, const struct radv_shader_binary *binary,
|
||||
bool keep_shader_info, bool from_cache, const struct radv_shader_args *args)
|
||||
{
|
||||
struct ac_shader_config config = {0};
|
||||
struct ac_rtld_binary rtld_binary = {0};
|
||||
struct radv_shader *shader = calloc(1, sizeof(struct radv_shader));
|
||||
if (!shader)
|
||||
return NULL;
|
||||
@@ -1580,39 +1667,9 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
|
||||
shader->ref_count = 1;
|
||||
|
||||
if (binary->type == RADV_BINARY_TYPE_RTLD) {
|
||||
struct ac_rtld_symbol lds_symbols[2];
|
||||
unsigned num_lds_symbols = 0;
|
||||
const char *elf_data = (const char *)((struct radv_shader_binary_rtld *)binary)->data;
|
||||
size_t elf_size = ((struct radv_shader_binary_rtld *)binary)->elf_size;
|
||||
struct ac_rtld_binary rtld_binary = {0};
|
||||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9 &&
|
||||
(binary->stage == MESA_SHADER_GEOMETRY || binary->info.is_ngg) &&
|
||||
!binary->is_gs_copy_shader) {
|
||||
struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
|
||||
sym->name = "esgs_ring";
|
||||
sym->size = binary->info.ngg_info.esgs_ring_size;
|
||||
sym->align = 64 * 1024;
|
||||
}
|
||||
|
||||
if (binary->info.is_ngg && binary->stage == MESA_SHADER_GEOMETRY) {
|
||||
struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
|
||||
sym->name = "ngg_emit";
|
||||
sym->size = binary->info.ngg_info.ngg_emit_size * 4;
|
||||
sym->align = 4;
|
||||
}
|
||||
|
||||
struct ac_rtld_open_info open_info = {
|
||||
.info = &device->physical_device->rad_info,
|
||||
.shader_type = binary->stage,
|
||||
.wave_size = binary->info.wave_size,
|
||||
.num_parts = 1,
|
||||
.elf_ptrs = &elf_data,
|
||||
.elf_sizes = &elf_size,
|
||||
.num_shared_lds_symbols = num_lds_symbols,
|
||||
.shared_lds_symbols = lds_symbols,
|
||||
};
|
||||
|
||||
if (!ac_rtld_open(&rtld_binary, open_info)) {
|
||||
if (!radv_open_rtld_binary(device, shader, binary, &rtld_binary)) {
|
||||
free(shader);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1634,6 +1691,7 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
|
||||
|
||||
shader->code_size = rtld_binary.rx_size;
|
||||
shader->exec_size = rtld_binary.exec_size;
|
||||
ac_rtld_close(&rtld_binary);
|
||||
} else {
|
||||
assert(binary->type == RADV_BINARY_TYPE_LEGACY);
|
||||
config = ((struct radv_shader_binary_legacy *)binary)->base.config;
|
||||
@@ -1652,25 +1710,15 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
|
||||
radv_postprocess_config(device, &config, &binary->info, binary->stage, args, &shader->config);
|
||||
}
|
||||
|
||||
void *dest_ptr = radv_alloc_shader_memory(device, shader);
|
||||
if (!dest_ptr) {
|
||||
if (binary->type == RADV_BINARY_TYPE_RTLD)
|
||||
ac_rtld_close(&rtld_binary);
|
||||
free(shader);
|
||||
if (!radv_shader_binary_upload(device, binary, shader))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (binary->type == RADV_BINARY_TYPE_RTLD) {
|
||||
struct radv_shader_binary_rtld *bin = (struct radv_shader_binary_rtld *)binary;
|
||||
struct ac_rtld_upload_info info = {
|
||||
.binary = &rtld_binary,
|
||||
.rx_va = radv_shader_get_va(shader),
|
||||
.rx_ptr = dest_ptr,
|
||||
};
|
||||
struct ac_rtld_binary rtld_binary = {0};
|
||||
|
||||
if (!ac_rtld_upload(&info)) {
|
||||
radv_shader_destroy(device, shader);
|
||||
ac_rtld_close(&rtld_binary);
|
||||
if (!radv_open_rtld_binary(device, shader, binary, &rtld_binary)) {
|
||||
free(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1690,19 +1738,10 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
|
||||
memcpy(shader->disasm_string, disasm_data, disasm_size);
|
||||
shader->disasm_string[disasm_size] = 0;
|
||||
}
|
||||
|
||||
shader->code_ptr = dest_ptr;
|
||||
ac_rtld_close(&rtld_binary);
|
||||
} else {
|
||||
struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
|
||||
memcpy(dest_ptr, bin->data + bin->stats_size, bin->code_size);
|
||||
|
||||
/* Add end-of-code markers for the UMR disassembler. */
|
||||
uint32_t *ptr32 = (uint32_t *)dest_ptr + bin->code_size / 4;
|
||||
for (unsigned i = 0; i < DEBUGGER_NUM_MARKERS; i++)
|
||||
ptr32[i] = DEBUGGER_END_OF_CODE_MARKER;
|
||||
|
||||
shader->code_ptr = dest_ptr;
|
||||
shader->ir_string =
|
||||
bin->ir_size ? strdup((const char *)(bin->data + bin->stats_size + bin->code_size)) : NULL;
|
||||
shader->disasm_string =
|
||||
|
||||
Reference in New Issue
Block a user