summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2022-04-25 15:46:28 -0400
committerMarge Bot <emma+marge@anholt.net>2022-04-27 03:54:29 +0000
commit8cd82ee2566a142c2fe7533a365c4ea6f6202b6f (patch)
tree7e43a0111d6b9ebb49f379a6a98c271a0e259b3f
parent939a0cf876507684c40d6fb523336c767ef455cd (diff)
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 <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16179>
-rw-r--r--src/gallium/drivers/zink/zink_context.c1
-rw-r--r--src/gallium/drivers/zink/zink_kopper.c36
-rw-r--r--src/gallium/drivers/zink/zink_kopper.h3
3 files changed, 40 insertions, 0 deletions
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