zink: don't handle mutable init on surface creation with tc enabled

using the cmdbuf during this call is illegal and causes desync, thus
the initialization has to be deferred until the surface is bound

fixes #7579

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21292>
This commit is contained in:
Mike Blumenkrantz 2023-02-13 14:56:06 -05:00 committed by Marge Bot
parent 44ce7ee6c1
commit 64708f9316
3 changed files with 41 additions and 4 deletions

View file

@ -3139,6 +3139,22 @@ zink_set_color_write_enables(struct zink_context *ctx)
}
}
static void
check_framebuffer_surface_mutable(struct pipe_context *pctx, struct pipe_surface *psurf)
{
struct zink_context *ctx = zink_context(pctx);
struct zink_ctx_surface *csurf = (struct zink_ctx_surface *)psurf;
if (!csurf->needs_mutable)
return;
zink_resource_object_init_mutable(ctx, zink_resource(psurf->texture));
struct pipe_surface *psurf2 = pctx->create_surface(pctx, psurf->texture, psurf);
pipe_resource_reference(&psurf2->texture, NULL);
struct zink_ctx_surface *csurf2 = (struct zink_ctx_surface *)psurf2;
zink_surface_reference(zink_screen(pctx->screen), &csurf->surf, csurf2->surf);
pctx->surface_destroy(pctx, psurf2);
csurf->needs_mutable = false;
}
static void
zink_set_framebuffer_state(struct pipe_context *pctx,
const struct pipe_framebuffer_state *state)
@ -3225,6 +3241,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
if (!samples)
samples = MAX3(transient ? transient->base.nr_samples : 1, psurf->texture->nr_samples, psurf->nr_samples ? psurf->nr_samples : 1);
struct zink_resource *res = zink_resource(psurf->texture);
check_framebuffer_surface_mutable(pctx, psurf);
if (zink_csurface(psurf)->info.layerCount > layers)
ctx->fb_layer_mismatch |= BITFIELD_BIT(i);
if (res->modifiers) {
@ -3254,6 +3271,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
if (ctx->fb_state.zsbuf) {
struct pipe_surface *psurf = ctx->fb_state.zsbuf;
struct zink_surface *transient = zink_transient_surface(psurf);
check_framebuffer_surface_mutable(pctx, psurf);
if (transient || psurf->nr_samples)
ctx->transient_attachments |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
if (!samples)

View file

@ -272,10 +272,18 @@ zink_create_surface(struct pipe_context *pctx,
{
struct zink_resource *res = zink_resource(pres);
bool is_array = templ->u.tex.last_layer != templ->u.tex.first_layer;
bool needs_mutable = false;
enum pipe_texture_target target_2d[] = {PIPE_TEXTURE_2D, PIPE_TEXTURE_2D_ARRAY};
if (!res->obj->dt && pres->format != templ->format)
if (!res->obj->dt && pres->format != templ->format) {
/* mutable not set by default */
needs_mutable = !(res->base.b.bind & ZINK_BIND_MUTABLE);
}
if (!zink_screen(pctx->screen)->threaded && needs_mutable) {
/* this is fine without tc */
needs_mutable = false;
zink_resource_object_init_mutable(zink_context(pctx), res);
}
if (!zink_get_format(zink_screen(pctx->screen), templ->format))
return NULL;
@ -291,12 +299,19 @@ zink_create_surface(struct pipe_context *pctx,
surface->is_swapchain = true;
psurf = &surface->base;
}
} else
} else if (!needs_mutable) {
psurf = zink_get_surface(zink_context(pctx), pres, templ, &ivci);
if (!psurf)
}
if (!psurf && !needs_mutable)
return NULL;
struct zink_ctx_surface *csurf = (struct zink_ctx_surface*)wrap_surface(pctx, psurf);
struct zink_ctx_surface *csurf = (struct zink_ctx_surface*)wrap_surface(pctx, needs_mutable ? templ : psurf);
csurf->needs_mutable = needs_mutable;
if (needs_mutable) {
csurf->surf = NULL;
pipe_resource_reference(&csurf->base.texture, pres);
init_pipe_surface_info(pctx, &csurf->base, templ, pres);
}
if (templ->nr_samples && !zink_screen(pctx->screen)->info.have_EXT_multisampled_render_to_single_sampled) {
/* transient fb attachment: not cached */
@ -357,6 +372,9 @@ zink_surface_destroy(struct pipe_context *pctx,
struct pipe_surface *psurface)
{
struct zink_ctx_surface *csurf = (struct zink_ctx_surface *)psurface;
if (csurf->needs_mutable)
/* this has an extra resource ref */
pipe_resource_reference(&csurf->base.texture, NULL);
zink_surface_reference(zink_screen(pctx->screen), &csurf->surf, NULL);
pipe_surface_release(pctx, (struct pipe_surface**)&csurf->transient);
FREE(csurf);

View file

@ -1447,6 +1447,7 @@ struct zink_ctx_surface {
struct zink_surface *surf; //the actual surface
struct zink_ctx_surface *transient; //for use with EXT_multisample_render_to_texture
bool transient_init; //whether the transient surface has data
bool needs_mutable;
};
/* use this cast for framebuffer surfaces */