radv: add a pointer to radv_shader_binary in radv_shader

With GPL, we will have to keep the shader binary in the library for
uploading it later, so it's easier to have a pointer in radv_shader.
The shader binary will be freed when the library is destroyed.

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/18515>
This commit is contained in:
Samuel Pitoiset 2022-09-01 13:56:34 +02:00 committed by Marge Bot
parent e612f32e1a
commit f8d887527a
5 changed files with 65 additions and 61 deletions

View file

@ -3105,8 +3105,7 @@ non_uniform_access_callback(const nir_src *src, void *_)
VkResult
radv_upload_shaders(struct radv_device *device, struct radv_pipeline *pipeline,
struct radv_shader_binary **binaries, struct radv_shader_binary *gs_copy_binary)
radv_upload_shaders(struct radv_device *device, struct radv_pipeline *pipeline)
{
uint32_t code_size = 0;
@ -3143,7 +3142,7 @@ radv_upload_shaders(struct radv_device *device, struct radv_pipeline *pipeline,
shader->va = slab_va + slab_offset;
void *dest_ptr = slab_ptr + slab_offset;
if (!radv_shader_binary_upload(device, binaries[i], shader, dest_ptr))
if (!radv_shader_binary_upload(device, shader->binary, shader, dest_ptr))
return VK_ERROR_OUT_OF_HOST_MEMORY;
slab_offset += align(shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
@ -3153,7 +3152,8 @@ radv_upload_shaders(struct radv_device *device, struct radv_pipeline *pipeline,
pipeline->gs_copy_shader->va = slab_va + slab_offset;
void *dest_ptr = slab_ptr + slab_offset;
if (!radv_shader_binary_upload(device, gs_copy_binary, pipeline->gs_copy_shader, dest_ptr))
if (!radv_shader_binary_upload(device, pipeline->gs_copy_shader->binary,
pipeline->gs_copy_shader, dest_ptr))
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
@ -3518,8 +3518,7 @@ radv_pipeline_create_gs_copy_shader(struct radv_pipeline *pipeline,
struct radv_pipeline_stage *stages,
const struct radv_pipeline_key *pipeline_key,
const struct radv_pipeline_layout *pipeline_layout,
bool keep_executable_info, bool keep_statistic_info,
struct radv_shader_binary **gs_copy_binary)
bool keep_executable_info, bool keep_statistic_info)
{
struct radv_device *device = pipeline->device;
struct radv_shader_info info = {0};
@ -3548,7 +3547,7 @@ radv_pipeline_create_gs_copy_shader(struct radv_pipeline *pipeline,
info.inline_push_constant_mask = gs_copy_args.ac.inline_push_const_mask;
return radv_create_gs_copy_shader(device, stages[MESA_SHADER_GEOMETRY].nir, &info, &gs_copy_args,
gs_copy_binary, keep_executable_info, keep_statistic_info,
keep_executable_info, keep_statistic_info,
pipeline_key->optimisations_disabled);
}
@ -3557,9 +3556,7 @@ radv_pipeline_nir_to_asm(struct radv_pipeline *pipeline, struct radv_pipeline_st
const struct radv_pipeline_key *pipeline_key,
const struct radv_pipeline_layout *pipeline_layout,
bool keep_executable_info, bool keep_statistic_info,
gl_shader_stage last_vgt_api_stage,
struct radv_shader_binary **binaries,
struct radv_shader_binary **gs_copy_binary)
gl_shader_stage last_vgt_api_stage)
{
struct radv_device *device = pipeline->device;
unsigned active_stages = 0;
@ -3575,8 +3572,7 @@ radv_pipeline_nir_to_asm(struct radv_pipeline *pipeline, struct radv_pipeline_st
if (stages[MESA_SHADER_GEOMETRY].nir && !pipeline_has_ngg) {
pipeline->gs_copy_shader =
radv_pipeline_create_gs_copy_shader(pipeline, stages, pipeline_key, pipeline_layout,
keep_executable_info, keep_statistic_info,
gs_copy_binary);
keep_executable_info, keep_statistic_info);
}
for (int s = MESA_VULKAN_SHADER_STAGES - 1; s >= 0; s--) {
@ -3606,7 +3602,7 @@ radv_pipeline_nir_to_asm(struct radv_pipeline *pipeline, struct radv_pipeline_st
pipeline->shaders[s] = radv_shader_nir_to_asm(device, &stages[s], shaders, shader_count,
pipeline_key, keep_executable_info,
keep_statistic_info, &binaries[s]);
keep_statistic_info);
stages[s].feedback.duration += os_time_get_nano() - stage_start;
@ -3853,8 +3849,6 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout
gl_shader_stage *last_vgt_api_stage)
{
const char *noop_fs_entrypoint = "noop_fs";
struct radv_shader_binary *binaries[MESA_VULKAN_SHADER_STAGES] = {NULL};
struct radv_shader_binary *gs_copy_binary = NULL;
unsigned char hash[20];
bool keep_executable_info =
(flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR) ||
@ -4029,7 +4023,7 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout
/* Compile NIR shaders to AMD assembly. */
radv_pipeline_nir_to_asm(pipeline, stages, pipeline_key, pipeline_layout, keep_executable_info,
keep_statistic_info, *last_vgt_api_stage, binaries, &gs_copy_binary);
keep_statistic_info, *last_vgt_api_stage);
if (keep_executable_info) {
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
@ -4047,29 +4041,35 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout
}
/* Upload shader binaries. */
radv_upload_shaders(device, pipeline, binaries, gs_copy_binary);
radv_upload_shaders(device, pipeline);
if (!keep_executable_info) {
if (pipeline->gs_copy_shader) {
assert(!binaries[MESA_SHADER_COMPUTE] && !pipeline->shaders[MESA_SHADER_COMPUTE]);
binaries[MESA_SHADER_COMPUTE] = gs_copy_binary;
assert(!pipeline->shaders[MESA_SHADER_COMPUTE]);
pipeline->shaders[MESA_SHADER_COMPUTE] = pipeline->gs_copy_shader;
}
radv_pipeline_cache_insert_shaders(device, cache, hash, pipeline, binaries,
radv_pipeline_cache_insert_shaders(device, cache, hash, pipeline,
stack_sizes ? *stack_sizes : NULL,
num_stack_sizes ? *num_stack_sizes : 0);
if (pipeline->gs_copy_shader) {
pipeline->gs_copy_shader = pipeline->shaders[MESA_SHADER_COMPUTE];
pipeline->shaders[MESA_SHADER_COMPUTE] = NULL;
binaries[MESA_SHADER_COMPUTE] = NULL;
}
}
free(gs_copy_binary);
if (pipeline->gs_copy_shader) {
free(pipeline->gs_copy_shader->binary);
pipeline->gs_copy_shader->binary = NULL;
}
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
free(binaries[i]);
if (pipeline->shaders[i]) {
free(pipeline->shaders[i]->binary);
pipeline->shaders[i]->binary = NULL;
}
if (stages[i].nir) {
if (radv_can_dump_shader_stats(device, stages[i].nir) && pipeline->shaders[i]) {
radv_dump_shader_stats(device, pipeline, i, stderr);

View file

@ -367,8 +367,6 @@ radv_create_shaders_from_pipeline_cache(
}
}
struct radv_shader_binary *binaries[MESA_VULKAN_SHADER_STAGES] = {NULL};
struct radv_shader_binary *gs_copy_binary = NULL;
bool needs_upload = false;
char *p = entry->code;
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
@ -380,7 +378,6 @@ radv_create_shaders_from_pipeline_cache(
entry->shaders[i] = radv_shader_create(device, binary, false, true, NULL);
needs_upload = true;
binaries[i] = binary;
} else if (entry->binary_sizes[i]) {
p += entry->binary_sizes[i];
}
@ -393,17 +390,22 @@ radv_create_shaders_from_pipeline_cache(
/* For the GS copy shader, RADV uses the compute shader slot to avoid a new cache entry. */
pipeline->gs_copy_shader = pipeline->shaders[MESA_SHADER_COMPUTE];
pipeline->shaders[MESA_SHADER_COMPUTE] = NULL;
gs_copy_binary = binaries[MESA_SHADER_COMPUTE];
}
if (needs_upload) {
result = radv_upload_shaders(device, pipeline, binaries, gs_copy_binary);
result = radv_upload_shaders(device, pipeline);
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
if (pipeline->shaders[i])
free(binaries[i]);
if (pipeline->shaders[i]) {
free(pipeline->shaders[i]->binary);
pipeline->shaders[i]->binary = NULL;
}
}
if (pipeline->gs_copy_shader) {
free(pipeline->gs_copy_shader->binary);
pipeline->gs_copy_shader->binary = NULL;
}
free(gs_copy_binary);
if (result != VK_SUCCESS) {
radv_pipeline_cache_unlock(cache);
@ -445,7 +447,6 @@ radv_create_shaders_from_pipeline_cache(
void
radv_pipeline_cache_insert_shaders(struct radv_device *device, struct radv_pipeline_cache *cache,
const unsigned char *sha1, struct radv_pipeline *pipeline,
struct radv_shader_binary *const *binaries,
const struct radv_pipeline_shader_stack_size *stack_sizes,
uint32_t num_stack_sizes)
{
@ -483,9 +484,14 @@ radv_pipeline_cache_insert_shaders(struct radv_device *device, struct radv_pipel
}
size_t size = sizeof(*entry) + sizeof(*stack_sizes) * num_stack_sizes;
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i)
if (pipeline->shaders[i])
size += binaries[i]->total_size;
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
struct radv_shader *shader = pipeline->shaders[i];
if (!shader)
continue;
size += shader->binary->total_size;
}
const size_t size_without_align = size;
size = align(size_without_align, alignof(struct cache_entry));
@ -501,13 +507,15 @@ radv_pipeline_cache_insert_shaders(struct radv_device *device, struct radv_pipel
char *p = entry->code;
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
if (!pipeline->shaders[i])
struct radv_shader *shader = pipeline->shaders[i];
if (!shader)
continue;
entry->binary_sizes[i] = binaries[i]->total_size;
entry->binary_sizes[i] = shader->binary->total_size;
memcpy(p, binaries[i], binaries[i]->total_size);
p += binaries[i]->total_size;
memcpy(p, shader->binary, shader->binary->total_size);
p += shader->binary->total_size;
}
if (num_stack_sizes) {

View file

@ -401,12 +401,10 @@ bool radv_create_shaders_from_pipeline_cache(
void radv_pipeline_cache_insert_shaders(
struct radv_device *device, struct radv_pipeline_cache *cache, const unsigned char *sha1,
struct radv_pipeline *pipeline, struct radv_shader_binary *const *binaries,
const struct radv_pipeline_shader_stack_size *stack_sizes, uint32_t num_stack_sizes);
struct radv_pipeline *pipeline, const struct radv_pipeline_shader_stack_size *stack_sizes,
uint32_t num_stack_sizes);
VkResult radv_upload_shaders(struct radv_device *device, struct radv_pipeline *pipeline,
struct radv_shader_binary **binaries,
struct radv_shader_binary *gs_copy_binary);
VkResult radv_upload_shaders(struct radv_device *device, struct radv_pipeline *pipeline);
enum radv_blit_ds_layout {
RADV_BLIT_DS_LAYOUT_TILE_ENABLE,

View file

@ -1990,7 +1990,7 @@ radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_b
}
struct radv_shader *
radv_shader_create(struct radv_device *device, const struct radv_shader_binary *binary,
radv_shader_create(struct radv_device *device, struct radv_shader_binary *binary,
bool keep_shader_info, bool from_cache, const struct radv_shader_args *args)
{
struct ac_shader_config config = {0};
@ -1999,6 +1999,7 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
return NULL;
shader->ref_count = 1;
shader->binary = binary;
if (binary->type == RADV_BINARY_TYPE_RTLD) {
struct ac_rtld_binary rtld_binary = {0};
@ -2175,8 +2176,7 @@ static struct radv_shader *
shader_compile(struct radv_device *device, struct nir_shader *const *shaders, int shader_count, gl_shader_stage stage,
const struct radv_shader_info *info, const struct radv_shader_args *args,
struct radv_nir_compiler_options *options, bool gs_copy_shader,
bool trap_handler_shader, bool keep_shader_info, bool keep_statistic_info,
struct radv_shader_binary **binary_out)
bool trap_handler_shader, bool keep_shader_info, bool keep_statistic_info)
{
enum radeon_family chip_family = device->physical_device->rad_info.family;
struct radv_shader_binary *binary = NULL;
@ -2242,7 +2242,6 @@ shader_compile(struct radv_device *device, struct nir_shader *const *shaders, in
/* Copy the shader binary configuration to store it in the cache. */
memcpy(&binary->config, &shader->config, sizeof(binary->config));
*binary_out = binary;
return shader;
}
@ -2250,7 +2249,7 @@ struct radv_shader *
radv_shader_nir_to_asm(struct radv_device *device, struct radv_pipeline_stage *pl_stage,
struct nir_shader *const *shaders, int shader_count,
const struct radv_pipeline_key *key, bool keep_shader_info,
bool keep_statistic_info, struct radv_shader_binary **binary_out)
bool keep_statistic_info)
{
gl_shader_stage stage = shaders[shader_count - 1]->info.stage;
struct radv_nir_compiler_options options = {0};
@ -2263,14 +2262,14 @@ radv_shader_nir_to_asm(struct radv_device *device, struct radv_pipeline_stage *p
return shader_compile(device, shaders, shader_count, stage, &pl_stage->info,
&pl_stage->args, &options, false, false, keep_shader_info,
keep_statistic_info, binary_out);
keep_statistic_info);
}
struct radv_shader *
radv_create_gs_copy_shader(struct radv_device *device, struct nir_shader *shader,
const struct radv_shader_info *info, const struct radv_shader_args *args,
struct radv_shader_binary **binary_out, bool keep_shader_info,
bool keep_statistic_info, bool disable_optimizations)
bool keep_shader_info, bool keep_statistic_info,
bool disable_optimizations)
{
struct radv_nir_compiler_options options = {0};
gl_shader_stage stage = MESA_SHADER_VERTEX;
@ -2278,7 +2277,7 @@ radv_create_gs_copy_shader(struct radv_device *device, struct nir_shader *shader
options.key.optimisations_disabled = disable_optimizations;
return shader_compile(device, &shader, 1, stage, info, args, &options, true, false,
keep_shader_info, keep_statistic_info, binary_out);
keep_shader_info, keep_statistic_info);
}
struct radv_trap_handler_shader *
@ -2286,7 +2285,6 @@ radv_create_trap_handler_shader(struct radv_device *device)
{
struct radv_nir_compiler_options options = {0};
struct radv_shader *shader = NULL;
struct radv_shader_binary *binary = NULL;
struct radv_shader_info info = {0};
struct radv_pipeline_key key = {0};
struct radv_trap_handler_shader *trap;
@ -2307,19 +2305,19 @@ radv_create_trap_handler_shader(struct radv_device *device)
MESA_SHADER_COMPUTE, false, MESA_SHADER_VERTEX, &args);
shader = shader_compile(device, &b.shader, 1, MESA_SHADER_COMPUTE, &info, &args, &options,
false, true, false, false, &binary);
false, true, false, false);
trap->alloc = radv_alloc_shader_memory(device, shader->code_size, NULL);
trap->bo = trap->alloc->arena->bo;
char *dest_ptr = trap->alloc->arena->ptr + trap->alloc->offset;
struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)shader->binary;
memcpy(dest_ptr, bin->data, bin->code_size);
ralloc_free(b.shader);
free(shader->binary);
free(shader);
free(binary);
return trap;
}
@ -2520,6 +2518,7 @@ radv_shader_destroy(struct radv_device *device, struct radv_shader *shader)
{
assert(shader->ref_count == 0);
free(shader->binary);
free(shader->spirv);
free(shader->nir_string);
free(shader->disasm_string);

View file

@ -485,6 +485,7 @@ struct radv_shader {
uint32_t code_size;
uint32_t exec_size;
struct radv_shader_info info;
struct radv_shader_binary *binary;
/* debug only */
char *spirv;
@ -557,13 +558,12 @@ VkResult radv_create_shaders(struct radv_pipeline *pipeline,
struct radv_shader_args;
struct radv_shader *radv_shader_create(struct radv_device *device,
const struct radv_shader_binary *binary,
struct radv_shader_binary *binary,
bool keep_shader_info, bool from_cache,
const struct radv_shader_args *args);
struct radv_shader *radv_shader_nir_to_asm(
struct radv_device *device, struct radv_pipeline_stage *stage, struct nir_shader *const *shaders,
int shader_count, const struct radv_pipeline_key *key, bool keep_shader_info, bool keep_statistic_info,
struct radv_shader_binary **binary_out);
int shader_count, const struct radv_pipeline_key *key, bool keep_shader_info, bool keep_statistic_info);
bool radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_binary *binary,
struct radv_shader *shader, void *dest_ptr);
@ -575,7 +575,6 @@ void radv_free_shader_memory(struct radv_device *device, union radv_shader_arena
struct radv_shader *
radv_create_gs_copy_shader(struct radv_device *device, struct nir_shader *nir,
const struct radv_shader_info *info, const struct radv_shader_args *args,
struct radv_shader_binary **binary_out,
bool keep_shader_info, bool keep_statistic_info,
bool disable_optimizations);