diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 18621aa238a..fa0ed8258bc 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -8,6 +8,7 @@ #include "zink_render_pass.h" #include "zink_resource.h" #include "zink_screen.h" +#include "zink_surface.h" #include "util/hash_table.h" #include "util/u_debug.h" @@ -39,6 +40,12 @@ zink_batch_release(struct zink_screen *screen, struct zink_batch *batch) } _mesa_set_clear(batch->sampler_views, NULL); + set_foreach(batch->surfaces, entry) { + struct pipe_surface *surf = (struct pipe_surface *)entry->key; + pipe_surface_reference(&surf, NULL); + } + _mesa_set_clear(batch->surfaces, NULL); + util_dynarray_foreach(&batch->zombie_samplers, VkSampler, samp) { vkDestroySampler(screen->dev, *samp, NULL); } @@ -164,3 +171,15 @@ zink_batch_reference_program(struct zink_batch *batch, pipe_reference(NULL, &prog->reference); } } + +void +zink_batch_reference_surface(struct zink_batch *batch, + struct zink_surface *surface) +{ + struct pipe_surface *surf = &surface->base; + struct set_entry *entry = _mesa_set_search(batch->surfaces, surf); + if (!entry) { + entry = _mesa_set_add(batch->surfaces, surf); + pipe_reference(NULL, &surf->reference); + } +} diff --git a/src/gallium/drivers/zink/zink_batch.h b/src/gallium/drivers/zink/zink_batch.h index ce49031dcb1..c543a063c21 100644 --- a/src/gallium/drivers/zink/zink_batch.h +++ b/src/gallium/drivers/zink/zink_batch.h @@ -37,6 +37,7 @@ struct zink_render_pass; struct zink_resource; struct zink_screen; struct zink_sampler_view; +struct zink_surface; #define ZINK_BATCH_DESC_SIZE 1000 @@ -52,6 +53,7 @@ struct zink_batch { struct set *resources; struct set *sampler_views; + struct set *surfaces; struct util_dynarray zombie_samplers; @@ -83,4 +85,8 @@ zink_batch_reference_sampler_view(struct zink_batch *batch, void zink_batch_reference_program(struct zink_batch *batch, struct zink_gfx_program *prog); + +void +zink_batch_reference_surface(struct zink_batch *batch, + struct zink_surface *surface); #endif diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index e87774f3fb3..9065660f10a 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1559,9 +1559,10 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->batches[i].resources = _mesa_pointer_set_create(NULL); ctx->batches[i].sampler_views = _mesa_pointer_set_create(NULL); ctx->batches[i].programs = _mesa_pointer_set_create(NULL); + ctx->batches[i].surfaces = _mesa_pointer_set_create(NULL); if (!ctx->batches[i].resources || !ctx->batches[i].sampler_views || - !ctx->batches[i].programs) + !ctx->batches[i].programs || !ctx->batches[i].surfaces) goto fail; util_dynarray_init(&ctx->batches[i].zombie_samplers, NULL); diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 73cd7bdb3a1..bb5b8d5a968 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -322,10 +322,11 @@ zink_draw_vbo(struct pipe_context *pctx, VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)]; struct zink_resource *read_desc_resources[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)] = {}; struct zink_resource *write_desc_resources[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)] = {}; + struct zink_surface *surface_refs[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_IMAGES] = {}; VkDescriptorBufferInfo buffer_infos[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)]; VkDescriptorImageInfo image_infos[PIPE_SHADER_TYPES * (PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_IMAGES)]; VkBufferView buffer_view[] = {VK_NULL_HANDLE}; - int num_wds = 0, num_buffer_info = 0, num_image_info = 0; + int num_wds = 0, num_buffer_info = 0, num_image_info = 0, num_surface_refs = 0; struct { struct zink_resource *res; @@ -413,6 +414,7 @@ zink_draw_vbo(struct pipe_context *pctx, case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { struct zink_image_view *image_view = &ctx->image_views[i][index + k]; assert(image_view); + surface_refs[num_surface_refs++] = image_view->surface; res = zink_resource(image_view->base.resource); if (!res) break; @@ -579,6 +581,10 @@ zink_draw_vbo(struct pipe_context *pctx, zink_batch_reference_resource_rw(batch, write_desc_resources[i], true); } vkUpdateDescriptorSets(screen->dev, num_wds, wds, 0, NULL); + for (int i = 0; i < num_surface_refs; i++) { + if (surface_refs[i]) + zink_batch_reference_surface(batch, surface_refs[i]); + } } vkCmdBindPipeline(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);