Mesa (master): zink: guarantee surface lifetimes for shader images
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Jan 25 22:59:13 UTC 2021
Module: Mesa
Branch: master
Commit: 0376064783eee6dd798e156836573c457909189d
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0376064783eee6dd798e156836573c457909189d
Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date: Fri Aug 7 10:00:13 2020 -0400
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: 3f9a6d333b3 ("zink: export shader image caps using features")
Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8627>
---
src/gallium/drivers/zink/zink_batch.c | 19 +++++++++++++++++++
src/gallium/drivers/zink/zink_batch.h | 6 ++++++
src/gallium/drivers/zink/zink_context.c | 3 ++-
src/gallium/drivers/zink/zink_draw.c | 8 +++++++-
4 files changed, 34 insertions(+), 2 deletions(-)
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);
More information about the mesa-commit
mailing list