diff --git a/src/xrt/auxiliary/util/u_pacing.h b/src/xrt/auxiliary/util/u_pacing.h index e9646d446..54a31f7ed 100644 --- a/src/xrt/auxiliary/util/u_pacing.h +++ b/src/xrt/auxiliary/util/u_pacing.h @@ -134,6 +134,19 @@ struct u_pacing_compositor uint64_t present_margin_ns, uint64_t when_ns); + /*! + * Provide a vblank timing information, derived from the + * VK_EXT_display_control extension. Since the extension only says when + * a vblank happened (somewhat inaccurate as well) but not if a specific + * present happened at that time no frame_id is given. + * + * @param[in] upc The compositor pacing helper. + * @param[in] last_vblank_ns The last time that the GPU started scanning out. + * + * @see @ref frame-pacing. + */ + void (*update_vblank_from_display_control)(struct u_pacing_compositor *upc, uint64_t last_vblank_ns); + /*! * Provide an updated estimate of the present offset. * @@ -220,6 +233,20 @@ u_pc_info(struct u_pacing_compositor *upc, present_margin_ns, when_ns); } +/*! + * @copydoc u_pacing_compositor::info_display_control + * + * Helper for calling through the function pointer. + * + * @public @memberof u_pacing_compositor + * @ingroup aux_pacing + */ +static inline void +u_pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns) +{ + upc->update_vblank_from_display_control(upc, last_vblank_ns); +} + /*! * @copydoc u_pacing_compositor::update_present_offset * diff --git a/src/xrt/auxiliary/util/u_pacing_compositor.c b/src/xrt/auxiliary/util/u_pacing_compositor.c index 078adca36..83b342286 100644 --- a/src/xrt/auxiliary/util/u_pacing_compositor.c +++ b/src/xrt/auxiliary/util/u_pacing_compositor.c @@ -641,6 +641,14 @@ pc_info(struct u_pacing_compositor *upc, #undef TE_END } +static void +pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns) +{ + /* + * This is a no-op, here just in case display control is used at the + * same time as the google extension. We ignore this call. + */ +} static void pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns) @@ -682,6 +690,7 @@ u_pc_display_timing_create(uint64_t estimated_frame_period_ns, pc->base.predict = pc_predict; pc->base.mark_point = pc_mark_point; pc->base.info = pc_info; + pc->base.update_vblank_from_display_control = pc_update_vblank_from_display_control; pc->base.update_present_offset = pc_update_present_offset; pc->base.destroy = pc_destroy; pc->frame_period_ns = estimated_frame_period_ns; diff --git a/src/xrt/auxiliary/util/u_pacing_compositor_fake.c b/src/xrt/auxiliary/util/u_pacing_compositor_fake.c index aedc6cda6..609d8044d 100644 --- a/src/xrt/auxiliary/util/u_pacing_compositor_fake.c +++ b/src/xrt/auxiliary/util/u_pacing_compositor_fake.c @@ -152,6 +152,15 @@ pc_info(struct u_pacing_compositor *upc, */ } +static void +pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns) +{ + struct fake_timing *ft = fake_timing(upc); + + // Use the last vblank time to sync to the output. + ft->last_present_time_ns = last_vblank_ns; +} + static void pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns) { @@ -184,6 +193,7 @@ u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_p ft->base.predict = pc_predict; ft->base.mark_point = pc_mark_point; ft->base.info = pc_info; + ft->base.update_vblank_from_display_control = pc_update_vblank_from_display_control; ft->base.update_present_offset = pc_update_present_offset; ft->base.destroy = pc_destroy; ft->frame_period_ns = estimated_frame_period_ns;