[Mesa-dev] [PATCH] st/dri: decrease input lag by syncing sooner in SwapBuffers
Marek Olšák
maraeo at gmail.com
Fri Apr 26 02:06:25 UTC 2019
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;
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
More information about the mesa-dev
mailing list