From c442dd789066104e5e84cc90d98a7ff5cd6296cf Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Wed, 21 Nov 2018 22:03:07 +0100 Subject: [PATCH] st/nine: Use helper to release swapchain buffers later MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch introduces a structure to release the present_handles only when they are fully released by the server, thus making "DestroyD3DWindowBuffer" actually release the buffer right away when called. Signed-off-by: Axel Davy Tested-by: Dieter Nützel --- src/gallium/state_trackers/nine/swapchain9.c | 49 ++++++++++++++++---- src/gallium/state_trackers/nine/swapchain9.h | 1 + 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c index d330c855726..138e8816a05 100644 --- a/src/gallium/state_trackers/nine/swapchain9.c +++ b/src/gallium/state_trackers/nine/swapchain9.c @@ -128,6 +128,40 @@ D3DWindowBuffer_create(struct NineSwapChain9 *This, return ret; } +static void +D3DWindowBuffer_release(struct NineSwapChain9 *This, + D3DWindowBuffer *present_handle) +{ + int i; + /* Add it to the 'pending release' list */ + for (i = 0; i < D3DPRESENT_BACK_BUFFERS_MAX_EX + 1; i++) { + if (!This->present_handles_pending_release[i]) { + This->present_handles_pending_release[i] = present_handle; + break; + } + } + if (i == (D3DPRESENT_BACK_BUFFERS_MAX_EX + 1)) { + ERR("Server not releasing buffers...\n"); + assert(false); + } + + /* Destroy elements of the list released by the server */ + for (i = 0; i < D3DPRESENT_BACK_BUFFERS_MAX_EX + 1; i++) { + if (This->present_handles_pending_release[i] && + ID3DPresent_IsBufferReleased(This->present, This->present_handles_pending_release[i])) { + /* WaitBufferReleased also waits the presentation feedback + * (which should arrive at about the same time), + * while IsBufferReleased doesn't. DestroyD3DWindowBuffer unfortunately + * checks it to release immediately all data, else the release + * is postponed for This->present release. To avoid leaks (we may handle + * a lot of resize), call WaitBufferReleased. */ + ID3DPresent_WaitBufferReleased(This->present, This->present_handles_pending_release[i]); + ID3DPresent_DestroyD3DWindowBuffer(This->present, This->present_handles_pending_release[i]); + This->present_handles_pending_release[i] = NULL; + } + } +} + static int NineSwapChain9_GetBackBufferCountForParams( struct NineSwapChain9 *This, D3DPRESENT_PARAMETERS *pParams ); @@ -291,7 +325,7 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This, This->enable_threadpool = FALSE; for (i = 0; i < oldBufferCount; i++) { - ID3DPresent_DestroyD3DWindowBuffer(This->present, This->present_handles[i]); + D3DWindowBuffer_release(This, This->present_handles[i]); This->present_handles[i] = NULL; if (This->present_buffers[i]) pipe_resource_reference(&(This->present_buffers[i]), NULL); @@ -519,6 +553,11 @@ NineSwapChain9_dtor( struct NineSwapChain9 *This ) FREE(This->pending_presentation[i]); } + for (i = 0; i < D3DPRESENT_BACK_BUFFERS_MAX_EX + 1; i++) { + if (This->present_handles_pending_release[i]) + ID3DPresent_DestroyD3DWindowBuffer(This->present, This->present_handles_pending_release[i]); + } + for (i = 0; i < This->num_back_buffers; i++) { if (This->buffers[i]) NineUnknown_Detach(NineUnknown(This->buffers[i])); @@ -738,13 +777,7 @@ present( struct NineSwapChain9 *This, create_present_buffer(This, target_width, target_height, &new_resource, &new_handle); /* Switch to the new buffer */ if (new_handle) { - /* WaitBufferReleased also waits the presentation feedback, - * while IsBufferReleased doesn't. DestroyD3DWindowBuffer unfortunately - * checks it to release immediately all data, else the release - * is postponed for This->present release. To avoid leaks (we may handle - * a lot of resize), call WaitBufferReleased. */ - ID3DPresent_WaitBufferReleased(This->present, This->present_handles[0]); - ID3DPresent_DestroyD3DWindowBuffer(This->present, This->present_handles[0]); + D3DWindowBuffer_release(This, This->present_handles[0]); This->present_handles[0] = new_handle; pipe_resource_reference(&This->present_buffers[0], new_resource); pipe_resource_reference(&new_resource, NULL); diff --git a/src/gallium/state_trackers/nine/swapchain9.h b/src/gallium/state_trackers/nine/swapchain9.h index 0fa0589d3b7..a6146445bdd 100644 --- a/src/gallium/state_trackers/nine/swapchain9.h +++ b/src/gallium/state_trackers/nine/swapchain9.h @@ -57,6 +57,7 @@ struct NineSwapChain9 struct NineSurface9 *buffers[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1]; /* 0 to BackBufferCount-1 : the back buffers. BackBufferCount : additional buffer */ struct pipe_resource *present_buffers[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1]; D3DWindowBuffer *present_handles[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1]; + D3DWindowBuffer *present_handles_pending_release[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1]; struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX]; unsigned int cur_fences; -- 2.30.2