zink: add more locking for pipeline cache

this ensures the size remains constant for entry updates

fixes #9494

cc: mesa-stable

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24559>
(cherry picked from commit 1c1e09249c)
This commit is contained in:
Mike Blumenkrantz 2023-08-08 09:25:35 -04:00 committed by Dylan Baker
parent 00ee04948b
commit b39929ed5c
5 changed files with 25 additions and 4 deletions

View file

@ -9344,7 +9344,7 @@
"description": "zink: add more locking for pipeline cache",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -428,8 +428,10 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
}
VkPipeline pipeline;
u_rwlock_wrlock(&prog->base.pipeline_cache_lock);
VkResult result = VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache,
1, &pci, NULL, &pipeline);
u_rwlock_wrunlock(&prog->base.pipeline_cache_lock);
if (result != VK_SUCCESS) {
mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
return VK_NULL_HANDLE;
@ -472,8 +474,10 @@ zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_pro
pci.stage = stage;
VkPipeline pipeline;
u_rwlock_wrlock(&comp->base.pipeline_cache_lock);
VkResult result = VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache,
1, &pci, NULL, &pipeline);
u_rwlock_wrunlock(&comp->base.pipeline_cache_lock);
if (result != VK_SUCCESS) {
mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result));
return VK_NULL_HANDLE;
@ -813,7 +817,10 @@ create_gfx_pipeline_library(struct zink_screen *screen, struct zink_shader_objec
VkPipeline
zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_program *prog)
{
return create_gfx_pipeline_library(screen, prog->objs, prog->base.layout, prog->base.pipeline_cache);
u_rwlock_wrlock(&prog->base.pipeline_cache_lock);
VkPipeline pipeline = create_gfx_pipeline_library(screen, prog->objs, prog->base.layout, prog->base.pipeline_cache);
u_rwlock_wrunlock(&prog->base.pipeline_cache_lock);
return pipeline;
}
VkPipeline
@ -851,11 +858,14 @@ zink_create_gfx_pipeline_combined(struct zink_screen *screen, struct zink_gfx_pr
pci.flags |= VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
VkPipeline pipeline;
u_rwlock_wrlock(&prog->base.pipeline_cache_lock);
if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
NULL, &pipeline) != VK_SUCCESS) {
mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
u_rwlock_wrunlock(&prog->base.pipeline_cache_lock);
return VK_NULL_HANDLE;
}
u_rwlock_wrunlock(&prog->base.pipeline_cache_lock);
return pipeline;
}

View file

@ -961,6 +961,7 @@ create_program(struct zink_context *ctx, bool is_compute)
return NULL;
pipe_reference_init(&pg->reference, 1);
u_rwlock_init(&pg->pipeline_cache_lock);
util_queue_fence_init(&pg->cache_fence);
pg->is_compute = is_compute;
pg->ctx = ctx;
@ -1494,6 +1495,7 @@ deinit_program(struct zink_screen *screen, struct zink_program *pg)
if (pg->pipeline_cache)
VKSCR(DestroyPipelineCache)(screen->dev, pg->pipeline_cache, NULL);
u_rwlock_destroy(&pg->pipeline_cache_lock);
zink_descriptor_program_deinit(screen, pg);
}

View file

@ -322,17 +322,24 @@ cache_put_job(void *data, void *gdata, int thread_index)
struct zink_program *pg = data;
struct zink_screen *screen = gdata;
size_t size = 0;
u_rwlock_rdlock(&pg->pipeline_cache_lock);
VkResult result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, NULL);
if (result != VK_SUCCESS) {
u_rwlock_rdunlock(&pg->pipeline_cache_lock);
mesa_loge("ZINK: vkGetPipelineCacheData failed (%s)", vk_Result_to_str(result));
return;
}
if (pg->pipeline_cache_size == size)
if (pg->pipeline_cache_size == size) {
u_rwlock_rdunlock(&pg->pipeline_cache_lock);
return;
}
void *pipeline_data = malloc(size);
if (!pipeline_data)
if (!pipeline_data) {
u_rwlock_rdunlock(&pg->pipeline_cache_lock);
return;
}
result = VKSCR(GetPipelineCacheData)(screen->dev, pg->pipeline_cache, &size, pipeline_data);
u_rwlock_rdunlock(&pg->pipeline_cache_lock);
if (result == VK_SUCCESS) {
pg->pipeline_cache_size = size;

View file

@ -42,6 +42,7 @@
#include "util/hash_table.h"
#include "util/list.h"
#include "util/log.h"
#include "util/rwlock.h"
#include "util/set.h"
#include "util/simple_mtx.h"
#include "util/slab.h"
@ -994,6 +995,7 @@ struct zink_program {
struct zink_context *ctx;
unsigned char sha1[20];
struct util_queue_fence cache_fence;
struct u_rwlock pipeline_cache_lock;
VkPipelineCache pipeline_cache;
size_t pipeline_cache_size;
struct zink_batch_usage *batch_uses;