radv: restore uploading shaders individually instead of consecutively

The shaders were uploaded consecutively to fit a RGP constraint but
this was more like a workaround. This upload path doesn't work well for
graphics pipeline library and it was the main blocker for GPL caching.

This commit breaks capturing shaders with RGP if the offset between
shaders is too big. Next commit should fix it by using shaders reloc.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21078>
This commit is contained in:
Samuel Pitoiset
2022-10-12 14:26:39 +02:00
committed by Marge Bot
parent 533d0008c7
commit 69bd1c0c40
7 changed files with 38 additions and 189 deletions

View File

@@ -122,37 +122,6 @@ radv_pipeline_has_gs_copy_shader(const struct radv_pipeline *pipeline)
return !!pipeline->gs_copy_shader;
}
static struct radv_pipeline_slab *
radv_pipeline_slab_create(struct radv_device *device, struct radv_pipeline *pipeline,
uint32_t code_size)
{
struct radv_pipeline_slab *slab;
slab = calloc(1, sizeof(*slab));
if (!slab)
return NULL;
slab->ref_count = 1;
slab->alloc = radv_alloc_shader_memory(device, code_size, pipeline);
if (!slab->alloc) {
free(slab);
return NULL;
}
return slab;
}
void
radv_pipeline_slab_destroy(struct radv_device *device, struct radv_pipeline_slab *slab)
{
if (!p_atomic_dec_zero(&slab->ref_count))
return;
radv_free_shader_memory(device, slab->alloc);
free(slab);
}
void
radv_pipeline_destroy(struct radv_device *device, struct radv_pipeline *pipeline,
const VkAllocationCallbacks *allocator)
@@ -189,9 +158,6 @@ radv_pipeline_destroy(struct radv_device *device, struct radv_pipeline *pipeline
vk_free(&device->vk.alloc, gfx_pipeline_lib->base.state_data);
}
if (pipeline->slab)
radv_pipeline_slab_destroy(device, pipeline->slab);
for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i)
if (pipeline->shaders[i])
radv_shader_unref(device, pipeline->shaders[i]);
@@ -1021,23 +987,12 @@ radv_graphics_pipeline_import_lib(struct radv_graphics_pipeline *pipeline,
continue;
pipeline->base.shaders[s] = radv_shader_ref(lib->base.base.shaders[s]);
/* Hold a pointer to the slab BO to indicate the shader is already uploaded. */
pipeline->base.shaders[s]->bo = lib->base.base.slab_bo;
}
/* Import the GS copy shader if present. */
if (lib->base.base.gs_copy_shader) {
assert(!pipeline->base.gs_copy_shader);
pipeline->base.gs_copy_shader = radv_shader_ref(lib->base.base.gs_copy_shader);
/* Hold a pointer to the slab BO to indicate the shader is already uploaded. */
pipeline->base.gs_copy_shader->bo = lib->base.base.slab_bo;
}
/* Refcount the slab BO to make sure it's not freed when the library is destroyed. */
if (lib->base.base.slab) {
p_atomic_inc(&lib->base.base.slab->ref_count);
}
/* Import the PS epilog if present. */
@@ -2824,69 +2779,6 @@ non_uniform_access_callback(const nir_src *src, void *_)
return nir_chase_binding(*src).success ? 0x2 : 0x3;
}
VkResult
radv_upload_shaders(struct radv_device *device, struct radv_pipeline *pipeline,
struct radv_shader_binary **binaries, struct radv_shader_binary *gs_copy_binary)
{
uint32_t code_size = 0;
/* Compute the total code size. */
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
struct radv_shader *shader = pipeline->shaders[i];
if (!shader)
continue;
if (shader->bo)
continue;
code_size += align(shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
}
if (pipeline->gs_copy_shader && !pipeline->gs_copy_shader->bo) {
code_size += align(pipeline->gs_copy_shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
}
/* Allocate memory for all shader binaries. */
pipeline->slab = radv_pipeline_slab_create(device, pipeline, code_size);
if (!pipeline->slab)
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
pipeline->slab_bo = pipeline->slab->alloc->arena->bo;
/* Upload shader binaries. */
uint64_t slab_va = radv_buffer_get_va(pipeline->slab_bo);
uint32_t slab_offset = pipeline->slab->alloc->offset;
char *slab_ptr = pipeline->slab->alloc->arena->ptr;
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
struct radv_shader *shader = pipeline->shaders[i];
if (!shader)
continue;
if (shader->bo)
continue;
shader->va = slab_va + slab_offset;
void *dest_ptr = slab_ptr + slab_offset;
if (!radv_shader_binary_upload(device, binaries[i], shader, dest_ptr))
return VK_ERROR_OUT_OF_HOST_MEMORY;
slab_offset += align(shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
}
if (pipeline->gs_copy_shader && !pipeline->gs_copy_shader->bo) {
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))
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
return VK_SUCCESS;
}
static nir_ssa_def *
radv_adjust_vertex_fetch_alpha(nir_builder *b, enum ac_vs_input_alpha_adjust alpha_adjust,
nir_ssa_def *alpha)
@@ -3738,9 +3630,6 @@ radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline,
}
}
/* Upload shader binaries. */
radv_upload_shaders(device, &pipeline->base, binaries, gs_copy_binary);
if (!skip_shaders_cache) {
if (pipeline->base.gs_copy_shader) {
assert(!binaries[MESA_SHADER_COMPUTE] && !pipeline->base.shaders[MESA_SHADER_COMPUTE]);
@@ -5587,9 +5476,6 @@ radv_compute_pipeline_compile(struct radv_compute_pipeline *pipeline,
}
}
/* Upload compute shader binary. */
radv_upload_shaders(device, &pipeline->base, binaries, NULL);
if (!keep_executable_info) {
radv_pipeline_cache_insert_shaders(device, cache, hash, &pipeline->base, binaries,
stack_sizes ? *stack_sizes : NULL,