From: Marek Olšák Date: Mon, 22 Apr 2019 21:11:00 +0000 (-0400) Subject: st/dri: decrease input lag by syncing sooner in SwapBuffers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=20909284f204091757c050aa40cfffaf3f981b9c;p=mesa.git st/dri: decrease input lag by syncing sooner in SwapBuffers 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. --- 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 @@ -356,7 +356,7 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, return 0; case PIPE_CAP_MAX_FRAMES_IN_FLIGHT: - return 2; + return 1; case PIPE_CAP_DMABUF: #ifdef PIPE_OS_LINUX 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 @@ -562,19 +562,19 @@ dri_flush(__DRIcontext *cPriv, * 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)) {