diff mbox series

[v2,4/6] drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits

Message ID 20220830172851.269402-5-contact@emersion.fr (mailing list archive)
State New, archived
Headers show
Series Add support for atomic async page-flips | expand

Commit Message

Simon Ser Aug. 30, 2022, 5:29 p.m. UTC
If the driver supports it, allow user-space to supply the
DRM_MODE_PAGE_FLIP_ASYNC flag to request an async page-flip.
Set drm_crtc_state.async_flip accordingly.

Document that drivers will reject atomic commits if an async
flip isn't possible. This allows user-space to fall back to
something else. For instance, Xorg falls back to a blit.
Another option is to wait as close to the next vblank as
possible before performing the page-flip to reduce latency.

v2: document new uAPI

Signed-off-by: Simon Ser <contact@emersion.fr>
Co-developed-by: André Almeida <andrealmeid@igalia.com>
Signed-off-by: André Almeida <andrealmeid@igalia.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Joshua Ashton <joshua@froggi.es>
Cc: Melissa Wen <mwen@igalia.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Harry Wentland <hwentlan@amd.com>
Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_atomic_uapi.c | 28 +++++++++++++++++++++++++---
 include/uapi/drm/drm_mode.h       |  4 ++++
 2 files changed, 29 insertions(+), 3 deletions(-)

Comments

Pekka Paalanen Aug. 31, 2022, 7:50 a.m. UTC | #1
On Tue, 30 Aug 2022 17:29:35 +0000
Simon Ser <contact@emersion.fr> wrote:

> If the driver supports it, allow user-space to supply the
> DRM_MODE_PAGE_FLIP_ASYNC flag to request an async page-flip.
> Set drm_crtc_state.async_flip accordingly.
> 
> Document that drivers will reject atomic commits if an async
> flip isn't possible. This allows user-space to fall back to
> something else. For instance, Xorg falls back to a blit.
> Another option is to wait as close to the next vblank as
> possible before performing the page-flip to reduce latency.
> 
> v2: document new uAPI
> 
> Signed-off-by: Simon Ser <contact@emersion.fr>
> Co-developed-by: André Almeida <andrealmeid@igalia.com>
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Joshua Ashton <joshua@froggi.es>
> Cc: Melissa Wen <mwen@igalia.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Harry Wentland <hwentlan@amd.com>
> Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/drm_atomic_uapi.c | 28 +++++++++++++++++++++++++---
>  include/uapi/drm/drm_mode.h       |  4 ++++
>  2 files changed, 29 insertions(+), 3 deletions(-)

...

> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 86a292c3185a..cce1a1bea645 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -942,6 +942,10 @@ struct hdr_output_metadata {
>   * Request that the page-flip is performed as soon as possible, ie. with no
>   * delay due to waiting for vblank. This may cause tearing to be visible on
>   * the screen.
> + *
> + * When used with atomic uAPI, the driver will return an error if the hardware
> + * doesn't support performing an asynchronous page-flip for this update.
> + * User-space should handle this, e.g. by falling back to a regular page-flip.
>   */
>  #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
>  #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4

Hi Simon,

recalling what Ville explained that enabling async flips might require
one more sync flip first, how is that supposed to work?

A TEST_ONLY commit is not allowed to change hardware state, and a
failing real commit is not allowed to change hardware state either
(right?), therefore a failing async flip cannot prepare the next flip
to be async, meaning async will never work.


Thanks,
pq
Simon Ser Aug. 31, 2022, 2:56 p.m. UTC | #2
On Wednesday, August 31st, 2022 at 09:50, Pekka Paalanen <ppaalanen@gmail.com> wrote:

> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 86a292c3185a..cce1a1bea645 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -942,6 +942,10 @@ struct hdr_output_metadata {
> > * Request that the page-flip is performed as soon as possible, ie. with no
> > * delay due to waiting for vblank. This may cause tearing to be visible on
> > * the screen.
> > + *
> > + * When used with atomic uAPI, the driver will return an error if the hardware
> > + * doesn't support performing an asynchronous page-flip for this update.
> > + * User-space should handle this, e.g. by falling back to a regular page-flip.
> > */
> > #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
> > #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
> 
> Hi Simon,
> 
> recalling what Ville explained that enabling async flips might require
> one more sync flip first, how is that supposed to work?
> 
> A TEST_ONLY commit is not allowed to change hardware state, and a
> failing real commit is not allowed to change hardware state either
> (right?), therefore a failing async flip cannot prepare the next flip
> to be async, meaning async will never work.

I'd blame it on bad hw, and make it one special quirk in the driver,
just like it does now.

Ville, thoughts?
Ville Syrjälä Aug. 31, 2022, 3:52 p.m. UTC | #3
On Wed, Aug 31, 2022 at 02:56:12PM +0000, Simon Ser wrote:
> On Wednesday, August 31st, 2022 at 09:50, Pekka Paalanen <ppaalanen@gmail.com> wrote:
> 
> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > index 86a292c3185a..cce1a1bea645 100644
> > > --- a/include/uapi/drm/drm_mode.h
> > > +++ b/include/uapi/drm/drm_mode.h
> > > @@ -942,6 +942,10 @@ struct hdr_output_metadata {
> > > * Request that the page-flip is performed as soon as possible, ie. with no
> > > * delay due to waiting for vblank. This may cause tearing to be visible on
> > > * the screen.
> > > + *
> > > + * When used with atomic uAPI, the driver will return an error if the hardware
> > > + * doesn't support performing an asynchronous page-flip for this update.
> > > + * User-space should handle this, e.g. by falling back to a regular page-flip.
> > > */
> > > #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
> > > #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
> > 
> > Hi Simon,
> > 
> > recalling what Ville explained that enabling async flips might require
> > one more sync flip first, how is that supposed to work?
> > 
> > A TEST_ONLY commit is not allowed to change hardware state, and a
> > failing real commit is not allowed to change hardware state either
> > (right?), therefore a failing async flip cannot prepare the next flip
> > to be async, meaning async will never work.
> 
> I'd blame it on bad hw, and make it one special quirk in the driver,
> just like it does now.
> 
> Ville, thoughts?

I suppose it might be worth mentioning that special case here,
to avoid people getting confused why the first async flip was
accepted but took a full frame to complete.
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 79730fa1dd8e..ee24ed7e2edb 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1278,6 +1278,18 @@  static void complete_signaling(struct drm_device *dev,
 	kfree(fence_state);
 }
 
+static void
+set_async_flip(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int i;
+
+	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+		crtc_state->async_flip = true;
+	}
+}
+
 int drm_mode_atomic_ioctl(struct drm_device *dev,
 			  void *data, struct drm_file *file_priv)
 {
@@ -1318,9 +1330,16 @@  int drm_mode_atomic_ioctl(struct drm_device *dev,
 	}
 
 	if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) {
-		drm_dbg_atomic(dev,
-			       "commit failed: invalid flag DRM_MODE_PAGE_FLIP_ASYNC\n");
-		return -EINVAL;
+		if (!dev->mode_config.async_page_flip) {
+			drm_dbg_atomic(dev,
+				       "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported\n");
+			return -EINVAL;
+		}
+		if (dev->mode_config.atomic_async_page_flip_not_supported) {
+			drm_dbg_atomic(dev,
+				       "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported with atomic\n");
+			return -EINVAL;
+		}
 	}
 
 	/* can't test and expect an event at the same time. */
@@ -1418,6 +1437,9 @@  int drm_mode_atomic_ioctl(struct drm_device *dev,
 	if (ret)
 		goto out;
 
+	if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC)
+		set_async_flip(state);
+
 	if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
 		ret = drm_atomic_check_only(state);
 	} else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 86a292c3185a..cce1a1bea645 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -942,6 +942,10 @@  struct hdr_output_metadata {
  * Request that the page-flip is performed as soon as possible, ie. with no
  * delay due to waiting for vblank. This may cause tearing to be visible on
  * the screen.
+ *
+ * When used with atomic uAPI, the driver will return an error if the hardware
+ * doesn't support performing an asynchronous page-flip for this update.
+ * User-space should handle this, e.g. by falling back to a regular page-flip.
  */
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4