[Mesa-dev] [PATCH 1/6] st/nine: Use helper to release swapchain buffers later

Dieter Nützel Dieter at nuetzel-hh.de
Thu Dec 20 04:48:28 UTC 2018


For the series:

Tested-by: Dieter Nützel <Dieter at nuetzel-hh.de>

(with my 'normal' apps) ;-)

+ LS2015 (D3D9) under Wine Staging Nine 4.0-rc2
nice numbers

Dieter

Am 16.12.2018 22:25, schrieb Axel Davy:
> 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 at gmail.com>
> ---
>  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;


More information about the mesa-dev mailing list