aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2018-11-12 13:09:29 +0100
committerJan Ekström <jeebjp@gmail.com>2018-11-19 00:23:15 +0200
commitb8bb5329a578a0335d3470293108c98792633831 (patch)
tree5ca17346bba6aebfe6bfac6509d68497df2fa8cf
parent34df6bd82fe4a32b1a4b1d878297976a999aabe4 (diff)
vulkan: slightly improve vsync jitter measurements
By design, some vulkan implementations block until vsync during vkAcquireNextImageKHR. Since mpv only considers the time that `swap_buffers` spent blocking as constituting part of the vsync, we can help it out a bit by pre-emptively calling this function here in order to improve the accuracy of vsync jitter measurements on vulkan. (If it fails, we just ignore the error and have the user call it a second time later - maybe it will work then) On my system this drops vsync-jitter from ~0.030 to ~0.007, an accuracy of +/- 100μs. (Which *might* have something to do with the fact that this is the polling interval for command polling)
-rw-r--r--video/out/vulkan/context.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/video/out/vulkan/context.c b/video/out/vulkan/context.c
index b819345d74..29a2c9b727 100644
--- a/video/out/vulkan/context.c
+++ b/video/out/vulkan/context.c
@@ -133,6 +133,9 @@ struct priv {
int num_sems;
int idx_sems; // index of next free semaphore pair
int last_imgidx; // the image index last acquired (for submit)
+
+ // This is used to pre-fetch the next frame at the end of swap_buffers
+ struct ra_fbo queued_fbo;
};
static const struct ra_swapchain_fns vulkan_swapchain;
@@ -405,6 +408,9 @@ bool ra_vk_ctx_resize(struct ra_swapchain *sw, int w, int h)
p->sems_out[idx] = sem_out;
}
+ // Invalidate the queued texture
+ p->queued_fbo = (struct ra_fbo) {0};
+
// Recreate the ra_tex wrappers
for (int i = 0; i < p->num_images; i++)
ra_tex_free(ra, &p->images[i]);
@@ -455,6 +461,13 @@ static bool start_frame(struct ra_swapchain *sw, struct ra_fbo *out_fbo)
if (!p->swapchain)
return false;
+ if (p->queued_fbo.tex) {
+ assert(out_fbo != &p->queued_fbo);
+ *out_fbo = p->queued_fbo;
+ p->queued_fbo = (struct ra_fbo) {0};
+ return true;
+ }
+
VkSemaphore sem_in = p->sems_in[p->idx_sems];
MP_TRACE(vk, "vkAcquireNextImageKHR signals %p\n", (void *)sem_in);
@@ -565,6 +578,12 @@ static void swap_buffers(struct ra_swapchain *sw)
while (p->frames_in_flight >= sw->ctx->opts.swapchain_depth)
mpvk_poll_commands(p->vk, 100000); // 100μs
+
+ // Also try and block until the next hardware buffer swap early. this
+ // prevents start_frame from blocking later, thus slightly improving the
+ // frame timing stats. (since mpv assumes most blocking will happen in
+ // swap_buffers)
+ start_frame(sw, &p->queued_fbo);
}
static const struct ra_swapchain_fns vulkan_swapchain = {