radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, pipeline->base.slab_bo);
+ /* With graphics pipeline library, binaries are uploaded from a library and they hold a pointer
+ * to the slab BO.
+ */
+ for (unsigned s = 0; s < MESA_VULKAN_SHADER_STAGES; s++) {
+ struct radv_shader *shader = pipeline->base.shaders[s];
+
+ if (!shader || !shader->bo)
+ continue;
+
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, shader->bo);
+ }
+
+ if (pipeline->base.gs_copy_shader && pipeline->base.gs_copy_shader->bo) {
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, pipeline->base.gs_copy_shader->bo);
+ }
+
if (unlikely(cmd_buffer->device->trace_bo))
radv_save_pipeline(cmd_buffer, &pipeline->base);
radv_pipeline_layout_finish(device, &gfx_pipeline_lib->layout);
for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
- if (pipeline->shaders[i]) {
- free(pipeline->shaders[i]->binary);
- pipeline->shaders[i]->binary = NULL;
- }
-
ralloc_free(pipeline->retained_shaders[i].nir);
}
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. */
if (!shader)
continue;
+ if (shader->bo)
+ continue;
+
code_size += align(shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
}
- if (pipeline->gs_copy_shader) {
+ if (pipeline->gs_copy_shader && !pipeline->gs_copy_shader->bo) {
code_size += align(pipeline->gs_copy_shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
}
if (!shader)
continue;
+ if (shader->bo)
+ continue;
+
shader->va = slab_va + slab_offset;
void *dest_ptr = slab_ptr + slab_offset;
slab_offset += align(shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
}
- if (pipeline->gs_copy_shader) {
+ 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 (pipeline->gs_copy_shader && !(flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR)) {
+ 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) {
- if (pipeline->shaders[i] && !(flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR)) {
+ if (pipeline->shaders[i]) {
free(pipeline->shaders[i]->binary);
pipeline->shaders[i]->binary = NULL;
}