summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorAxel Davy <[email protected]>2018-11-21 22:03:07 +0100
committerAxel Davy <[email protected]>2018-12-23 08:14:50 +0100
commitc442dd789066104e5e84cc90d98a7ff5cd6296cf (patch)
tree27f652e31b3bf30629cc28edbecbb2319fd0ff86 /src/gallium
parent51a44c3aac7642a4b26dcfb3a80d3dd87892aa6f (diff)
st/nine: Use helper to release swapchain buffers later
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 <[email protected]> Tested-by: Dieter Nützel <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/state_trackers/nine/swapchain9.c49
-rw-r--r--src/gallium/state_trackers/nine/swapchain9.h1
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;