}
}
+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;
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;
-
- 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,
- };
+ struct ac_rtld_binary rtld_binary = {0};
- if (!ac_rtld_open(&rtld_binary, open_info)) {
+ if (!radv_open_rtld_binary(device, shader, binary, &rtld_binary)) {
free(shader);
return NULL;
}
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;
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;
}
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 =