diff options
author | Simon Ser <contact@emersion.fr> | 2022-08-30 17:29:35 +0000 |
---|---|---|
committer | Cristian Ciocaltea <cristian.ciocaltea@collabora.com> | 2023-08-08 23:40:18 +0300 |
commit | f6de551227de6244119f9f2bea3ae81543ee7c4f (patch) | |
tree | 23eb73d8e286d6c04a2cc24165e6d5d91f10e6ed /drivers/gpu | |
parent | 9d923e79d060d8c7218c8229c65c964b7f04e864 (diff) | |
download | linux-f6de551227de6244119f9f2bea3ae81543ee7c4f.tar.gz |
drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits
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> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Link: https://lore.kernel.org/r/20220830172851.269402-5-contact@emersion.fr
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/drm_atomic_uapi.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index c06d0639d552..945761968428 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -1282,6 +1282,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) { @@ -1322,9 +1334,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. */ @@ -1422,6 +1441,9 @@ retry: 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) { |