zink: guarantee surface lifetimes for shader images

these may be unset from the ctx before the draw command has completed,
so we need (more) references to prevent that

Fixes: 3f9a6d333b ("zink: export shader image caps using features")

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8627>
This commit is contained in:
Mike Blumenkrantz 2020-08-07 10:00:13 -04:00 committed by Marge Bot
parent dab229ef69
commit 0376064783
4 changed files with 34 additions and 2 deletions

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);

View file

@ -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);