Module: Mesa Branch: staging/22.1 Commit: 8cd82ee2566a142c2fe7533a365c4ea6f6202b6f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8cd82ee2566a142c2fe7533a365c4ea6f6202b6f
Author: Mike Blumenkrantz <[email protected]> Date: Mon Apr 25 15:46:28 2022 -0400 zink: fix up swapchain depth buffer geometry during fb update due to desync between the frontend and the driver, the size that the depth buffer was created with may not match the size of the swapchain if the window is being resized very quickly, so just go ahead and clobber the existing depth buffer with a series of very illegal internal object replacements to make everything match up do not try at home. Reviewed-by: Adam Jackson <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16179> --- src/gallium/drivers/zink/zink_context.c | 1 + src/gallium/drivers/zink/zink_kopper.c | 36 +++++++++++++++++++++++++++++++++ src/gallium/drivers/zink/zink_kopper.h | 3 +++ 3 files changed, 40 insertions(+) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 2eb93722823..60cc5ab0ffd 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -2214,6 +2214,7 @@ setup_framebuffer(struct zink_context *ctx) unsigned old_h = ctx->fb_state.height; ctx->fb_state.width = ctx->swapchain_size.width; ctx->fb_state.height = ctx->swapchain_size.height; + zink_kopper_fixup_depth_buffer(ctx); update_framebuffer_state(ctx, old_w, old_h); ctx->swapchain_size.width = ctx->swapchain_size.height = 0; } diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c index 18c55d3c90e..bc9d9e68be2 100644 --- a/src/gallium/drivers/zink/zink_kopper.c +++ b/src/gallium/drivers/zink/zink_kopper.c @@ -728,3 +728,39 @@ zink_kopper_update(struct pipe_screen *pscreen, struct pipe_resource *pres, int *h = cdt->caps.currentExtent.height; return true; } + +void +zink_kopper_fixup_depth_buffer(struct zink_context *ctx) +{ + struct zink_screen *screen = zink_screen(ctx->base.screen); + if (!ctx->fb_state.zsbuf) + return; + + assert(ctx->fb_state.zsbuf->texture->bind & PIPE_BIND_DISPLAY_TARGET); + + struct zink_resource *res = zink_resource(ctx->fb_state.zsbuf->texture); + struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf); + struct zink_ctx_surface *csurf = (struct zink_ctx_surface*)ctx->fb_state.zsbuf; + if (surf->info.width == ctx->fb_state.width && + surf->info.height == ctx->fb_state.height) + return; + + struct pipe_resource templ = *ctx->fb_state.zsbuf->texture; + templ.width0 = ctx->fb_state.width; + templ.height0 = ctx->fb_state.height; + struct pipe_resource *pz = screen->base.resource_create(&screen->base, &templ); + struct zink_resource *z = zink_resource(pz); + zink_resource_object_reference(screen, &res->obj, z->obj); + res->base.b.width0 = ctx->fb_state.width; + res->base.b.height0 = ctx->fb_state.height; + pipe_resource_reference(&pz, NULL); + + ctx->fb_state.zsbuf->width = ctx->fb_state.width; + ctx->fb_state.zsbuf->height = ctx->fb_state.height; + struct pipe_surface *psurf = ctx->base.create_surface(&ctx->base, &res->base.b, ctx->fb_state.zsbuf); + struct zink_ctx_surface *cz = (struct zink_ctx_surface*)psurf; + + /* oh god why */ + zink_surface_reference(screen, &csurf->surf, cz->surf); + pipe_surface_release(&ctx->base, &psurf); +} diff --git a/src/gallium/drivers/zink/zink_kopper.h b/src/gallium/drivers/zink/zink_kopper.h index 5b7a10b17f9..7c11d804040 100644 --- a/src/gallium/drivers/zink/zink_kopper.h +++ b/src/gallium/drivers/zink/zink_kopper.h @@ -111,4 +111,7 @@ void zink_kopper_deinit_displaytarget(struct zink_screen *screen, struct kopper_displaytarget *cdt); bool zink_kopper_update(struct pipe_screen *pscreen, struct pipe_resource *pres, int *w, int *h); +void +zink_kopper_fixup_depth_buffer(struct zink_context *ctx); + #endif
