From: "Kazlauskas, Nicholas" <Nicholas.Kazlauskas-5C7GfCeVMHo@public.gmane.org>
To: Daniel Vetter <daniel-/w4YWyX8dFk@public.gmane.org>,
Mario Kleiner
<mario.kleiner.de-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: "Deucher,
Alexander" <Alexander.Deucher-5C7GfCeVMHo@public.gmane.org>,
"michel-otUistvHUpPR7s880joybQ@public.gmane.org"
<michel-otUistvHUpPR7s880joybQ@public.gmane.org>,
"dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org"
<dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>,
"amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org"
<amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>
Subject: Re: [PATCH 2/3] drm: Add basic helper to allow precise pageflip timestamps in vrr.
Date: Mon, 11 Feb 2019 15:01:44 +0000 [thread overview]
Message-ID: <41354dd1-e3fe-58cc-9c10-1a8cd05b2a40@amd.com> (raw)
In-Reply-To: <20190211083540.GR23159-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
On 2/11/19 3:35 AM, Daniel Vetter wrote:
> On Mon, Feb 11, 2019 at 04:22:24AM +0100, Mario Kleiner wrote:
>> The pageflip completion timestamps transmitted to userspace
>> via pageflip completion events are supposed to describe the
>> time at which the first pixel of the new post-pageflip scanout
>> buffer leaves the video output of the gpu. This time is
>> identical to end of vblank, when active scanout starts.
>>
>> For a crtc in standard fixed refresh rate, the end of vblank
>> is identical to the vblank timestamps calculated by
>> drm_update_vblank_count() at each vblank interrupt, or each
>> vblank dis-/enable. Therefore pageflip events just carry
>> that vblank timestamp as their pageflip timestamp.
>>
>> For a crtc switched to variable refresh rate mode (vrr), the
>> pageflip completion timestamps are identical to the vblank
>> timestamps iff the pageflip was executed early in vblank,
>> before the minimum vblank duration elapsed. In this case
>> the time of display onset is identical to when the crtc
>> is running in fixed refresh rate.
>>
>> However, if a pageflip completes later in the vblank, inside
>> the "extended front porch" in vrr mode, then the vblank will
>> terminate at a fixed (back porch) duration after flip, so
>> the display onset time is delayed correspondingly. In this
>> case the vblank timestamp computed at vblank irq time would
>> be too early, and we need a way to calculate an estimated
>> pageflip timestamp that will be later than the vblank timestamp.
>>
>> How a driver determines such a "late flip" timestamp is hw
>> and driver specific, but this patch adds a new helper function
>> that allows the driver to propose such an alternate "late flip"
>> timestamp for use in pageflip events:
>>
>> drm_crtc_set_vrr_pageflip_timestamp(crtc, flip_timestamp);
>>
>> When sending out pageflip events, we now compare that proposed
>> flip_timestamp against the vblank timestamp of the current
>> vblank of flip completion and choose to send out the greater/
>> later timestamp as flip completion timestamp.
>>
>> The most simple way for a kms driver to supply a suitable
>> flip_timestamp in vrr mode would be to simply take a timestamp
>> at start of the pageflip completion handler, e.g., pageflip
>> irq handler: flip_timestamp = ktime_get(); and then set that
>> as proposed "late" alternative timestamp via ...
>> drm_crtc_set_vrr_pageflip_timestamp(crtc, flip_timestamp);
>>
>> More clever approaches could try to add some corrective offset
>> for fixed back porch duration, or ideally use hardware features
>> like hw timestamps to calculate the exact end time of vblank.
>>
>> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
>> Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
>> Cc: Harry Wentland <harry.wentland@amd.com>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>
> Uh, this looks like a pretty bad hack. Can't we fix amdgpu to only give us
> the right timestampe, once? With this I guess if you do a vblank query in
> between the wrong and the right vblank you'll get the bogus value. Not
> really great for userspace.
> -Daniel
I think we calculate the timestamp and send the vblank event both within
the pageflip IRQ handler so calculating the right pageflip timestamp
once could probably be done. I'm not sure if it's easier than proposing
a later flip time with an API like this though.
The actual scanout time should be known from the page-flip handler so
the semantics for VRR on/off remain the same. This is because the
page-flip triggers entering the back porch if we're in the extended
front porch.
But scanout time from vblank events for something like
DRM_IOCTL_WAIT_VBLANK are going to be wrong in most cases and are only
treated as estimates. If we're in the regular front porch then the
timing to scanout is based on the fixed duration front porch for the
current mode. If we're in the extended back porch then it's technically
driver defined but the most reasonable guess is to assume that the front
porch is going to end at any moment, so just return the length of the
back porch for getting the scanout time.
Proposing the late timestamp shouldn't affect vblank event in the
DRM_IOCTL_WAIT_VBLANK case and should only be used in the page-flip
event case. I'm not sure if that's what's guaranteed to happen with this
patch though. There doesn't seem to be any locking on either
dev->vblank_time_lock or the vblank->seqlock so while it's likely to get
the same vblank event back as the one just stored I don't think it's
guaranteed.
Nicholas Kazlauskas
>
>> ---
>> drivers/gpu/drm/drm_vblank.c | 49 +++++++++++++++++++++++++++++++++++-
>> include/drm/drm_vblank.h | 8 ++++++
>> 2 files changed, 56 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
>> index 98e091175921..4b3a4c38fabe 100644
>> --- a/drivers/gpu/drm/drm_vblank.c
>> +++ b/drivers/gpu/drm/drm_vblank.c
>> @@ -814,10 +814,21 @@ static void send_vblank_event(struct drm_device *dev,
>> u64 seq, ktime_t now)
>> {
>> struct timespec64 tv;
>> + ktime_t alt_flip_time;
>>
>> switch (e->event.base.type) {
>> - case DRM_EVENT_VBLANK:
>> case DRM_EVENT_FLIP_COMPLETE:
>> + /*
>> + * For flip completion events, override "now" time
>> + * with alt_flip_time provided by the driver via
>> + * drm_crtc_set_vrr_pageflip_timestamp() in VRR mode
>> + * if that time is later than given "now" vblank time.
>> + */
>> + alt_flip_time = dev->vblank[e->pipe].alt_flip_time;
>> + if (alt_flip_time > now)
>> + now = alt_flip_time;
>> + /* Fallthrough */
>> + case DRM_EVENT_VBLANK:
>> tv = ktime_to_timespec64(now);
>> e->event.vbl.sequence = seq;
>> /*
>> @@ -916,11 +927,47 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
>>
>> now = ktime_get();
>> }
>> +
>> e->pipe = pipe;
>> send_vblank_event(dev, e, seq, now);
>> }
>> EXPORT_SYMBOL(drm_crtc_send_vblank_event);
>>
>> +/**
>> + * drm_crtc_set_vrr_pageflip_timestamp - helper to set alternate pageflip time
>> + * @crtc: the source CRTC of the pageflip completion event
>> + * @flip_time: The alternate pageflip completion timestamp in VRR mode
>> + *
>> + * In variable refresh rate mode (VRR), a pageflip completion timestamp carried
>> + * by the pageflip event can never be earlier than the vblank timestamp of the
>> + * vblank of flip completion, as that vblank timestamp defines the end of the
>> + * shortest possible vblank duration. In case of a delayed flip completion
>> + * inside the extended VRR front porch however, the end of vblank can be much
>> + * later, so the driver must assign an estimated timestamp of that later end of
>> + * vblank. For a CRTC in VRR mode, the driver should use this helper function to
>> + * set an alternate flip completion timestamp in case of late flip completions
>> + * in extended vblank. In the most simple case, this @flip_time timestamp could
>> + * simply be a ktime_get() timestamp taken at the start of the pageflip
>> + * completion routine, with some constant duration of the back porch interval
>> + * added, although more precise estimates may be possible on some hardware if
>> + * the hardware provides some means of timestamping the true end of vblank.
>> + *
>> + * When sending out pageflip events, e.g., via drm_crtc_send_vblank_event(), it
>> + * will use either the standard vblank timestamp, calculated for a minimum
>> + * duration vblank, or the provided @flip_time if that time is later than the
>> + * vblank timestamp, to get the best possible estimate of start of display of
>> + * the new post-pageflip scanout buffer.
>> + */
>> +void drm_crtc_set_vrr_pageflip_timestamp(struct drm_crtc *crtc,
>> + ktime_t flip_time)
>> +{
>> + struct drm_device *dev = crtc->dev;
>> + struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(crtc)];
>> +
>> + vblank->alt_flip_time = flip_time;
>> +}
>> +EXPORT_SYMBOL(drm_crtc_set_vrr_pageflip_timestamp);
>> +
>> static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
>> {
>> if (drm_core_check_feature(dev, DRIVER_MODESET)) {
>> diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
>> index 6ad9630d4f48..aacf44694ab6 100644
>> --- a/include/drm/drm_vblank.h
>> +++ b/include/drm/drm_vblank.h
>> @@ -117,6 +117,12 @@ struct drm_vblank_crtc {
>> * @time: Vblank timestamp corresponding to @count.
>> */
>> ktime_t time;
>> + /**
>> + * @alt_flip_time: Vblank timestamp for end of extended vblank due to
>> + * a late pageflip completion in variable refresh rate mode. Pageflip
>> + * events will carry the later one of @time and @alt_flip_time.
>> + */
>> + ktime_t alt_flip_time;
>>
>> /**
>> * @refcount: Number of users/waiters of the vblank interrupt. Only when
>> @@ -179,6 +185,8 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs);
>> u64 drm_crtc_vblank_count(struct drm_crtc *crtc);
>> u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
>> ktime_t *vblanktime);
>> +void drm_crtc_set_vrr_pageflip_timestamp(struct drm_crtc *crtc,
>> + ktime_t flip_time);
>> void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
>> struct drm_pending_vblank_event *e);
>> void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
>> --
>> 2.17.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
next prev parent reply other threads:[~2019-02-11 15:01 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-11 3:22 Some VRR vblank/pageflip timestamping fixes Mario Kleiner
2019-02-11 3:22 ` [PATCH 1/3] drm/amdgpu: Fix get_crtc_scanoutpos behavior in vrr when vpos >= vtotal Mario Kleiner
[not found] ` <20190211032225.9488-1-mario.kleiner.de-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-02-11 3:22 ` [PATCH 2/3] drm: Add basic helper to allow precise pageflip timestamps in vrr Mario Kleiner
2019-02-11 8:35 ` Daniel Vetter
[not found] ` <20190211083540.GR23159-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-02-11 15:01 ` Kazlauskas, Nicholas [this message]
[not found] ` <41354dd1-e3fe-58cc-9c10-1a8cd05b2a40-5C7GfCeVMHo@public.gmane.org>
2019-02-11 17:04 ` Daniel Vetter
2019-02-12 21:32 ` Mario Kleiner via dri-devel
[not found] ` <CAEsyxyiT-k5LecWs1=Zyj9J=GPjbQFQSPzYQpDxFzjwwRvFS-A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-02-13 9:50 ` Daniel Vetter
[not found] ` <20190213095055.GF23159-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-02-13 9:55 ` Chris Wilson
2019-02-13 11:05 ` Mario Kleiner via amd-gfx
[not found] ` <CAEsyxygzqwWGJLBZ5M_AkGQ7HFgzS=rxRgZ+dCFK0QG7Ek63Zw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-02-13 12:46 ` Daniel Vetter
2019-02-13 11:22 ` Mario Kleiner via amd-gfx
2019-02-13 14:33 ` Kazlauskas, Nicholas
[not found] ` <f1680226-4123-8fd6-374c-e639595f7dd6-5C7GfCeVMHo@public.gmane.org>
2019-02-13 15:14 ` Daniel Vetter
2019-02-13 15:41 ` Kazlauskas, Nicholas
[not found] ` <b65833b3-5f68-87b7-7fe6-d89fd58a83ef-5C7GfCeVMHo@public.gmane.org>
2019-02-13 16:03 ` Daniel Vetter
[not found] ` <CAKMK7uGr8+zvRuTKo6ecDOFfGFnPRwxR8AWwhNAcqJat_vtk8w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-02-13 18:10 ` Mario Kleiner via amd-gfx
[not found] ` <CAEsyxygFmFDZWrmPXSa0qwc76trF9Cj-e1TOsJc7kDorxuGBqw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-02-13 18:34 ` Kazlauskas, Nicholas
2019-02-13 20:53 ` Daniel Vetter
2019-02-11 3:22 ` [PATCH 3/3] drm/amd/display: Provide more accurate pageflip timestamps in vrr mode Mario Kleiner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=41354dd1-e3fe-58cc-9c10-1a8cd05b2a40@amd.com \
--to=nicholas.kazlauskas-5c7gfcevmho@public.gmane.org \
--cc=Alexander.Deucher-5C7GfCeVMHo@public.gmane.org \
--cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=daniel-/w4YWyX8dFk@public.gmane.org \
--cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=mario.kleiner.de-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=michel-otUistvHUpPR7s880joybQ@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox