From 51df136c8b5e332163802349d96dff422d566c29 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Wed, 31 Mar 2021 14:12:29 -0700 Subject: wgl: Add a context to framebuffer destruction If the window is destroyed on a thread that has a currently-bound context, use that context for destroying the framebuffer. This ensures that the winsys can wait for in-flight work before destroying any resources. If the window did have a context bound beforehand but it was unbound, we should've already done a glFinish. If the window is destroyed from an unrelated thread... well, we're screwed, but that's the best we can do. Reviewed-By: Bill Kristiansen Reviewed-by: Jose Fonseca Part-of: --- src/gallium/frontends/wgl/stw_context.c | 4 ++-- src/gallium/frontends/wgl/stw_framebuffer.c | 15 ++++++++++----- src/gallium/frontends/wgl/stw_framebuffer.h | 3 ++- src/gallium/frontends/wgl/stw_winsys.h | 3 ++- src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp | 3 ++- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/gallium/frontends/wgl/stw_context.c b/src/gallium/frontends/wgl/stw_context.c index 9a909ebfcc0..e2f059835f0 100644 --- a/src/gallium/frontends/wgl/stw_context.c +++ b/src/gallium/frontends/wgl/stw_context.c @@ -555,7 +555,7 @@ stw_make_current(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc) if (old_fb && old_fb != fb) { stw_lock_framebuffers(stw_dev); stw_framebuffer_lock(old_fb); - stw_framebuffer_release_locked(old_fb); + stw_framebuffer_release_locked(old_fb, old_ctx->st); stw_unlock_framebuffers(stw_dev); } @@ -584,7 +584,7 @@ fail: old_ctx->current_framebuffer = NULL; stw_lock_framebuffers(stw_dev); stw_framebuffer_lock(old_fb); - stw_framebuffer_release_locked(old_fb); + stw_framebuffer_release_locked(old_fb, old_ctx->st); stw_unlock_framebuffers(stw_dev); } } diff --git a/src/gallium/frontends/wgl/stw_framebuffer.c b/src/gallium/frontends/wgl/stw_framebuffer.c index 359fd314526..05a56af9bc9 100644 --- a/src/gallium/frontends/wgl/stw_framebuffer.c +++ b/src/gallium/frontends/wgl/stw_framebuffer.c @@ -74,7 +74,8 @@ stw_framebuffer_from_hwnd_locked(HWND hwnd) * locked. After this function completes, the fb's mutex will be unlocked. */ void -stw_framebuffer_release_locked(struct stw_framebuffer *fb) +stw_framebuffer_release_locked(struct stw_framebuffer *fb, + struct st_context_iface *stctx) { struct stw_framebuffer **link; @@ -102,7 +103,7 @@ stw_framebuffer_release_locked(struct stw_framebuffer *fb) fb->shared_surface); if (fb->winsys_framebuffer) - fb->winsys_framebuffer->destroy(fb->winsys_framebuffer); + fb->winsys_framebuffer->destroy(fb->winsys_framebuffer, stctx ? stctx->pipe : NULL); stw_st_destroy_framebuffer_locked(fb->stfb); @@ -238,8 +239,12 @@ stw_call_window_proc(int nCode, WPARAM wParam, LPARAM lParam) else if (pParams->message == WM_DESTROY) { stw_lock_framebuffers(stw_dev); fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd ); - if (fb) - stw_framebuffer_release_locked(fb); + if (fb) { + struct stw_context *current_context = stw_current_context(); + struct st_context_iface *ctx_iface = current_context && + current_context->current_framebuffer == fb ? current_context->st : NULL; + stw_framebuffer_release_locked(fb, ctx_iface); + } stw_unlock_framebuffers(stw_dev); } } @@ -363,7 +368,7 @@ stw_framebuffer_cleanup(void) next = fb->next; stw_framebuffer_lock(fb); - stw_framebuffer_release_locked(fb); + stw_framebuffer_release_locked(fb, NULL); fb = next; } diff --git a/src/gallium/frontends/wgl/stw_framebuffer.h b/src/gallium/frontends/wgl/stw_framebuffer.h index 45d41544957..33923b13686 100644 --- a/src/gallium/frontends/wgl/stw_framebuffer.h +++ b/src/gallium/frontends/wgl/stw_framebuffer.h @@ -154,7 +154,8 @@ stw_framebuffer_reference_locked(struct stw_framebuffer *fb) void -stw_framebuffer_release_locked(struct stw_framebuffer *fb); +stw_framebuffer_release_locked(struct stw_framebuffer *fb, + struct st_context_iface *stctx); /** * Search a framebuffer with a matching HWND. diff --git a/src/gallium/frontends/wgl/stw_winsys.h b/src/gallium/frontends/wgl/stw_winsys.h index 9d5f6debe3c..47b8b202960 100644 --- a/src/gallium/frontends/wgl/stw_winsys.h +++ b/src/gallium/frontends/wgl/stw_winsys.h @@ -48,7 +48,8 @@ typedef enum struct stw_winsys_framebuffer { void - (*destroy)(struct stw_winsys_framebuffer *fb); + (*destroy)(struct stw_winsys_framebuffer *fb, + struct pipe_context *context); boolean (*present)(struct stw_winsys_framebuffer *fb); diff --git a/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp b/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp index 9409beb9ee6..50248b3e49b 100644 --- a/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp +++ b/src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp @@ -60,7 +60,8 @@ d3d12_wgl_framebuffer(struct stw_winsys_framebuffer *fb) } static void -d3d12_wgl_framebuffer_destroy(struct stw_winsys_framebuffer *fb) +d3d12_wgl_framebuffer_destroy(struct stw_winsys_framebuffer *fb, + pipe_context *ctx) { FREE(fb); } -- cgit v1.2.3