Re: [PATCH 2/3] drm: Add basic helper to allow precise pageflip timestamps in vrr.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 13, 2019 at 10:50 AM Daniel Vetter <daniel@xxxxxxxx> wrote:
>
> On Tue, Feb 12, 2019 at 10:32:31PM +0100, Mario Kleiner wrote:
> > On Mon, Feb 11, 2019 at 6:04 PM Daniel Vetter <daniel@xxxxxxxx> wrote:
> > >
> > > On Mon, Feb 11, 2019 at 4:01 PM Kazlauskas, Nicholas
> > > <Nicholas.Kazlauskas@xxxxxxx> wrote:
> > > >
> > > > 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
...
> > > > >
> > > > > 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.
> > >
> > > That's the inconsistency I mean to highlight - the timestamp for the
> > > same frame as observed through flip complete and through the
> > > wait_vblank ioctl can differ. Which they really shouldn't.
> > >
> >
> > Ideally they shouldn't differ. The kernel docs for drm_crtc_state say
> > that vblank and pageflip timestamps should always match. But then the
> > kernel docs for "Variable refresh properties" in drm_connector.c for
> > vblank timestamps were changed for the VRR implementation in Linux
> > 5.0-rc to redefine them when in VRR mode. They are defined, but
> > probably rather useless for any practical purpose, like this:
> >
> > "The semantics for the vertical blank timestamp differ when
> > variable refresh rate is active. The vertical blank timestamp
> > is defined to be an estimate using the current mode's fixed
> > refresh rate timings. The semantics for the page-flip event
> > timestamp remain the same."
>
> Uh I missed that. That sounds like nonsense tbh.
>
> > So our docs contradict each other as of Linux 5.0-rc. Certainly having
> > useful vblank timetamps would be useful.
>
> Yup, imo vblank should still match page_flip. Otherwise I expect a lot of
> hilarity will ensue.
>
> > > Now added complication is that amdgpu sends out vblank events really
> > > early, which is used by userspace to do frontbuffer rendering in the
> > > vblank time. But I don't think anyone wants to do both VRR and
> >
> > I think all kms drivers try to call drm_crtc_handle_vblank() at start
> > of vblank to give Mesa the most time for frontbuffer rendering for
> > classic X. But vblank events are also used for scheduling bufferswaps
> > or other stuff for redirected windowed rendering, or via api's like
> > OML_sync_controls glXWaitForMscOML, so there might be other things
> > affected by a more delayed vblank handling.
>
> The frontbuffer rendering is very much X driver specific, and I think
> -amdgpu/radeon is the only one that requires this. No i915 driver ever
> used the vblank interrupt to schedule frontbuffer blits, we use some
> CS-side stalls.
>
> Wrt scheduling pageflips: The rule is that right after you've received the
> vblank for frame X, then an immediately schedule pageflip should hit X+1,
> but not X. amdgpu had this broken, but it's fixed since a while.
>
> > > frontbuffer rendering, hence I think it should be possible to create
> > > correct vblank timestamps for the VRR case, while leaving the current
> > > logic in place for everything else. But that means moving the entire
> > > vblank processing to where you know the next frame's start time for
> > > VRR, both for page flips and for all other vblank events.
> > > -Daniel
> > >
> >
> > I think for amdgpu it would be doable by calling drm_handle_vblank
> > from the pageflip irq handler in VRR mode, and then additionally from
> > the vblank interrupt handler like now. Vblank irq's are triggered via
> > vline interrupts with programmable vertical trigger line position, so
> > we could program the trigger line to be start of back-porch instead of
> > start of front-porch. In the pageflip case we do vblank handling +
> > timestamping + pflip completion from pflip irq, and have the regular
> > back-porch vblank handling for refresh cycles in which no
> > pageflip/pflip irq happened.
>
> Hm, can't we simply program the vblank to occur in the back porch region
> for VRR? The vblank timestamping should automatically correct the
> timestamp in that case. Would require a lot less code changes.
>
> Plus update the documentation ofc.
>

Thanks to an unexpected bus driver strike i got stuck in the lab
instead of my bed for the last 6 extra hours, so i had some time to
think about this and hack up a proof-of-concept. Yes, moving vblank
irq ~ drm_handle_vblank() to the start of back-porch seems to do the
trick in VRR mode pretty well, at least as far as 30 minutes of
testing with my own application Psychtoolbox show. This may work -
More sleep and more testing required :)

As a side-effect of the shifted point of drm_update_vblank_counter()
update in back-porch or flip-irq though, the flip throttling in VRR
needed some work, which makes it even more hacky/messy - Michel will
not be pleased ;). Might need a timestamp-based throttling in VRR mode
to make it less messy.

-mario

> > Not sure if/how that would mess with below-vrr-refresh-rate-range
> > support for stutter reduction at low fps though? Or with performance,
> > given vblank event dispatch could be delayed a lot in VRR compared to
> > normal mode? Or with all the vblank accounting during modesets or crtc
> > en/disable?
>
> Currently VRR and explicit frame scheduling don't mix. We've discussed
> this, and consens seems to be that we need a new property for page_flip,
> similar to the target frame, but instead of frames a timestamp. Then the
> driver can hit a specific time for the next frame.
>
> And since compositors use the vblank ioctl just to do frame scheduling, I
> don't think we have to worry hugely about interactions there. Much better
> to aim for clean semantics (i.e. vblank and flip complete timestamps
> better match).
>
> > Also, could other drivers like Intel easily do this delayed vblank
> > processing in the non-pageflip case?
>
> Intel's problem :-) But yeah we have page flip timestamp registers, so
> worst case all we need to do is shuffle code around a bit. And we have
> interrupts for both start of vblank and and of vblank. It might be a bit
> more work because we use the vblank interrupt to avoid races in atomic
> updates, but that's not too terrible to fix.
>
> > From my user perspective as a developer of a neuroscience research
> > application that has a couple of exciting/important use cases for VRR
> > mode, i absolutely do need trustworthy and precise pageflip event
> > timestamps that represent reality, otherwise VRR mode would be less
> > than useless for me. I can do without meaningful vblank timestamps in
> > VRR mode though, and expected to do without them, as any scheduling
> > has to happen time-based instead of based on vblank counts anyway,
> > given that vblank counts are quite meaningless if every frame can have
> > a different duration. I'd expect that situation to be similar for
> > other apps that would want to use timestamps in VRR mode like video
> > games, movie players or VR/AR applications.
>
> Yeah for that you want to schedule your frames with a target frame number.
> Would still be nice if vblank timestamps wouldn't be an outright lie (and
> the timestamp is still useful information, even if the frame counter
> isn't - many displays have min/max frame rates for VRR, which is
> information we could perhaps expose).
> -Daniel
>
> >
> > -mario
> >
> > > >
> > > > 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@xxxxxxxxxxxxxxxxxxxxx
> > > > >> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > > > >
> > > >
> > >
> > >
> > > --
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > > +41 (0) 79 365 57 48 - http://blog.ffwll.ch
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
amd-gfx mailing list
amd-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux