[Mesa-dev] [PATCH] st/dri: decrease input lag by syncing sooner in SwapBuffers

Rob Clark robdclark at gmail.com
Sat Apr 27 16:13:26 UTC 2019


On Thu, Apr 25, 2019 at 7:06 PM Marek Olšák <maraeo at gmail.com> wrote:
>
> From: Marek Olšák <marek.olsak at amd.com>
>
> It's done by:
> - decrease the number of frames in flight by 1
> - flush before throttling in SwapBuffers
>   (instead of wait-then-flush, do flush-then-wait)
>
> The improvement is apparent with Unigine Heaven.
>
> Previously:
>     draw frame 2
>     wait frame 0
>     flush frame 2
>     present frame 2
>
>     The input lag is 2 frames.
>
> Now:
>     draw frame 2
>     flush frame 2
>     wait frame 1
>     present frame 2
>
>     The input lag is 1 frame. Flushing is done before waiting, because
>     otherwise the device would be idle after waiting.
>
> Nine is affected because it also uses the pipe cap.
> ---
>  src/gallium/auxiliary/util/u_screen.c         |  2 +-
>  src/gallium/state_trackers/dri/dri_drawable.c | 20 +++++++++----------
>  2 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c
> index 27f51e0898e..410f17421e6 100644
> --- a/src/gallium/auxiliary/util/u_screen.c
> +++ b/src/gallium/auxiliary/util/u_screen.c
> @@ -349,21 +349,21 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
>     case PIPE_CAP_MAX_VARYINGS:
>        return 8;
>
>     case PIPE_CAP_COMPUTE_GRID_INFO_LAST_BLOCK:
>        return 0;
>
>     case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES:
>        return 0;
>
>     case PIPE_CAP_MAX_FRAMES_IN_FLIGHT:
> -      return 2;
> +      return 1;

would it be safer to leave the current default and let drivers opt-in
to the lower # individually?  I guess triple buffering would still be
better for some of the smaller gpu's?

disclaimer: I haven't tested this myself or looked very closely at the
dri code.. so could be misunderstanding something..

BR,
-R

>
>     case PIPE_CAP_DMABUF:
>  #ifdef PIPE_OS_LINUX
>        return 1;
>  #else
>        return 0;
>  #endif
>
>     default:
>        unreachable("bad PIPE_CAP_*");
> diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
> index 26bfdbecc53..c1de3bed9dd 100644
> --- a/src/gallium/state_trackers/dri/dri_drawable.c
> +++ b/src/gallium/state_trackers/dri/dri_drawable.c
> @@ -555,33 +555,33 @@ dri_flush(__DRIcontext *cPriv,
>         *
>         * This pulls a fence off the throttling queue and waits for it if the
>         * number of fences on the throttling queue has reached the desired
>         * number.
>         *
>         * Then flushes to insert a fence at the current rendering position, and
>         * pushes that fence on the queue. This requires that the st_context_iface
>         * flush method returns a fence even if there are no commands to flush.
>         */
>        struct pipe_screen *screen = drawable->screen->base.screen;
> -      struct pipe_fence_handle *fence;
> +      struct pipe_fence_handle *oldest_fence, *new_fence = NULL;
>
> -      fence = swap_fences_pop_front(drawable);
> -      if (fence) {
> -         (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
> -         screen->fence_reference(screen, &fence, NULL);
> -      }
> +      st->flush(st, flush_flags, &new_fence);
>
> -      st->flush(st, flush_flags, &fence);
> +      oldest_fence = swap_fences_pop_front(drawable);
> +      if (oldest_fence) {
> +         screen->fence_finish(screen, NULL, oldest_fence, PIPE_TIMEOUT_INFINITE);
> +         screen->fence_reference(screen, &oldest_fence, NULL);
> +      }
>
> -      if (fence) {
> -         swap_fences_push_back(drawable, fence);
> -         screen->fence_reference(screen, &fence, NULL);
> +      if (new_fence) {
> +         swap_fences_push_back(drawable, new_fence);
> +         screen->fence_reference(screen, &new_fence, NULL);
>        }
>     }
>     else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
>        st->flush(st, flush_flags, NULL);
>     }
>
>     if (drawable) {
>        drawable->flushing = FALSE;
>     }
>
> --
> 2.17.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list