zink: use a custom surface referencing function whenever unrefing a surface

pipe_surface_reference uses surface->context, which is not reliable when sharing
surfaces between contexts. since a surface will never be destroyed outside of
zink if its context is dead, forcing surfaces to go directly to the screen object
prevents accessing dead contexts

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9665>
This commit is contained in:
Mike Blumenkrantz 2021-03-19 17:17:08 -04:00
parent a9ab5b4f16
commit 9b544c1fe7
5 changed files with 18 additions and 5 deletions

View File

@ -51,7 +51,7 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs)
set_foreach(bs->surfaces, entry) {
struct zink_surface *surf = (struct zink_surface *)entry->key;
batch_usage_unset(&surf->batch_uses, !!bs->is_compute, bs->batch_id);
pipe_surface_reference((struct pipe_surface**)&surf, NULL);
zink_surface_reference(screen, &surf, NULL);
_mesa_set_remove(bs->surfaces, entry);
}
set_foreach(bs->bufferviews, entry) {

View File

@ -404,6 +404,7 @@ zink_clear_texture(struct pipe_context *pctx,
util_blitter_clear_depth_stencil(ctx->blitter, surf, flags, depth, stencil, box->x, box->y, box->width, box->height);
}
}
/* this will never destroy the surface */
pipe_surface_reference(&surf, NULL);
}

View File

@ -693,8 +693,7 @@ zink_sampler_view_destroy(struct pipe_context *pctx,
if (pview->texture->target == PIPE_BUFFER)
zink_buffer_view_reference(zink_screen(pctx->screen), &view->buffer_view, NULL);
else {
struct pipe_surface *psurf = &view->image_view->base;
pipe_surface_reference(&psurf, NULL);
zink_surface_reference(zink_screen(pctx->screen), &view->image_view, NULL);
}
pipe_resource_reference(&pview->texture, NULL);
FREE(view);
@ -924,7 +923,7 @@ unbind_shader_image(struct zink_context *ctx, enum pipe_shader_type stage, unsig
if (image_view->base.resource->target == PIPE_BUFFER)
zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
else
pipe_surface_reference((struct pipe_surface**)&image_view->surface, NULL);
zink_surface_reference(zink_screen(ctx->base.screen), &image_view->surface, NULL);
pipe_resource_reference(&image_view->base.resource, NULL);
image_view->base.resource = NULL;
image_view->surface = NULL;

View File

@ -74,7 +74,7 @@ zink_destroy_framebuffer(struct zink_screen *screen,
for (int i = 0; i < ARRAY_SIZE(fb->surfaces); ++i)
pipe_surface_reference(fb->surfaces + i, NULL);
pipe_surface_reference(&fb->null_surface, NULL);
zink_surface_reference(screen, (struct zink_surface**)&fb->null_surface, NULL);
ralloc_free(fb);
}

View File

@ -47,6 +47,19 @@ zink_surface(struct pipe_surface *pipe)
void
zink_destroy_surface(struct zink_screen *screen, struct pipe_surface *psurface);
static inline void
zink_surface_reference(struct zink_screen *screen, struct zink_surface **dst, struct zink_surface *src)
{
struct zink_surface *old_dst = *dst;
if (pipe_reference_described(old_dst ? &old_dst->base.reference : NULL,
src ? &src->base.reference : NULL,
(debug_reference_descriptor)
debug_describe_surface))
zink_destroy_surface(screen, &old_dst->base);
*dst = src;
}
void
zink_context_surface_init(struct pipe_context *context);