st/nine: Use helper to release swapchain buffers later
authorAxel Davy <davyaxel0@gmail.com>
Wed, 21 Nov 2018 21:03:07 +0000 (22:03 +0100)
committerAxel Davy <davyaxel0@gmail.com>
Sun, 23 Dec 2018 07:14:50 +0000 (08:14 +0100)
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 <davyaxel0@gmail.com>
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
src/gallium/state_trackers/nine/swapchain9.c
src/gallium/state_trackers/nine/swapchain9.h

index d330c855726afe93c829c6b88d312f3152f73df8..138e8816a05c5c4e5e8953bc10422674ec595ba0 100644 (file)
@@ -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);
index 0fa0589d3b71935440c98ac4b7c2b7a44763bdf5..a6146445bdd0bd6dda748b5134b4b0466c994194 100644 (file)
@@ -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;