intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RESEND 0/6] drm/atomic: add async plane update
@ 2017-05-25 19:51 Gustavo Padovan
  2017-05-25 19:51 ` [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous " Gustavo Padovan
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Gustavo Padovan @ 2017-05-25 19:51 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, intel-gfx

From: Gustavo Padovan <gustavo.padovan@collabora.com>

Hi,

Resending to include intel-gfx@ and get the patches picked up by CI.

New version of the patches after the comments from Archit. Full details
and the previous discussion can be found here:

https://www.spinics.net/lists/dri-devel/msg141337.html

I'm not including the uAPI patch here, because we don't have any userspace
for it yet.

Please review. Thanks!

Gustavo

--
Gustavo Padovan (6):
  drm/atomic: initial support for asynchronous plane update
  drm/i915: update cursors asynchronously through atomic
  drm/i915: remove intel_cursor_plane_funcs
  drm/msm: update cursors asynchronously through atomic
  drm/msm: remove mdp5_cursor_plane_funcs
  drm/vc4: update cursors asynchronously through atomic

 drivers/gpu/drm/drm_atomic.c              |  65 +++++++++++
 drivers/gpu/drm/drm_atomic_helper.c       |  35 ++++++
 drivers/gpu/drm/i915/intel_atomic_plane.c |  73 +++++++++++++
 drivers/gpu/drm/i915/intel_display.c      | 160 ++++-----------------------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 175 +++++++++++-------------------
 drivers/gpu/drm/msm/msm_atomic.c          |   6 +
 drivers/gpu/drm/vc4/vc4_plane.c           |  99 ++++++-----------
 include/drm/drm_atomic.h                  |   2 +
 include/drm/drm_atomic_helper.h           |   2 +
 include/drm/drm_modeset_helper_vtables.h  |  48 ++++++++
 10 files changed, 355 insertions(+), 310 deletions(-)

-- 
2.9.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous plane update
  2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
@ 2017-05-25 19:51 ` Gustavo Padovan
  2017-05-26  8:45   ` Archit Taneja
  2017-06-01  0:47   ` Eric Anholt
  2017-05-25 19:51 ` [PATCH RESEND 2/6] drm/i915: update cursors asynchronously through atomic Gustavo Padovan
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: Gustavo Padovan @ 2017-05-25 19:51 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, intel-gfx, Daniel Vetter

From: Gustavo Padovan <gustavo.padovan@collabora.com>

In some cases, like cursor updates, it is interesting to update the
plane in an asynchronous fashion to avoid big delays. The current queued
update could be still waiting for a fence to signal and thus block any
subsequent update until its scan out. In cases like this if we update the
cursor synchronously through the atomic API it will cause significant
delays that would even be noticed by the final user.

This patch creates a fast path to jump ahead the current queued state and
do single planes updates without going through all atomic steps in
drm_atomic_helper_commit(). We take this path for legacy cursor updates.

For now only single plane updates are supported, but we plan to support
multiple planes updates and async PageFlips through this interface as well
in the near future.

v4:
	- fix state->crtc NULL check (Archit Taneja)

v3:
	- fix iteration on the wrong crtc state
	- put back code to forbid updates if there is a queued update for
	the same plane (Ville Syrjälä)
	- move size checks back to drivers (Ville Syrjälä)
	- move ASYNC_UPDATE flag addition to its own patch (Ville Syrjälä)

v2:
	- allow updates even if there is a queued update for the same
	plane.
        - fixes on the documentation (Emil Velikov)
        - unconditionally call ->atomic_async_update (Emil Velikov)
        - check for ->atomic_async_update earlier (Daniel Vetter)
        - make ->atomic_async_check() the last step (Daniel Vetter)
        - add ASYNC_UPDATE flag (Eric Anholt)
        - update state in core after ->atomic_async_update (Eric Anholt)
	- update docs (Eric Anholt)

Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Eric Anholt <eric@anholt.net>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
---
 drivers/gpu/drm/drm_atomic.c             | 65 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_atomic_helper.c      | 35 +++++++++++++++++
 include/drm/drm_atomic.h                 |  2 +
 include/drm/drm_atomic_helper.h          |  2 +
 include/drm/drm_modeset_helper_vtables.h | 48 +++++++++++++++++++++++
 5 files changed, 152 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index be62774..2a0c297 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -631,6 +631,68 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
 	return 0;
 }
 
+static bool drm_atomic_async_check(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	struct drm_plane *__plane, *plane = NULL;
+	struct drm_plane_state *__plane_state, *plane_state = NULL;
+	const struct drm_plane_helper_funcs *funcs;
+	int i, j, n_planes = 0;
+
+	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+		if (drm_atomic_crtc_needs_modeset(crtc_state))
+			return false;
+	}
+
+	for_each_new_plane_in_state(state, __plane, __plane_state, i) {
+		n_planes++;
+		plane = __plane;
+		plane_state = __plane_state;
+	}
+
+	/* FIXME: we support only single plane updates for now */
+	if (!plane || n_planes != 1)
+		return false;
+
+	if (!plane_state->crtc)
+		return false;
+
+	funcs = plane->helper_private;
+	if (!funcs->atomic_async_update)
+		return false;
+
+	if (plane_state->fence)
+		return false;
+
+	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+		if (plane->crtc != crtc)
+			continue;
+
+		spin_lock(&crtc->commit_lock);
+		commit = list_first_entry_or_null(&crtc->commit_list,
+						  struct drm_crtc_commit,
+						  commit_entry);
+		if (!commit) {
+			spin_unlock(&crtc->commit_lock);
+			continue;
+		}
+		spin_unlock(&crtc->commit_lock);
+
+		if (!crtc->state->state)
+			continue;
+
+		for_each_plane_in_state(crtc->state->state, __plane,
+					__plane_state, j) {
+			if (__plane == plane)
+				return false;
+		}
+	}
+
+	return !funcs->atomic_async_check(plane, plane_state);
+}
+
 static void drm_atomic_crtc_print_state(struct drm_printer *p,
 		const struct drm_crtc_state *state)
 {
@@ -1591,6 +1653,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
 		}
 	}
 
+	if (state->legacy_cursor_update)
+		state->async_update = drm_atomic_async_check(state);
+
 	return ret;
 }
 EXPORT_SYMBOL(drm_atomic_check_only);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 5a3c9c0..a8efdfe 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1235,6 +1235,30 @@ static void commit_work(struct work_struct *work)
 }
 
 /**
+ * drm_atomic_helper_async_commit - commit state asynchronously
+ *
+ * This function commits a state asynchronously, i.e., not vblank
+ * synchronized. It should be used on a state only when
+ * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
+ * the states like normal sync commits, but just do in-place changes on the
+ * current state.
+ */
+void drm_atomic_helper_async_commit(struct drm_device *dev,
+				    struct drm_atomic_state *state)
+{
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
+	const struct drm_plane_helper_funcs *funcs;
+	int i;
+
+	for_each_new_plane_in_state(state, plane, plane_state, i) {
+		funcs = plane->helper_private;
+		funcs->atomic_async_update(plane, plane_state);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_async_commit);
+
+/**
  * drm_atomic_helper_commit - commit validated state object
  * @dev: DRM device
  * @state: the driver state object
@@ -1258,6 +1282,17 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 {
 	int ret;
 
+	if (state->async_update) {
+		ret = drm_atomic_helper_prepare_planes(dev, state);
+		if (ret)
+			return ret;
+
+		drm_atomic_helper_async_commit(dev, state);
+		drm_atomic_helper_cleanup_planes(dev, state);
+
+		return 0;
+	}
+
 	ret = drm_atomic_helper_setup_commit(state, nonblock);
 	if (ret)
 		return ret;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 788daf7..70ca279 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -160,6 +160,7 @@ struct __drm_connnectors_state {
  * @dev: parent DRM device
  * @allow_modeset: allow full modeset
  * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
+ * @async_update: hint for asynchronous plane update
  * @planes: pointer to array of structures with per-plane data
  * @crtcs: pointer to array of CRTC pointers
  * @num_connector: size of the @connectors and @connector_states arrays
@@ -172,6 +173,7 @@ struct drm_atomic_state {
 	struct drm_device *dev;
 	bool allow_modeset : 1;
 	bool legacy_cursor_update : 1;
+	bool async_update : 1;
 	struct __drm_planes_state *planes;
 	struct __drm_crtcs_state *crtcs;
 	int num_connector;
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index f0a8678..8571b51 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -44,6 +44,8 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
 int drm_atomic_helper_commit(struct drm_device *dev,
 			     struct drm_atomic_state *state,
 			     bool nonblock);
+void drm_atomic_helper_async_commit(struct drm_device *dev,
+				    struct drm_atomic_state *state);
 
 int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
 					struct drm_atomic_state *state,
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index c01c328..7964a78 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -1048,6 +1048,54 @@ struct drm_plane_helper_funcs {
 	 */
 	void (*atomic_disable)(struct drm_plane *plane,
 			       struct drm_plane_state *old_state);
+
+	/**
+	 * @atomic_async_check:
+	 *
+	 * Drivers should set this function pointer to check if the plane state
+	 * can be updated in a async fashion. Here async means "not vblank
+	 * synchronized".
+	 *
+	 * This hook is called by drm_atomic_async_check() to establish if a
+	 * given update can be committed asynchronously, that is, if it can
+	 * jump ahead the state currently queued for update.
+	 *
+	 * RETURNS:
+	 *
+	 * Return 0 on success and any error returned indicates that the update
+	 * can not be applied in asynchronous manner.
+	 */
+	int (*atomic_async_check)(struct drm_plane *plane,
+				  struct drm_plane_state *state);
+
+	/**
+	 * @atomic_async_update:
+	 *
+	 * Drivers should set this function pointer to perform asynchronous
+	 * updates of planes, that is, jump ahead the currently queued
+	 * state for and update the plane. Here async means "not vblank
+	 * synchronized".
+	 *
+	 * This hook is called by drm_atomic_helper_async_commit().
+	 *
+	 * An async update will happen on legacy cursor updates.
+	 *
+	 * Note that unlike &drm_plane_helper_funcs.atomic_update this hook
+	 * takes the new &drm_plane_state as parameter. When doing async_update
+	 * drivers shouldn't replace the &drm_plane_state but update the
+	 * current one with the new plane configurations in the new
+	 * plane_state.
+	 *
+	 * FIXME:
+	 *  - It only works for single plane updates
+	 *  - Async Pageflips are not supported yet
+	 *  - Some hm might still scan out the old buffer until the next
+	 *  vblank, however we let go of the fb references as soon as
+	 *  we run this hook. For now drivers must implement their own workers
+	 *  for defering if needed, until a common solution is created.
+	 */
+	void (*atomic_async_update)(struct drm_plane *plane,
+				    struct drm_plane_state *new_state);
 };
 
 /**
-- 
2.9.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RESEND 2/6] drm/i915: update cursors asynchronously through atomic
  2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
  2017-05-25 19:51 ` [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous " Gustavo Padovan
@ 2017-05-25 19:51 ` Gustavo Padovan
  2017-05-25 19:51 ` [PATCH RESEND 3/6] drm/i915: remove intel_cursor_plane_funcs Gustavo Padovan
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Gustavo Padovan @ 2017-05-25 19:51 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, intel-gfx, Daniel Vetter

From: Gustavo Padovan <gustavo.padovan@collabora.com>

Add support to async updates of cursors by using the new atomic
interface for that. Basically what this commit does is do what
intel_legacy_cursor_update() did but through atomic.

v3:
	- set correct vma to new state for cleanup
	- move size checks back to drivers (Ville Syrjälä)

v2:
	- move fb setting to core and use new state (Eric Anholt)

Cc: Daniel Vetter <daniel.vetter@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
---
 drivers/gpu/drm/i915/intel_atomic_plane.c |  73 +++++++++++++++
 drivers/gpu/drm/i915/intel_display.c      | 149 +++++-------------------------
 2 files changed, 97 insertions(+), 125 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index cfb4729..974c91f 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -246,11 +246,84 @@ static void intel_plane_atomic_update(struct drm_plane *plane,
 	}
 }
 
+static int intel_plane_atomic_async_check(struct drm_plane *plane,
+					  struct drm_plane_state *state)
+{
+	struct drm_crtc *crtc = plane->state->crtc;
+	struct drm_crtc_state *crtc_state = crtc->state;
+
+	if (plane->type != DRM_PLANE_TYPE_CURSOR)
+		return -EINVAL;
+
+	/*
+	 * When crtc is inactive or there is a modeset pending,
+	 * wait for it to complete in the slowpath
+	 */
+	if (!crtc_state->active || to_intel_crtc_state(crtc_state)->update_pipe)
+		return -EINVAL;
+
+	/*
+	 * If any parameters change that may affect watermarks,
+	 * take the slowpath. Only changing fb or position should be
+	 * in the fastpath.
+	 */
+	if (plane->state->crtc != state->crtc ||
+	    plane->state->src_w != state->src_w ||
+	    plane->state->src_h != state->src_h ||
+	    plane->state->crtc_w != state->crtc_w ||
+	    plane->state->crtc_h != state->crtc_h ||
+	    !plane->state->fb != !state->fb)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void intel_plane_atomic_async_update(struct drm_plane *plane,
+					    struct drm_plane_state *new_state)
+{
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct drm_crtc *crtc = plane->state->crtc;
+	struct drm_framebuffer *old_fb;
+	struct i915_vma *old_vma;
+
+	old_vma = to_intel_plane_state(plane->state)->vma;
+	old_fb = plane->state->fb;
+
+	i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(new_state->fb),
+			  intel_plane->frontbuffer_bit);
+
+	plane->state->src_x = new_state->src_x;
+	plane->state->src_y = new_state->src_y;
+	plane->state->crtc_x = new_state->crtc_x;
+	plane->state->crtc_y = new_state->crtc_y;
+	plane->state->fb = new_state->fb;
+	*to_intel_plane_state(plane->state) = *to_intel_plane_state(new_state);
+
+	to_intel_plane_state(new_state)->vma = old_vma;
+	new_state->fb = old_fb;
+
+	if (plane->state->visible) {
+		trace_intel_update_plane(plane, to_intel_crtc(crtc));
+		intel_plane->update_plane(plane,
+					  to_intel_crtc_state(crtc->state),
+					  to_intel_plane_state(plane->state));
+	} else {
+		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
+		intel_plane->disable_plane(plane, crtc);
+	}
+
+	mutex_lock(&plane->dev->struct_mutex);
+	intel_cleanup_plane_fb(plane, new_state);
+	mutex_unlock(&plane->dev->struct_mutex);
+}
+
 const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
 	.prepare_fb = intel_prepare_plane_fb,
 	.cleanup_fb = intel_cleanup_plane_fb,
 	.atomic_check = intel_plane_atomic_check,
 	.atomic_update = intel_plane_atomic_update,
+	.atomic_async_check = intel_plane_atomic_async_check,
+	.atomic_async_update = intel_plane_atomic_async_update,
 };
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 207f144..7f4c8d3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13010,6 +13010,26 @@ static int intel_atomic_commit(struct drm_device *dev,
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	int ret = 0;
 
+	/*
+	 * The atomic async update fast path takes care
+	 * of avoiding the vblank waits for simple cursor
+	 * movement and flips. For cursor on/off and size changes,
+	 * we want to perform the vblank waits so that watermark
+	 * updates happen during the correct frames. Gen9+ have
+	 * double buffered watermarks and so shouldn't need this.
+	 */
+	if (state->async_update) {
+		ret = mutex_lock_interruptible(&dev->struct_mutex);
+		if (ret)
+			return ret;
+
+		ret = drm_atomic_helper_prepare_planes(dev, state);
+		mutex_unlock(&dev->struct_mutex);
+
+		drm_atomic_helper_async_commit(dev, state);
+		return 0;
+	}
+
 	ret = drm_atomic_helper_setup_commit(state, nonblock);
 	if (ret)
 		return ret;
@@ -13168,6 +13188,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		}
 	}
 
+	if (new_state->state->async_update)
+		return 0;
+
 	if (!obj && !old_obj)
 		return 0;
 
@@ -13395,132 +13418,8 @@ const struct drm_plane_funcs intel_plane_funcs = {
 	.atomic_destroy_state = intel_plane_destroy_state,
 };
 
-static int
-intel_legacy_cursor_update(struct drm_plane *plane,
-			   struct drm_crtc *crtc,
-			   struct drm_framebuffer *fb,
-			   int crtc_x, int crtc_y,
-			   unsigned int crtc_w, unsigned int crtc_h,
-			   uint32_t src_x, uint32_t src_y,
-			   uint32_t src_w, uint32_t src_h,
-			   struct drm_modeset_acquire_ctx *ctx)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
-	int ret;
-	struct drm_plane_state *old_plane_state, *new_plane_state;
-	struct intel_plane *intel_plane = to_intel_plane(plane);
-	struct drm_framebuffer *old_fb;
-	struct drm_crtc_state *crtc_state = crtc->state;
-	struct i915_vma *old_vma;
-
-	/*
-	 * When crtc is inactive or there is a modeset pending,
-	 * wait for it to complete in the slowpath
-	 */
-	if (!crtc_state->active || needs_modeset(crtc_state) ||
-	    to_intel_crtc_state(crtc_state)->update_pipe)
-		goto slow;
-
-	old_plane_state = plane->state;
-
-	/*
-	 * If any parameters change that may affect watermarks,
-	 * take the slowpath. Only changing fb or position should be
-	 * in the fastpath.
-	 */
-	if (old_plane_state->crtc != crtc ||
-	    old_plane_state->src_w != src_w ||
-	    old_plane_state->src_h != src_h ||
-	    old_plane_state->crtc_w != crtc_w ||
-	    old_plane_state->crtc_h != crtc_h ||
-	    !old_plane_state->fb != !fb)
-		goto slow;
-
-	new_plane_state = intel_plane_duplicate_state(plane);
-	if (!new_plane_state)
-		return -ENOMEM;
-
-	drm_atomic_set_fb_for_plane(new_plane_state, fb);
-
-	new_plane_state->src_x = src_x;
-	new_plane_state->src_y = src_y;
-	new_plane_state->src_w = src_w;
-	new_plane_state->src_h = src_h;
-	new_plane_state->crtc_x = crtc_x;
-	new_plane_state->crtc_y = crtc_y;
-	new_plane_state->crtc_w = crtc_w;
-	new_plane_state->crtc_h = crtc_h;
-
-	ret = intel_plane_atomic_check_with_state(to_intel_crtc_state(crtc->state),
-						  to_intel_plane_state(new_plane_state));
-	if (ret)
-		goto out_free;
-
-	ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
-	if (ret)
-		goto out_free;
-
-	if (INTEL_INFO(dev_priv)->cursor_needs_physical) {
-		int align = IS_I830(dev_priv) ? 16 * 1024 : 256;
-
-		ret = i915_gem_object_attach_phys(intel_fb_obj(fb), align);
-		if (ret) {
-			DRM_DEBUG_KMS("failed to attach phys object\n");
-			goto out_unlock;
-		}
-	} else {
-		struct i915_vma *vma;
-
-		vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation);
-		if (IS_ERR(vma)) {
-			DRM_DEBUG_KMS("failed to pin object\n");
-
-			ret = PTR_ERR(vma);
-			goto out_unlock;
-		}
-
-		to_intel_plane_state(new_plane_state)->vma = vma;
-	}
-
-	old_fb = old_plane_state->fb;
-	old_vma = to_intel_plane_state(old_plane_state)->vma;
-
-	i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
-			  intel_plane->frontbuffer_bit);
-
-	/* Swap plane state */
-	new_plane_state->fence = old_plane_state->fence;
-	*to_intel_plane_state(old_plane_state) = *to_intel_plane_state(new_plane_state);
-	new_plane_state->fence = NULL;
-	new_plane_state->fb = old_fb;
-	to_intel_plane_state(new_plane_state)->vma = old_vma;
-
-	if (plane->state->visible) {
-		trace_intel_update_plane(plane, to_intel_crtc(crtc));
-		intel_plane->update_plane(plane,
-					  to_intel_crtc_state(crtc->state),
-					  to_intel_plane_state(plane->state));
-	} else {
-		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
-		intel_plane->disable_plane(plane, crtc);
-	}
-
-	intel_cleanup_plane_fb(plane, new_plane_state);
-
-out_unlock:
-	mutex_unlock(&dev_priv->drm.struct_mutex);
-out_free:
-	intel_plane_destroy_state(plane, new_plane_state);
-	return ret;
-
-slow:
-	return drm_atomic_helper_update_plane(plane, crtc, fb,
-					      crtc_x, crtc_y, crtc_w, crtc_h,
-					      src_x, src_y, src_w, src_h, ctx);
-}
-
 static const struct drm_plane_funcs intel_cursor_plane_funcs = {
-	.update_plane = intel_legacy_cursor_update,
+	.update_plane = drm_atomic_helper_update_plane,
 	.disable_plane = drm_atomic_helper_disable_plane,
 	.destroy = intel_plane_destroy,
 	.set_property = drm_atomic_helper_plane_set_property,
-- 
2.9.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RESEND 3/6] drm/i915: remove intel_cursor_plane_funcs
  2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
  2017-05-25 19:51 ` [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous " Gustavo Padovan
  2017-05-25 19:51 ` [PATCH RESEND 2/6] drm/i915: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-05-25 19:51 ` Gustavo Padovan
  2017-05-25 19:51 ` [PATCH RESEND 4/6] drm/msm: update cursors asynchronously through atomic Gustavo Padovan
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Gustavo Padovan @ 2017-05-25 19:51 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, intel-gfx, Daniel Vetter

From: Gustavo Padovan <gustavo.padovan@collabora.com>

After converting legacy cursor updates to atomic async commits
intel_cursor_plane_funcs just duplicates intel_plane_funcs now.

Cc: Daniel Vetter <daniel.vetter@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
---
 drivers/gpu/drm/i915/intel_display.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7f4c8d3..ee75165 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13418,17 +13418,6 @@ const struct drm_plane_funcs intel_plane_funcs = {
 	.atomic_destroy_state = intel_plane_destroy_state,
 };
 
-static const struct drm_plane_funcs intel_cursor_plane_funcs = {
-	.update_plane = drm_atomic_helper_update_plane,
-	.disable_plane = drm_atomic_helper_disable_plane,
-	.destroy = intel_plane_destroy,
-	.set_property = drm_atomic_helper_plane_set_property,
-	.atomic_get_property = intel_plane_atomic_get_property,
-	.atomic_set_property = intel_plane_atomic_set_property,
-	.atomic_duplicate_state = intel_plane_duplicate_state,
-	.atomic_destroy_state = intel_plane_destroy_state,
-};
-
 static struct intel_plane *
 intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
 {
@@ -13675,7 +13664,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
 	cursor->disable_plane = intel_disable_cursor_plane;
 
 	ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base,
-				       0, &intel_cursor_plane_funcs,
+				       0, &intel_plane_funcs,
 				       intel_cursor_formats,
 				       ARRAY_SIZE(intel_cursor_formats),
 				       DRM_PLANE_TYPE_CURSOR,
-- 
2.9.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RESEND 4/6] drm/msm: update cursors asynchronously through atomic
  2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
                   ` (2 preceding siblings ...)
  2017-05-25 19:51 ` [PATCH RESEND 3/6] drm/i915: remove intel_cursor_plane_funcs Gustavo Padovan
@ 2017-05-25 19:51 ` Gustavo Padovan
  2017-05-26  8:44   ` Archit Taneja
  2017-05-25 19:51 ` [PATCH RESEND 5/6] drm/msm: remove mdp5_cursor_plane_funcs Gustavo Padovan
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Gustavo Padovan @ 2017-05-25 19:51 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, intel-gfx, Archit Taneja

From: Gustavo Padovan <gustavo.padovan@collabora.com>

Add support to async updates of cursors by using the new atomic
interface for that. Basically what this commit does is do what
mdp5_update_cursor_plane_legacy() did but through atomic.

v4: add missing atomic async commit call to msm_atomic_commit(Archit Taneja)

v3: move size checks back to drivers (Ville Syrjälä)

v2: move fb setting to core and use new state (Eric Anholt)

Cc: Rob Clark <robdclark@gmail.com>
Cc: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 151 +++++++++++++-----------------
 drivers/gpu/drm/msm/msm_atomic.c          |   6 ++
 2 files changed, 69 insertions(+), 88 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index a38c5fe..07106c1 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -33,15 +33,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct drm_framebuffer *fb,
 		struct drm_rect *src, struct drm_rect *dest);
 
-static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane,
-		struct drm_crtc *crtc,
-		struct drm_framebuffer *fb,
-		int crtc_x, int crtc_y,
-		unsigned int crtc_w, unsigned int crtc_h,
-		uint32_t src_x, uint32_t src_y,
-		uint32_t src_w, uint32_t src_h,
-		struct drm_modeset_acquire_ctx *ctx);
-
 static struct mdp5_kms *get_kms(struct drm_plane *plane)
 {
 	struct msm_drm_private *priv = plane->dev->dev_private;
@@ -257,7 +248,7 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
 };
 
 static const struct drm_plane_funcs mdp5_cursor_plane_funcs = {
-		.update_plane = mdp5_update_cursor_plane_legacy,
+		.update_plane = drm_atomic_helper_update_plane,
 		.disable_plane = drm_atomic_helper_disable_plane,
 		.destroy = mdp5_plane_destroy,
 		.set_property = drm_atomic_helper_plane_set_property,
@@ -484,11 +475,73 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane,
 	}
 }
 
+static int mdp5_plane_atomic_async_check(struct drm_plane *plane,
+					 struct drm_plane_state *state)
+{
+	struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state);
+	struct drm_crtc_state *crtc_state;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(state->state,
+							state->crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	if (!crtc_state->active)
+		return -EINVAL;
+
+	mdp5_state = to_mdp5_plane_state(state);
+
+	/* don't use fast path if we don't have a hwpipe allocated yet */
+	if (!mdp5_state->hwpipe)
+		return -EINVAL;
+
+	/* only allow changing of position(crtc x/y or src x/y) in fast path */
+	if (plane->state->crtc != state->crtc ||
+	    plane->state->src_w != state->src_w ||
+	    plane->state->src_h != state->src_h ||
+	    plane->state->crtc_w != state->crtc_w ||
+	    plane->state->crtc_h != state->crtc_h ||
+	    !plane->state->fb ||
+	    plane->state->fb != state->fb)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void mdp5_plane_atomic_async_update(struct drm_plane *plane,
+					   struct drm_plane_state *new_state)
+{
+	plane->state->src_x = new_state->src_x;
+	plane->state->src_y = new_state->src_y;
+	plane->state->crtc_x = new_state->crtc_x;
+	plane->state->crtc_y = new_state->crtc_y;
+
+	if (plane_enabled(new_state)) {
+		struct mdp5_ctl *ctl;
+		struct mdp5_pipeline *pipeline =
+					mdp5_crtc_get_pipeline(plane->crtc);
+		int ret;
+
+		ret = mdp5_plane_mode_set(plane, new_state->crtc, new_state->fb,
+				&new_state->src, &new_state->dst);
+		WARN_ON(ret < 0);
+
+		ctl = mdp5_crtc_get_ctl(new_state->crtc);
+
+		mdp5_ctl_commit(ctl, pipeline, mdp5_plane_get_flush(plane));
+	}
+
+	*to_mdp5_plane_state(plane->state) =
+		*to_mdp5_plane_state(new_state);
+}
+
 static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = {
 		.prepare_fb = mdp5_plane_prepare_fb,
 		.cleanup_fb = mdp5_plane_cleanup_fb,
 		.atomic_check = mdp5_plane_atomic_check,
 		.atomic_update = mdp5_plane_atomic_update,
+		.atomic_async_check = mdp5_plane_atomic_async_check,
+		.atomic_async_update = mdp5_plane_atomic_async_update,
 };
 
 static void set_scanout_locked(struct mdp5_kms *mdp5_kms,
@@ -997,84 +1050,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
 	return ret;
 }
 
-static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane,
-			struct drm_crtc *crtc, struct drm_framebuffer *fb,
-			int crtc_x, int crtc_y,
-			unsigned int crtc_w, unsigned int crtc_h,
-			uint32_t src_x, uint32_t src_y,
-			uint32_t src_w, uint32_t src_h,
-			struct drm_modeset_acquire_ctx *ctx)
-{
-	struct drm_plane_state *plane_state, *new_plane_state;
-	struct mdp5_plane_state *mdp5_pstate;
-	struct drm_crtc_state *crtc_state = crtc->state;
-	int ret;
-
-	if (!crtc_state->active || drm_atomic_crtc_needs_modeset(crtc_state))
-		goto slow;
-
-	plane_state = plane->state;
-	mdp5_pstate = to_mdp5_plane_state(plane_state);
-
-	/* don't use fast path if we don't have a hwpipe allocated yet */
-	if (!mdp5_pstate->hwpipe)
-		goto slow;
-
-	/* only allow changing of position(crtc x/y or src x/y) in fast path */
-	if (plane_state->crtc != crtc ||
-	    plane_state->src_w != src_w ||
-	    plane_state->src_h != src_h ||
-	    plane_state->crtc_w != crtc_w ||
-	    plane_state->crtc_h != crtc_h ||
-	    !plane_state->fb ||
-	    plane_state->fb != fb)
-		goto slow;
-
-	new_plane_state = mdp5_plane_duplicate_state(plane);
-	if (!new_plane_state)
-		return -ENOMEM;
-
-	new_plane_state->src_x = src_x;
-	new_plane_state->src_y = src_y;
-	new_plane_state->src_w = src_w;
-	new_plane_state->src_h = src_h;
-	new_plane_state->crtc_x = crtc_x;
-	new_plane_state->crtc_y = crtc_y;
-	new_plane_state->crtc_w = crtc_w;
-	new_plane_state->crtc_h = crtc_h;
-
-	ret = mdp5_plane_atomic_check_with_state(crtc_state, new_plane_state);
-	if (ret)
-		goto slow_free;
-
-	if (new_plane_state->visible) {
-		struct mdp5_ctl *ctl;
-		struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(crtc);
-
-		ret = mdp5_plane_mode_set(plane, crtc, fb,
-					  &new_plane_state->src,
-					  &new_plane_state->dst);
-		WARN_ON(ret < 0);
-
-		ctl = mdp5_crtc_get_ctl(crtc);
-
-		mdp5_ctl_commit(ctl, pipeline, mdp5_plane_get_flush(plane));
-	}
-
-	*to_mdp5_plane_state(plane_state) =
-		*to_mdp5_plane_state(new_plane_state);
-
-	mdp5_plane_destroy_state(plane, new_plane_state);
-
-	return 0;
-slow_free:
-	mdp5_plane_destroy_state(plane, new_plane_state);
-slow:
-	return drm_atomic_helper_update_plane(plane, crtc, fb,
-					      crtc_x, crtc_y, crtc_w, crtc_h,
-					      src_x, src_y, src_w, src_h, ctx);
-}
-
 /*
  * Use this func and the one below only after the atomic state has been
  * successfully swapped
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 9633a68b..0104311 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -202,6 +202,12 @@ int msm_atomic_commit(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	if (state->async_update) {
+		drm_atomic_helper_async_commit(dev, state);
+		drm_atomic_helper_cleanup_planes(dev, state);
+		return 0;
+	}
+
 	c = commit_init(state);
 	if (!c) {
 		ret = -ENOMEM;
-- 
2.9.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RESEND 5/6] drm/msm: remove mdp5_cursor_plane_funcs
  2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
                   ` (3 preceding siblings ...)
  2017-05-25 19:51 ` [PATCH RESEND 4/6] drm/msm: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-05-25 19:51 ` Gustavo Padovan
  2017-05-26  8:44   ` Archit Taneja
  2017-05-25 19:51 ` [PATCH RESEND 6/6] drm/vc4: update cursors asynchronously through atomic Gustavo Padovan
  2017-05-25 20:11 ` ✓ Fi.CI.BAT: success for drm/atomic: add async plane update Patchwork
  6 siblings, 1 reply; 16+ messages in thread
From: Gustavo Padovan @ 2017-05-25 19:51 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, intel-gfx, Archit Taneja

From: Gustavo Padovan <gustavo.padovan@collabora.com>

After converting legacy cursor updates to atomic async commits
mdp5_cursor_plane_funcs just duplicates mdp5_plane_funcs now.

Cc: Rob Clark <robdclark@gmail.com>
Cc: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 26 +++-----------------------
 1 file changed, 3 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 07106c1..794ca07 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -247,19 +247,6 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
 		.atomic_print_state = mdp5_plane_atomic_print_state,
 };
 
-static const struct drm_plane_funcs mdp5_cursor_plane_funcs = {
-		.update_plane = drm_atomic_helper_update_plane,
-		.disable_plane = drm_atomic_helper_disable_plane,
-		.destroy = mdp5_plane_destroy,
-		.set_property = drm_atomic_helper_plane_set_property,
-		.atomic_set_property = mdp5_plane_atomic_set_property,
-		.atomic_get_property = mdp5_plane_atomic_get_property,
-		.reset = mdp5_plane_reset,
-		.atomic_duplicate_state = mdp5_plane_duplicate_state,
-		.atomic_destroy_state = mdp5_plane_destroy_state,
-		.atomic_print_state = mdp5_plane_atomic_print_state,
-};
-
 static int mdp5_plane_prepare_fb(struct drm_plane *plane,
 				 struct drm_plane_state *new_state)
 {
@@ -1111,16 +1098,9 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
 
 	spin_lock_init(&mdp5_plane->pipe_lock);
 
-	if (type == DRM_PLANE_TYPE_CURSOR)
-		ret = drm_universal_plane_init(dev, plane, 0xff,
-				&mdp5_cursor_plane_funcs,
-				mdp5_plane->formats, mdp5_plane->nformats,
-				type, NULL);
-	else
-		ret = drm_universal_plane_init(dev, plane, 0xff,
-				&mdp5_plane_funcs,
-				mdp5_plane->formats, mdp5_plane->nformats,
-				type, NULL);
+	ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
+				       mdp5_plane->formats,
+				       mdp5_plane->nformats, type, NULL);
 	if (ret)
 		goto fail;
 
-- 
2.9.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH RESEND 6/6] drm/vc4: update cursors asynchronously through atomic
  2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
                   ` (4 preceding siblings ...)
  2017-05-25 19:51 ` [PATCH RESEND 5/6] drm/msm: remove mdp5_cursor_plane_funcs Gustavo Padovan
@ 2017-05-25 19:51 ` Gustavo Padovan
  2017-06-01  0:43   ` Eric Anholt
  2017-05-25 20:11 ` ✓ Fi.CI.BAT: success for drm/atomic: add async plane update Patchwork
  6 siblings, 1 reply; 16+ messages in thread
From: Gustavo Padovan @ 2017-05-25 19:51 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, intel-gfx

From: Gustavo Padovan <gustavo.padovan@collabora.com>

Add support to async updates of cursors by using the new atomic
interface for that. Basically what this commit does is do what
vc4_update_plane() did but through atomic.

v3: move size checks back to drivers (Ville Syrjälä)

v2: move fb setting to core and use new state (Eric Anholt)

Cc: Eric Anholt <eric@anholt.net>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
Tested-by: Robert Foss <robert.foss@collabora.com>
---
 drivers/gpu/drm/vc4/vc4_plane.c | 99 +++++++++++++++--------------------------
 1 file changed, 35 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index d34cd53..05e9f5f 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -735,70 +735,38 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb)
 	vc4_state->dlist[vc4_state->ptr0_offset] = addr;
 }
 
-static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
-	.atomic_check = vc4_plane_atomic_check,
-	.atomic_update = vc4_plane_atomic_update,
-};
-
-static void vc4_plane_destroy(struct drm_plane *plane)
-{
-	drm_plane_helper_disable(plane);
-	drm_plane_cleanup(plane);
-}
-
-/* Implements immediate (non-vblank-synced) updates of the cursor
- * position, or falls back to the atomic helper otherwise.
- */
-static int
-vc4_update_plane(struct drm_plane *plane,
-		 struct drm_crtc *crtc,
-		 struct drm_framebuffer *fb,
-		 int crtc_x, int crtc_y,
-		 unsigned int crtc_w, unsigned int crtc_h,
-		 uint32_t src_x, uint32_t src_y,
-		 uint32_t src_w, uint32_t src_h,
-		 struct drm_modeset_acquire_ctx *ctx)
+static int vc4_plane_atomic_async_check(struct drm_plane *plane,
+					struct drm_plane_state *state)
 {
-	struct drm_plane_state *plane_state;
-	struct vc4_plane_state *vc4_state;
-
-	if (plane != crtc->cursor)
-		goto out;
-
-	plane_state = plane->state;
-	vc4_state = to_vc4_plane_state(plane_state);
+	if (plane != state->crtc->cursor)
+		return -EINVAL;
 
-	if (!plane_state)
-		goto out;
+	if (!plane->state)
+		return -EINVAL;
 
 	/* No configuring new scaling in the fast path. */
-	if (crtc_w != plane_state->crtc_w ||
-	    crtc_h != plane_state->crtc_h ||
-	    src_w != plane_state->src_w ||
-	    src_h != plane_state->src_h) {
-		goto out;
+	if (state->crtc_w != plane->state->crtc_w ||
+	    state->crtc_h != plane->state->crtc_h ||
+	    state->src_w != plane->state->src_w ||
+	    state->src_h != plane->state->src_h) {
+		return -EINVAL;
 	}
 
-	if (fb != plane_state->fb) {
-		drm_atomic_set_fb_for_plane(plane->state, fb);
-		vc4_plane_async_set_fb(plane, fb);
-	}
+	return 0;
+}
 
-	/* Set the cursor's position on the screen.  This is the
-	 * expected change from the drm_mode_cursor_universal()
-	 * helper.
-	 */
-	plane_state->crtc_x = crtc_x;
-	plane_state->crtc_y = crtc_y;
+static void vc4_plane_atomic_async_update(struct drm_plane *plane,
+					  struct drm_plane_state *new_state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
 
-	/* Allow changing the start position within the cursor BO, if
-	 * that matters.
-	 */
-	plane_state->src_x = src_x;
-	plane_state->src_y = src_y;
+	plane->state->src_x = new_state->src_x;
+	plane->state->src_y = new_state->src_y;
+	plane->state->crtc_x = new_state->crtc_x;
+	plane->state->crtc_y = new_state->crtc_y;
 
-	/* Update the display list based on the new crtc_x/y. */
-	vc4_plane_atomic_check(plane, plane_state);
+	if (plane->state->fb != new_state->fb)
+		vc4_plane_async_set_fb(plane, new_state->fb);
 
 	/* Note that we can't just call vc4_plane_write_dlist()
 	 * because that would smash the context data that the HVS is
@@ -810,20 +778,23 @@ vc4_update_plane(struct drm_plane *plane,
 	       &vc4_state->hw_dlist[vc4_state->pos2_offset]);
 	writel(vc4_state->dlist[vc4_state->ptr0_offset],
 	       &vc4_state->hw_dlist[vc4_state->ptr0_offset]);
+}
 
-	return 0;
+static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
+	.atomic_check = vc4_plane_atomic_check,
+	.atomic_update = vc4_plane_atomic_update,
+	.atomic_async_check = vc4_plane_atomic_async_check,
+	.atomic_async_update = vc4_plane_atomic_async_update,
+};
 
-out:
-	return drm_atomic_helper_update_plane(plane, crtc, fb,
-					      crtc_x, crtc_y,
-					      crtc_w, crtc_h,
-					      src_x, src_y,
-					      src_w, src_h,
-					      ctx);
+static void vc4_plane_destroy(struct drm_plane *plane)
+{
+	drm_plane_helper_disable(plane);
+	drm_plane_cleanup(plane);
 }
 
 static const struct drm_plane_funcs vc4_plane_funcs = {
-	.update_plane = vc4_update_plane,
+	.update_plane = drm_atomic_helper_update_plane,
 	.disable_plane = drm_atomic_helper_disable_plane,
 	.destroy = vc4_plane_destroy,
 	.set_property = NULL,
-- 
2.9.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* ✓ Fi.CI.BAT: success for drm/atomic: add async plane update
  2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
                   ` (5 preceding siblings ...)
  2017-05-25 19:51 ` [PATCH RESEND 6/6] drm/vc4: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-05-25 20:11 ` Patchwork
  6 siblings, 0 replies; 16+ messages in thread
From: Patchwork @ 2017-05-25 20:11 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: intel-gfx

== Series Details ==

Series: drm/atomic: add async plane update
URL   : https://patchwork.freedesktop.org/series/24926/
State : success

== Summary ==

Series 24926v1 drm/atomic: add async plane update
https://patchwork.freedesktop.org/api/1.0/series/24926/revisions/1/mbox/

Test kms_cursor_legacy:
        Subgroup basic-busy-flip-before-cursor-atomic:
                fail       -> PASS       (fi-snb-2600) fdo#100215

fdo#100215 https://bugs.freedesktop.org/show_bug.cgi?id=100215

fi-bdw-5557u     total:278  pass:267  dwarn:0   dfail:0   fail:0   skip:11  time:440s
fi-bdw-gvtdvm    total:278  pass:256  dwarn:8   dfail:0   fail:0   skip:14  time:438s
fi-bsw-n3050     total:278  pass:242  dwarn:0   dfail:0   fail:0   skip:36  time:569s
fi-bxt-j4205     total:278  pass:259  dwarn:0   dfail:0   fail:0   skip:19  time:511s
fi-byt-j1900     total:278  pass:254  dwarn:0   dfail:0   fail:0   skip:24  time:486s
fi-byt-n2820     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:482s
fi-hsw-4770      total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:413s
fi-hsw-4770r     total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:413s
fi-ilk-650       total:278  pass:228  dwarn:0   dfail:0   fail:0   skip:50  time:419s
fi-ivb-3520m     total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:492s
fi-ivb-3770      total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:465s
fi-kbl-7500u     total:278  pass:255  dwarn:5   dfail:0   fail:0   skip:18  time:461s
fi-kbl-7560u     total:278  pass:263  dwarn:5   dfail:0   fail:0   skip:10  time:570s
fi-skl-6260u     total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:462s
fi-skl-6700hq    total:278  pass:239  dwarn:0   dfail:1   fail:17  skip:21  time:435s
fi-skl-6700k     total:278  pass:256  dwarn:4   dfail:0   fail:0   skip:18  time:470s
fi-skl-6770hq    total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:495s
fi-skl-gvtdvm    total:278  pass:265  dwarn:0   dfail:0   fail:0   skip:13  time:438s
fi-snb-2520m     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:530s
fi-snb-2600      total:278  pass:248  dwarn:0   dfail:0   fail:1   skip:29  time:401s

028a0b3762b318a72ab04675355db97c854c230b drm-tip: 2017y-05m-25d-11h-47m-22s UTC integration manifest
299cc4d drm/atomic: initial support for asynchronous plane update

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_4811/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 4/6] drm/msm: update cursors asynchronously through atomic
  2017-05-25 19:51 ` [PATCH RESEND 4/6] drm/msm: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-05-26  8:44   ` Archit Taneja
  0 siblings, 0 replies; 16+ messages in thread
From: Archit Taneja @ 2017-05-26  8:44 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel; +Cc: Gustavo Padovan, intel-gfx



On 05/26/2017 01:21 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.com>
>
> Add support to async updates of cursors by using the new atomic
> interface for that. Basically what this commit does is do what
> mdp5_update_cursor_plane_legacy() did but through atomic.

Tested-by: Archit Taneja <architt@codeaurora.org>

>
> v4: add missing atomic async commit call to msm_atomic_commit(Archit Taneja)
>
> v3: move size checks back to drivers (Ville Syrjälä)
>
> v2: move fb setting to core and use new state (Eric Anholt)
>
> Cc: Rob Clark <robdclark@gmail.com>
> Cc: Archit Taneja <architt@codeaurora.org>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
> ---
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 151 +++++++++++++-----------------
>  drivers/gpu/drm/msm/msm_atomic.c          |   6 ++
>  2 files changed, 69 insertions(+), 88 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
> index a38c5fe..07106c1 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
> @@ -33,15 +33,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
>  		struct drm_crtc *crtc, struct drm_framebuffer *fb,
>  		struct drm_rect *src, struct drm_rect *dest);
>
> -static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane,
> -		struct drm_crtc *crtc,
> -		struct drm_framebuffer *fb,
> -		int crtc_x, int crtc_y,
> -		unsigned int crtc_w, unsigned int crtc_h,
> -		uint32_t src_x, uint32_t src_y,
> -		uint32_t src_w, uint32_t src_h,
> -		struct drm_modeset_acquire_ctx *ctx);
> -
>  static struct mdp5_kms *get_kms(struct drm_plane *plane)
>  {
>  	struct msm_drm_private *priv = plane->dev->dev_private;
> @@ -257,7 +248,7 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
>  };
>
>  static const struct drm_plane_funcs mdp5_cursor_plane_funcs = {
> -		.update_plane = mdp5_update_cursor_plane_legacy,
> +		.update_plane = drm_atomic_helper_update_plane,
>  		.disable_plane = drm_atomic_helper_disable_plane,
>  		.destroy = mdp5_plane_destroy,
>  		.set_property = drm_atomic_helper_plane_set_property,
> @@ -484,11 +475,73 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane,
>  	}
>  }
>
> +static int mdp5_plane_atomic_async_check(struct drm_plane *plane,
> +					 struct drm_plane_state *state)
> +{
> +	struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state);
> +	struct drm_crtc_state *crtc_state;
> +
> +	crtc_state = drm_atomic_get_existing_crtc_state(state->state,
> +							state->crtc);
> +	if (WARN_ON(!crtc_state))
> +		return -EINVAL;
> +
> +	if (!crtc_state->active)
> +		return -EINVAL;
> +
> +	mdp5_state = to_mdp5_plane_state(state);
> +
> +	/* don't use fast path if we don't have a hwpipe allocated yet */
> +	if (!mdp5_state->hwpipe)
> +		return -EINVAL;
> +
> +	/* only allow changing of position(crtc x/y or src x/y) in fast path */
> +	if (plane->state->crtc != state->crtc ||
> +	    plane->state->src_w != state->src_w ||
> +	    plane->state->src_h != state->src_h ||
> +	    plane->state->crtc_w != state->crtc_w ||
> +	    plane->state->crtc_h != state->crtc_h ||
> +	    !plane->state->fb ||
> +	    plane->state->fb != state->fb)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static void mdp5_plane_atomic_async_update(struct drm_plane *plane,
> +					   struct drm_plane_state *new_state)
> +{
> +	plane->state->src_x = new_state->src_x;
> +	plane->state->src_y = new_state->src_y;
> +	plane->state->crtc_x = new_state->crtc_x;
> +	plane->state->crtc_y = new_state->crtc_y;
> +
> +	if (plane_enabled(new_state)) {
> +		struct mdp5_ctl *ctl;
> +		struct mdp5_pipeline *pipeline =
> +					mdp5_crtc_get_pipeline(plane->crtc);
> +		int ret;
> +
> +		ret = mdp5_plane_mode_set(plane, new_state->crtc, new_state->fb,
> +				&new_state->src, &new_state->dst);
> +		WARN_ON(ret < 0);
> +
> +		ctl = mdp5_crtc_get_ctl(new_state->crtc);
> +
> +		mdp5_ctl_commit(ctl, pipeline, mdp5_plane_get_flush(plane));
> +	}
> +
> +	*to_mdp5_plane_state(plane->state) =
> +		*to_mdp5_plane_state(new_state);
> +}
> +
>  static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = {
>  		.prepare_fb = mdp5_plane_prepare_fb,
>  		.cleanup_fb = mdp5_plane_cleanup_fb,
>  		.atomic_check = mdp5_plane_atomic_check,
>  		.atomic_update = mdp5_plane_atomic_update,
> +		.atomic_async_check = mdp5_plane_atomic_async_check,
> +		.atomic_async_update = mdp5_plane_atomic_async_update,
>  };
>
>  static void set_scanout_locked(struct mdp5_kms *mdp5_kms,
> @@ -997,84 +1050,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
>  	return ret;
>  }
>
> -static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane,
> -			struct drm_crtc *crtc, struct drm_framebuffer *fb,
> -			int crtc_x, int crtc_y,
> -			unsigned int crtc_w, unsigned int crtc_h,
> -			uint32_t src_x, uint32_t src_y,
> -			uint32_t src_w, uint32_t src_h,
> -			struct drm_modeset_acquire_ctx *ctx)
> -{
> -	struct drm_plane_state *plane_state, *new_plane_state;
> -	struct mdp5_plane_state *mdp5_pstate;
> -	struct drm_crtc_state *crtc_state = crtc->state;
> -	int ret;
> -
> -	if (!crtc_state->active || drm_atomic_crtc_needs_modeset(crtc_state))
> -		goto slow;
> -
> -	plane_state = plane->state;
> -	mdp5_pstate = to_mdp5_plane_state(plane_state);
> -
> -	/* don't use fast path if we don't have a hwpipe allocated yet */
> -	if (!mdp5_pstate->hwpipe)
> -		goto slow;
> -
> -	/* only allow changing of position(crtc x/y or src x/y) in fast path */
> -	if (plane_state->crtc != crtc ||
> -	    plane_state->src_w != src_w ||
> -	    plane_state->src_h != src_h ||
> -	    plane_state->crtc_w != crtc_w ||
> -	    plane_state->crtc_h != crtc_h ||
> -	    !plane_state->fb ||
> -	    plane_state->fb != fb)
> -		goto slow;
> -
> -	new_plane_state = mdp5_plane_duplicate_state(plane);
> -	if (!new_plane_state)
> -		return -ENOMEM;
> -
> -	new_plane_state->src_x = src_x;
> -	new_plane_state->src_y = src_y;
> -	new_plane_state->src_w = src_w;
> -	new_plane_state->src_h = src_h;
> -	new_plane_state->crtc_x = crtc_x;
> -	new_plane_state->crtc_y = crtc_y;
> -	new_plane_state->crtc_w = crtc_w;
> -	new_plane_state->crtc_h = crtc_h;
> -
> -	ret = mdp5_plane_atomic_check_with_state(crtc_state, new_plane_state);
> -	if (ret)
> -		goto slow_free;
> -
> -	if (new_plane_state->visible) {
> -		struct mdp5_ctl *ctl;
> -		struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(crtc);
> -
> -		ret = mdp5_plane_mode_set(plane, crtc, fb,
> -					  &new_plane_state->src,
> -					  &new_plane_state->dst);
> -		WARN_ON(ret < 0);
> -
> -		ctl = mdp5_crtc_get_ctl(crtc);
> -
> -		mdp5_ctl_commit(ctl, pipeline, mdp5_plane_get_flush(plane));
> -	}
> -
> -	*to_mdp5_plane_state(plane_state) =
> -		*to_mdp5_plane_state(new_plane_state);
> -
> -	mdp5_plane_destroy_state(plane, new_plane_state);
> -
> -	return 0;
> -slow_free:
> -	mdp5_plane_destroy_state(plane, new_plane_state);
> -slow:
> -	return drm_atomic_helper_update_plane(plane, crtc, fb,
> -					      crtc_x, crtc_y, crtc_w, crtc_h,
> -					      src_x, src_y, src_w, src_h, ctx);
> -}
> -
>  /*
>   * Use this func and the one below only after the atomic state has been
>   * successfully swapped
> diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
> index 9633a68b..0104311 100644
> --- a/drivers/gpu/drm/msm/msm_atomic.c
> +++ b/drivers/gpu/drm/msm/msm_atomic.c
> @@ -202,6 +202,12 @@ int msm_atomic_commit(struct drm_device *dev,
>  	if (ret)
>  		return ret;
>
> +	if (state->async_update) {
> +		drm_atomic_helper_async_commit(dev, state);
> +		drm_atomic_helper_cleanup_planes(dev, state);
> +		return 0;
> +	}
> +
>  	c = commit_init(state);
>  	if (!c) {
>  		ret = -ENOMEM;
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 5/6] drm/msm: remove mdp5_cursor_plane_funcs
  2017-05-25 19:51 ` [PATCH RESEND 5/6] drm/msm: remove mdp5_cursor_plane_funcs Gustavo Padovan
@ 2017-05-26  8:44   ` Archit Taneja
  0 siblings, 0 replies; 16+ messages in thread
From: Archit Taneja @ 2017-05-26  8:44 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel; +Cc: Gustavo Padovan, intel-gfx



On 05/26/2017 01:21 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.com>
>
> After converting legacy cursor updates to atomic async commits
> mdp5_cursor_plane_funcs just duplicates mdp5_plane_funcs now.
>

Tested-by: Archit Taneja <architt@codeaurora.org>

> Cc: Rob Clark <robdclark@gmail.com>
> Cc: Archit Taneja <architt@codeaurora.org>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
> ---
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 26 +++-----------------------
>  1 file changed, 3 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
> index 07106c1..794ca07 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
> @@ -247,19 +247,6 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
>  		.atomic_print_state = mdp5_plane_atomic_print_state,
>  };
>
> -static const struct drm_plane_funcs mdp5_cursor_plane_funcs = {
> -		.update_plane = drm_atomic_helper_update_plane,
> -		.disable_plane = drm_atomic_helper_disable_plane,
> -		.destroy = mdp5_plane_destroy,
> -		.set_property = drm_atomic_helper_plane_set_property,
> -		.atomic_set_property = mdp5_plane_atomic_set_property,
> -		.atomic_get_property = mdp5_plane_atomic_get_property,
> -		.reset = mdp5_plane_reset,
> -		.atomic_duplicate_state = mdp5_plane_duplicate_state,
> -		.atomic_destroy_state = mdp5_plane_destroy_state,
> -		.atomic_print_state = mdp5_plane_atomic_print_state,
> -};
> -
>  static int mdp5_plane_prepare_fb(struct drm_plane *plane,
>  				 struct drm_plane_state *new_state)
>  {
> @@ -1111,16 +1098,9 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
>
>  	spin_lock_init(&mdp5_plane->pipe_lock);
>
> -	if (type == DRM_PLANE_TYPE_CURSOR)
> -		ret = drm_universal_plane_init(dev, plane, 0xff,
> -				&mdp5_cursor_plane_funcs,
> -				mdp5_plane->formats, mdp5_plane->nformats,
> -				type, NULL);
> -	else
> -		ret = drm_universal_plane_init(dev, plane, 0xff,
> -				&mdp5_plane_funcs,
> -				mdp5_plane->formats, mdp5_plane->nformats,
> -				type, NULL);
> +	ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
> +				       mdp5_plane->formats,
> +				       mdp5_plane->nformats, type, NULL);
>  	if (ret)
>  		goto fail;
>
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous plane update
  2017-05-25 19:51 ` [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous " Gustavo Padovan
@ 2017-05-26  8:45   ` Archit Taneja
  2017-06-01  0:47   ` Eric Anholt
  1 sibling, 0 replies; 16+ messages in thread
From: Archit Taneja @ 2017-05-26  8:45 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel; +Cc: Gustavo Padovan, intel-gfx, Daniel Vetter



On 05/26/2017 01:21 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.com>
>
> In some cases, like cursor updates, it is interesting to update the
> plane in an asynchronous fashion to avoid big delays. The current queued
> update could be still waiting for a fence to signal and thus block any
> subsequent update until its scan out. In cases like this if we update the
> cursor synchronously through the atomic API it will cause significant
> delays that would even be noticed by the final user.
>
> This patch creates a fast path to jump ahead the current queued state and
> do single planes updates without going through all atomic steps in
> drm_atomic_helper_commit(). We take this path for legacy cursor updates.
>
> For now only single plane updates are supported, but we plan to support
> multiple planes updates and async PageFlips through this interface as well
> in the near future.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
>
> v4:
> 	- fix state->crtc NULL check (Archit Taneja)
>
> v3:
> 	- fix iteration on the wrong crtc state
> 	- put back code to forbid updates if there is a queued update for
> 	the same plane (Ville Syrjälä)
> 	- move size checks back to drivers (Ville Syrjälä)
> 	- move ASYNC_UPDATE flag addition to its own patch (Ville Syrjälä)
>
> v2:
> 	- allow updates even if there is a queued update for the same
> 	plane.
>         - fixes on the documentation (Emil Velikov)
>         - unconditionally call ->atomic_async_update (Emil Velikov)
>         - check for ->atomic_async_update earlier (Daniel Vetter)
>         - make ->atomic_async_check() the last step (Daniel Vetter)
>         - add ASYNC_UPDATE flag (Eric Anholt)
>         - update state in core after ->atomic_async_update (Eric Anholt)
> 	- update docs (Eric Anholt)
>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Rob Clark <robdclark@gmail.com>
> Cc: Eric Anholt <eric@anholt.net>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
> ---
>  drivers/gpu/drm/drm_atomic.c             | 65 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_atomic_helper.c      | 35 +++++++++++++++++
>  include/drm/drm_atomic.h                 |  2 +
>  include/drm/drm_atomic_helper.h          |  2 +
>  include/drm/drm_modeset_helper_vtables.h | 48 +++++++++++++++++++++++
>  5 files changed, 152 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index be62774..2a0c297 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -631,6 +631,68 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
>  	return 0;
>  }
>
> +static bool drm_atomic_async_check(struct drm_atomic_state *state)
> +{
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_crtc_commit *commit;
> +	struct drm_plane *__plane, *plane = NULL;
> +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> +	const struct drm_plane_helper_funcs *funcs;
> +	int i, j, n_planes = 0;
> +
> +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> +		if (drm_atomic_crtc_needs_modeset(crtc_state))
> +			return false;
> +	}
> +
> +	for_each_new_plane_in_state(state, __plane, __plane_state, i) {
> +		n_planes++;
> +		plane = __plane;
> +		plane_state = __plane_state;
> +	}
> +
> +	/* FIXME: we support only single plane updates for now */
> +	if (!plane || n_planes != 1)
> +		return false;
> +
> +	if (!plane_state->crtc)
> +		return false;
> +
> +	funcs = plane->helper_private;
> +	if (!funcs->atomic_async_update)
> +		return false;
> +
> +	if (plane_state->fence)
> +		return false;
> +
> +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> +		if (plane->crtc != crtc)
> +			continue;
> +
> +		spin_lock(&crtc->commit_lock);
> +		commit = list_first_entry_or_null(&crtc->commit_list,
> +						  struct drm_crtc_commit,
> +						  commit_entry);
> +		if (!commit) {
> +			spin_unlock(&crtc->commit_lock);
> +			continue;
> +		}
> +		spin_unlock(&crtc->commit_lock);
> +
> +		if (!crtc->state->state)
> +			continue;
> +
> +		for_each_plane_in_state(crtc->state->state, __plane,
> +					__plane_state, j) {
> +			if (__plane == plane)
> +				return false;
> +		}
> +	}
> +
> +	return !funcs->atomic_async_check(plane, plane_state);
> +}
> +
>  static void drm_atomic_crtc_print_state(struct drm_printer *p,
>  		const struct drm_crtc_state *state)
>  {
> @@ -1591,6 +1653,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
>  		}
>  	}
>
> +	if (state->legacy_cursor_update)
> +		state->async_update = drm_atomic_async_check(state);
> +
>  	return ret;
>  }
>  EXPORT_SYMBOL(drm_atomic_check_only);
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 5a3c9c0..a8efdfe 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -1235,6 +1235,30 @@ static void commit_work(struct work_struct *work)
>  }
>
>  /**
> + * drm_atomic_helper_async_commit - commit state asynchronously
> + *
> + * This function commits a state asynchronously, i.e., not vblank
> + * synchronized. It should be used on a state only when
> + * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
> + * the states like normal sync commits, but just do in-place changes on the
> + * current state.
> + */
> +void drm_atomic_helper_async_commit(struct drm_device *dev,
> +				    struct drm_atomic_state *state)
> +{
> +	struct drm_plane *plane;
> +	struct drm_plane_state *plane_state;
> +	const struct drm_plane_helper_funcs *funcs;
> +	int i;
> +
> +	for_each_new_plane_in_state(state, plane, plane_state, i) {
> +		funcs = plane->helper_private;
> +		funcs->atomic_async_update(plane, plane_state);
> +	}
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_async_commit);
> +
> +/**
>   * drm_atomic_helper_commit - commit validated state object
>   * @dev: DRM device
>   * @state: the driver state object
> @@ -1258,6 +1282,17 @@ int drm_atomic_helper_commit(struct drm_device *dev,
>  {
>  	int ret;
>
> +	if (state->async_update) {
> +		ret = drm_atomic_helper_prepare_planes(dev, state);
> +		if (ret)
> +			return ret;
> +
> +		drm_atomic_helper_async_commit(dev, state);
> +		drm_atomic_helper_cleanup_planes(dev, state);
> +
> +		return 0;
> +	}
> +
>  	ret = drm_atomic_helper_setup_commit(state, nonblock);
>  	if (ret)
>  		return ret;
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 788daf7..70ca279 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -160,6 +160,7 @@ struct __drm_connnectors_state {
>   * @dev: parent DRM device
>   * @allow_modeset: allow full modeset
>   * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
> + * @async_update: hint for asynchronous plane update
>   * @planes: pointer to array of structures with per-plane data
>   * @crtcs: pointer to array of CRTC pointers
>   * @num_connector: size of the @connectors and @connector_states arrays
> @@ -172,6 +173,7 @@ struct drm_atomic_state {
>  	struct drm_device *dev;
>  	bool allow_modeset : 1;
>  	bool legacy_cursor_update : 1;
> +	bool async_update : 1;
>  	struct __drm_planes_state *planes;
>  	struct __drm_crtcs_state *crtcs;
>  	int num_connector;
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index f0a8678..8571b51 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -44,6 +44,8 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
>  int drm_atomic_helper_commit(struct drm_device *dev,
>  			     struct drm_atomic_state *state,
>  			     bool nonblock);
> +void drm_atomic_helper_async_commit(struct drm_device *dev,
> +				    struct drm_atomic_state *state);
>
>  int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
>  					struct drm_atomic_state *state,
> diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> index c01c328..7964a78 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -1048,6 +1048,54 @@ struct drm_plane_helper_funcs {
>  	 */
>  	void (*atomic_disable)(struct drm_plane *plane,
>  			       struct drm_plane_state *old_state);
> +
> +	/**
> +	 * @atomic_async_check:
> +	 *
> +	 * Drivers should set this function pointer to check if the plane state
> +	 * can be updated in a async fashion. Here async means "not vblank
> +	 * synchronized".
> +	 *
> +	 * This hook is called by drm_atomic_async_check() to establish if a
> +	 * given update can be committed asynchronously, that is, if it can
> +	 * jump ahead the state currently queued for update.
> +	 *
> +	 * RETURNS:
> +	 *
> +	 * Return 0 on success and any error returned indicates that the update
> +	 * can not be applied in asynchronous manner.
> +	 */
> +	int (*atomic_async_check)(struct drm_plane *plane,
> +				  struct drm_plane_state *state);
> +
> +	/**
> +	 * @atomic_async_update:
> +	 *
> +	 * Drivers should set this function pointer to perform asynchronous
> +	 * updates of planes, that is, jump ahead the currently queued
> +	 * state for and update the plane. Here async means "not vblank
> +	 * synchronized".
> +	 *
> +	 * This hook is called by drm_atomic_helper_async_commit().
> +	 *
> +	 * An async update will happen on legacy cursor updates.
> +	 *
> +	 * Note that unlike &drm_plane_helper_funcs.atomic_update this hook
> +	 * takes the new &drm_plane_state as parameter. When doing async_update
> +	 * drivers shouldn't replace the &drm_plane_state but update the
> +	 * current one with the new plane configurations in the new
> +	 * plane_state.
> +	 *
> +	 * FIXME:
> +	 *  - It only works for single plane updates
> +	 *  - Async Pageflips are not supported yet
> +	 *  - Some hm might still scan out the old buffer until the next
> +	 *  vblank, however we let go of the fb references as soon as
> +	 *  we run this hook. For now drivers must implement their own workers
> +	 *  for defering if needed, until a common solution is created.
> +	 */
> +	void (*atomic_async_update)(struct drm_plane *plane,
> +				    struct drm_plane_state *new_state);
>  };
>
>  /**
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 6/6] drm/vc4: update cursors asynchronously through atomic
  2017-05-25 19:51 ` [PATCH RESEND 6/6] drm/vc4: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-06-01  0:43   ` Eric Anholt
  2017-06-01  2:07     ` Gustavo Padovan
  0 siblings, 1 reply; 16+ messages in thread
From: Eric Anholt @ 2017-06-01  0:43 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel; +Cc: Gustavo Padovan, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 559 bytes --]

Gustavo Padovan <gustavo@padovan.org> writes:

> From: Gustavo Padovan <gustavo.padovan@collabora.com>
>
> Add support to async updates of cursors by using the new atomic

"Add support for"

> interface for that. Basically what this commit does is do what
> vc4_update_plane() did but through atomic.
>
> v3: move size checks back to drivers (Ville Syrjälä)
>
> v2: move fb setting to core and use new state (Eric Anholt)

Given that vc4 isn't using drm_atomic_helper_commit(), isn't this
effectively disabling async cursor updates on vc4?

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous plane update
  2017-05-25 19:51 ` [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous " Gustavo Padovan
  2017-05-26  8:45   ` Archit Taneja
@ 2017-06-01  0:47   ` Eric Anholt
  2017-06-01  2:24     ` Gustavo Padovan
  1 sibling, 1 reply; 16+ messages in thread
From: Eric Anholt @ 2017-06-01  0:47 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel; +Cc: Gustavo Padovan, intel-gfx, Daniel Vetter


[-- Attachment #1.1: Type: text/plain, Size: 10515 bytes --]

Gustavo Padovan <gustavo@padovan.org> writes:

> From: Gustavo Padovan <gustavo.padovan@collabora.com>
>
> In some cases, like cursor updates, it is interesting to update the
> plane in an asynchronous fashion to avoid big delays. The current queued
> update could be still waiting for a fence to signal and thus block any
> subsequent update until its scan out. In cases like this if we update the
> cursor synchronously through the atomic API it will cause significant
> delays that would even be noticed by the final user.
>
> This patch creates a fast path to jump ahead the current queued state and
> do single planes updates without going through all atomic steps in
> drm_atomic_helper_commit(). We take this path for legacy cursor updates.
>
> For now only single plane updates are supported, but we plan to support
> multiple planes updates and async PageFlips through this interface as well
> in the near future.

Sorry for taking so long to do some review for this.

> ---
>  drivers/gpu/drm/drm_atomic.c             | 65 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_atomic_helper.c      | 35 +++++++++++++++++
>  include/drm/drm_atomic.h                 |  2 +
>  include/drm/drm_atomic_helper.h          |  2 +
>  include/drm/drm_modeset_helper_vtables.h | 48 +++++++++++++++++++++++
>  5 files changed, 152 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index be62774..2a0c297 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -631,6 +631,68 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
>  	return 0;
>  }
>  
> +static bool drm_atomic_async_check(struct drm_atomic_state *state)
> +{
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_crtc_commit *commit;
> +	struct drm_plane *__plane, *plane = NULL;
> +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> +	const struct drm_plane_helper_funcs *funcs;
> +	int i, j, n_planes = 0;
> +
> +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> +		if (drm_atomic_crtc_needs_modeset(crtc_state))
> +			return false;
> +	}
> +
> +	for_each_new_plane_in_state(state, __plane, __plane_state, i) {
> +		n_planes++;
> +		plane = __plane;
> +		plane_state = __plane_state;
> +	}
> +
> +	/* FIXME: we support only single plane updates for now */
> +	if (!plane || n_planes != 1)
> +		return false;
> +
> +	if (!plane_state->crtc)
> +		return false;
> +
> +	funcs = plane->helper_private;
> +	if (!funcs->atomic_async_update)
> +		return false;
> +
> +	if (plane_state->fence)
> +		return false;
> +

Could you add a comment here like:

/* Don't do an async update if there is an outstanding commit modifying
 * the plane.  This prevents our async update's changes from getting
 * overridden by a previous synchronous update's state.
 */

(assuming I understand its intent correctly)

I don't understand KMS locking enough to say if this loop is actually
safely guaranteeing that.  If you're convinced of that, then with my
little cleanups this patch will be:

Acked-by: Eric Anholt <eric@anholt.net>

> +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> +		if (plane->crtc != crtc)
> +			continue;
> +
> +		spin_lock(&crtc->commit_lock);
> +		commit = list_first_entry_or_null(&crtc->commit_list,
> +						  struct drm_crtc_commit,
> +						  commit_entry);
> +		if (!commit) {
> +			spin_unlock(&crtc->commit_lock);
> +			continue;
> +		}
> +		spin_unlock(&crtc->commit_lock);
> +
> +		if (!crtc->state->state)
> +			continue;
> +
> +		for_each_plane_in_state(crtc->state->state, __plane,
> +					__plane_state, j) {
> +			if (__plane == plane)
> +				return false;
> +		}
> +	}
> +
> +	return !funcs->atomic_async_check(plane, plane_state);
> +}
> +
>  static void drm_atomic_crtc_print_state(struct drm_printer *p,
>  		const struct drm_crtc_state *state)
>  {
> @@ -1591,6 +1653,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
>  		}
>  	}
>  
> +	if (state->legacy_cursor_update)
> +		state->async_update = drm_atomic_async_check(state);
> +
>  	return ret;
>  }
>  EXPORT_SYMBOL(drm_atomic_check_only);
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 5a3c9c0..a8efdfe 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -1235,6 +1235,30 @@ static void commit_work(struct work_struct *work)
>  }
>  
>  /**
> + * drm_atomic_helper_async_commit - commit state asynchronously
> + *
> + * This function commits a state asynchronously, i.e., not vblank
> + * synchronized. It should be used on a state only when
> + * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
> + * the states like normal sync commits, but just do in-place changes on the
> + * current state.
> + */
> +void drm_atomic_helper_async_commit(struct drm_device *dev,
> +				    struct drm_atomic_state *state)
> +{
> +	struct drm_plane *plane;
> +	struct drm_plane_state *plane_state;
> +	const struct drm_plane_helper_funcs *funcs;
> +	int i;
> +
> +	for_each_new_plane_in_state(state, plane, plane_state, i) {
> +		funcs = plane->helper_private;
> +		funcs->atomic_async_update(plane, plane_state);
> +	}
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_async_commit);
> +
> +/**
>   * drm_atomic_helper_commit - commit validated state object
>   * @dev: DRM device
>   * @state: the driver state object
> @@ -1258,6 +1282,17 @@ int drm_atomic_helper_commit(struct drm_device *dev,
>  {
>  	int ret;
>  
> +	if (state->async_update) {
> +		ret = drm_atomic_helper_prepare_planes(dev, state);
> +		if (ret)
> +			return ret;
> +
> +		drm_atomic_helper_async_commit(dev, state);
> +		drm_atomic_helper_cleanup_planes(dev, state);
> +
> +		return 0;
> +	}
> +
>  	ret = drm_atomic_helper_setup_commit(state, nonblock);
>  	if (ret)
>  		return ret;
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 788daf7..70ca279 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -160,6 +160,7 @@ struct __drm_connnectors_state {
>   * @dev: parent DRM device
>   * @allow_modeset: allow full modeset
>   * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
> + * @async_update: hint for asynchronous plane update
>   * @planes: pointer to array of structures with per-plane data
>   * @crtcs: pointer to array of CRTC pointers
>   * @num_connector: size of the @connectors and @connector_states arrays
> @@ -172,6 +173,7 @@ struct drm_atomic_state {
>  	struct drm_device *dev;
>  	bool allow_modeset : 1;
>  	bool legacy_cursor_update : 1;
> +	bool async_update : 1;
>  	struct __drm_planes_state *planes;
>  	struct __drm_crtcs_state *crtcs;
>  	int num_connector;
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index f0a8678..8571b51 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -44,6 +44,8 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
>  int drm_atomic_helper_commit(struct drm_device *dev,
>  			     struct drm_atomic_state *state,
>  			     bool nonblock);
> +void drm_atomic_helper_async_commit(struct drm_device *dev,
> +				    struct drm_atomic_state *state);
>  
>  int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
>  					struct drm_atomic_state *state,
> diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> index c01c328..7964a78 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -1048,6 +1048,54 @@ struct drm_plane_helper_funcs {
>  	 */
>  	void (*atomic_disable)(struct drm_plane *plane,
>  			       struct drm_plane_state *old_state);
> +
> +	/**
> +	 * @atomic_async_check:
> +	 *
> +	 * Drivers should set this function pointer to check if the plane state
> +	 * can be updated in a async fashion. Here async means "not vblank
> +	 * synchronized".
> +	 *
> +	 * This hook is called by drm_atomic_async_check() to establish if a
> +	 * given update can be committed asynchronously, that is, if it can
> +	 * jump ahead the state currently queued for update.
> +	 *
> +	 * RETURNS:
> +	 *
> +	 * Return 0 on success and any error returned indicates that the update
> +	 * can not be applied in asynchronous manner.
> +	 */
> +	int (*atomic_async_check)(struct drm_plane *plane,
> +				  struct drm_plane_state *state);
> +
> +	/**
> +	 * @atomic_async_update:
> +	 *
> +	 * Drivers should set this function pointer to perform asynchronous
> +	 * updates of planes, that is, jump ahead the currently queued

"jump ahead of the"

> +	 * state for and update the plane. Here async means "not vblank

s/for //

> +	 * synchronized".
> +	 *
> +	 * This hook is called by drm_atomic_helper_async_commit().
> +	 *
> +	 * An async update will happen on legacy cursor updates.
> +	 *
> +	 * Note that unlike &drm_plane_helper_funcs.atomic_update this hook
> +	 * takes the new &drm_plane_state as parameter. When doing async_update
> +	 * drivers shouldn't replace the &drm_plane_state but update the
> +	 * current one with the new plane configurations in the new
> +	 * plane_state.

Also maybe document that this won't be called if there is an outstanding
commit modifying the plane?

> +	 *
> +	 * FIXME:
> +	 *  - It only works for single plane updates
> +	 *  - Async Pageflips are not supported yet
> +	 *  - Some hm might still scan out the old buffer until the next

"Some hw"?

> +	 *  vblank, however we let go of the fb references as soon as
> +	 *  we run this hook. For now drivers must implement their own workers
> +	 *  for defering if needed, until a common solution is created.
> +	 */

"deferring"

> +	void (*atomic_async_update)(struct drm_plane *plane,
> +				    struct drm_plane_state *new_state);

Is there a simple list of what parts of drm_plane_state may change in
this hook?  I noticed that vc4 wasn't checking that the format doesn't
change, for example.  I'm also not sure if we're guaranteed that the
plane-is-enabled state isn't changing, either.

If it's "everything", we'll need to improve the vc4 async check before
we expose this under anything but the cursor ioctl.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 6/6] drm/vc4: update cursors asynchronously through atomic
  2017-06-01  0:43   ` Eric Anholt
@ 2017-06-01  2:07     ` Gustavo Padovan
  0 siblings, 0 replies; 16+ messages in thread
From: Gustavo Padovan @ 2017-06-01  2:07 UTC (permalink / raw)
  To: Eric Anholt; +Cc: Gustavo Padovan, intel-gfx, dri-devel

2017-05-31 Eric Anholt <eric@anholt.net>:

> Gustavo Padovan <gustavo@padovan.org> writes:
> 
> > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> >
> > Add support to async updates of cursors by using the new atomic
> 
> "Add support for"
> 
> > interface for that. Basically what this commit does is do what
> > vc4_update_plane() did but through atomic.
> >
> > v3: move size checks back to drivers (Ville Syrjälä)
> >
> > v2: move fb setting to core and use new state (Eric Anholt)
> 
> Given that vc4 isn't using drm_atomic_helper_commit(), isn't this
> effectively disabling async cursor updates on vc4?

Right, yes. I didn't have a chance to run this in at the hw as I don't
have it right now. I'll update the patch and resend.

Gustavo


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous plane update
  2017-06-01  0:47   ` Eric Anholt
@ 2017-06-01  2:24     ` Gustavo Padovan
  2017-06-12  2:28       ` Gustavo Padovan
  0 siblings, 1 reply; 16+ messages in thread
From: Gustavo Padovan @ 2017-06-01  2:24 UTC (permalink / raw)
  To: Eric Anholt; +Cc: Gustavo Padovan, intel-gfx, dri-devel, Daniel Vetter

2017-05-31 Eric Anholt <eric@anholt.net>:

> Gustavo Padovan <gustavo@padovan.org> writes:
> 
> > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> >
> > In some cases, like cursor updates, it is interesting to update the
> > plane in an asynchronous fashion to avoid big delays. The current queued
> > update could be still waiting for a fence to signal and thus block any
> > subsequent update until its scan out. In cases like this if we update the
> > cursor synchronously through the atomic API it will cause significant
> > delays that would even be noticed by the final user.
> >
> > This patch creates a fast path to jump ahead the current queued state and
> > do single planes updates without going through all atomic steps in
> > drm_atomic_helper_commit(). We take this path for legacy cursor updates.
> >
> > For now only single plane updates are supported, but we plan to support
> > multiple planes updates and async PageFlips through this interface as well
> > in the near future.
> 
> Sorry for taking so long to do some review for this.
> 
> > ---
> >  drivers/gpu/drm/drm_atomic.c             | 65 ++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/drm_atomic_helper.c      | 35 +++++++++++++++++
> >  include/drm/drm_atomic.h                 |  2 +
> >  include/drm/drm_atomic_helper.h          |  2 +
> >  include/drm/drm_modeset_helper_vtables.h | 48 +++++++++++++++++++++++
> >  5 files changed, 152 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index be62774..2a0c297 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -631,6 +631,68 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
> >  	return 0;
> >  }
> >  
> > +static bool drm_atomic_async_check(struct drm_atomic_state *state)
> > +{
> > +	struct drm_crtc *crtc;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_crtc_commit *commit;
> > +	struct drm_plane *__plane, *plane = NULL;
> > +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> > +	const struct drm_plane_helper_funcs *funcs;
> > +	int i, j, n_planes = 0;
> > +
> > +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> > +		if (drm_atomic_crtc_needs_modeset(crtc_state))
> > +			return false;
> > +	}
> > +
> > +	for_each_new_plane_in_state(state, __plane, __plane_state, i) {
> > +		n_planes++;
> > +		plane = __plane;
> > +		plane_state = __plane_state;
> > +	}
> > +
> > +	/* FIXME: we support only single plane updates for now */
> > +	if (!plane || n_planes != 1)
> > +		return false;
> > +
> > +	if (!plane_state->crtc)
> > +		return false;
> > +
> > +	funcs = plane->helper_private;
> > +	if (!funcs->atomic_async_update)
> > +		return false;
> > +
> > +	if (plane_state->fence)
> > +		return false;
> > +
> 
> Could you add a comment here like:
> 
> /* Don't do an async update if there is an outstanding commit modifying
>  * the plane.  This prevents our async update's changes from getting
>  * overridden by a previous synchronous update's state.
>  */
> 
> (assuming I understand its intent correctly)
> 
> I don't understand KMS locking enough to say if this loop is actually
> safely guaranteeing that.  If you're convinced of that, then with my
> little cleanups this patch will be:

I'm going to check the locking again just to make sure.

> 
> Acked-by: Eric Anholt <eric@anholt.net>
> 
> > +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> > +		if (plane->crtc != crtc)
> > +			continue;
> > +
> > +		spin_lock(&crtc->commit_lock);
> > +		commit = list_first_entry_or_null(&crtc->commit_list,
> > +						  struct drm_crtc_commit,
> > +						  commit_entry);
> > +		if (!commit) {
> > +			spin_unlock(&crtc->commit_lock);
> > +			continue;
> > +		}
> > +		spin_unlock(&crtc->commit_lock);
> > +
> > +		if (!crtc->state->state)
> > +			continue;
> > +
> > +		for_each_plane_in_state(crtc->state->state, __plane,
> > +					__plane_state, j) {
> > +			if (__plane == plane)
> > +				return false;
> > +		}
> > +	}
> > +
> > +	return !funcs->atomic_async_check(plane, plane_state);
> > +}
> > +
> >  static void drm_atomic_crtc_print_state(struct drm_printer *p,
> >  		const struct drm_crtc_state *state)
> >  {
> > @@ -1591,6 +1653,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
> >  		}
> >  	}
> >  
> > +	if (state->legacy_cursor_update)
> > +		state->async_update = drm_atomic_async_check(state);
> > +
> >  	return ret;
> >  }
> >  EXPORT_SYMBOL(drm_atomic_check_only);
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > index 5a3c9c0..a8efdfe 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -1235,6 +1235,30 @@ static void commit_work(struct work_struct *work)
> >  }
> >  
> >  /**
> > + * drm_atomic_helper_async_commit - commit state asynchronously
> > + *
> > + * This function commits a state asynchronously, i.e., not vblank
> > + * synchronized. It should be used on a state only when
> > + * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
> > + * the states like normal sync commits, but just do in-place changes on the
> > + * current state.
> > + */
> > +void drm_atomic_helper_async_commit(struct drm_device *dev,
> > +				    struct drm_atomic_state *state)
> > +{
> > +	struct drm_plane *plane;
> > +	struct drm_plane_state *plane_state;
> > +	const struct drm_plane_helper_funcs *funcs;
> > +	int i;
> > +
> > +	for_each_new_plane_in_state(state, plane, plane_state, i) {
> > +		funcs = plane->helper_private;
> > +		funcs->atomic_async_update(plane, plane_state);
> > +	}
> > +}
> > +EXPORT_SYMBOL(drm_atomic_helper_async_commit);
> > +
> > +/**
> >   * drm_atomic_helper_commit - commit validated state object
> >   * @dev: DRM device
> >   * @state: the driver state object
> > @@ -1258,6 +1282,17 @@ int drm_atomic_helper_commit(struct drm_device *dev,
> >  {
> >  	int ret;
> >  
> > +	if (state->async_update) {
> > +		ret = drm_atomic_helper_prepare_planes(dev, state);
> > +		if (ret)
> > +			return ret;
> > +
> > +		drm_atomic_helper_async_commit(dev, state);
> > +		drm_atomic_helper_cleanup_planes(dev, state);
> > +
> > +		return 0;
> > +	}
> > +
> >  	ret = drm_atomic_helper_setup_commit(state, nonblock);
> >  	if (ret)
> >  		return ret;
> > diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> > index 788daf7..70ca279 100644
> > --- a/include/drm/drm_atomic.h
> > +++ b/include/drm/drm_atomic.h
> > @@ -160,6 +160,7 @@ struct __drm_connnectors_state {
> >   * @dev: parent DRM device
> >   * @allow_modeset: allow full modeset
> >   * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
> > + * @async_update: hint for asynchronous plane update
> >   * @planes: pointer to array of structures with per-plane data
> >   * @crtcs: pointer to array of CRTC pointers
> >   * @num_connector: size of the @connectors and @connector_states arrays
> > @@ -172,6 +173,7 @@ struct drm_atomic_state {
> >  	struct drm_device *dev;
> >  	bool allow_modeset : 1;
> >  	bool legacy_cursor_update : 1;
> > +	bool async_update : 1;
> >  	struct __drm_planes_state *planes;
> >  	struct __drm_crtcs_state *crtcs;
> >  	int num_connector;
> > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> > index f0a8678..8571b51 100644
> > --- a/include/drm/drm_atomic_helper.h
> > +++ b/include/drm/drm_atomic_helper.h
> > @@ -44,6 +44,8 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
> >  int drm_atomic_helper_commit(struct drm_device *dev,
> >  			     struct drm_atomic_state *state,
> >  			     bool nonblock);
> > +void drm_atomic_helper_async_commit(struct drm_device *dev,
> > +				    struct drm_atomic_state *state);
> >  
> >  int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
> >  					struct drm_atomic_state *state,
> > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > index c01c328..7964a78 100644
> > --- a/include/drm/drm_modeset_helper_vtables.h
> > +++ b/include/drm/drm_modeset_helper_vtables.h
> > @@ -1048,6 +1048,54 @@ struct drm_plane_helper_funcs {
> >  	 */
> >  	void (*atomic_disable)(struct drm_plane *plane,
> >  			       struct drm_plane_state *old_state);
> > +
> > +	/**
> > +	 * @atomic_async_check:
> > +	 *
> > +	 * Drivers should set this function pointer to check if the plane state
> > +	 * can be updated in a async fashion. Here async means "not vblank
> > +	 * synchronized".
> > +	 *
> > +	 * This hook is called by drm_atomic_async_check() to establish if a
> > +	 * given update can be committed asynchronously, that is, if it can
> > +	 * jump ahead the state currently queued for update.
> > +	 *
> > +	 * RETURNS:
> > +	 *
> > +	 * Return 0 on success and any error returned indicates that the update
> > +	 * can not be applied in asynchronous manner.
> > +	 */
> > +	int (*atomic_async_check)(struct drm_plane *plane,
> > +				  struct drm_plane_state *state);
> > +
> > +	/**
> > +	 * @atomic_async_update:
> > +	 *
> > +	 * Drivers should set this function pointer to perform asynchronous
> > +	 * updates of planes, that is, jump ahead the currently queued
> 
> "jump ahead of the"
> 
> > +	 * state for and update the plane. Here async means "not vblank
> 
> s/for //
> 
> > +	 * synchronized".
> > +	 *
> > +	 * This hook is called by drm_atomic_helper_async_commit().
> > +	 *
> > +	 * An async update will happen on legacy cursor updates.
> > +	 *
> > +	 * Note that unlike &drm_plane_helper_funcs.atomic_update this hook
> > +	 * takes the new &drm_plane_state as parameter. When doing async_update
> > +	 * drivers shouldn't replace the &drm_plane_state but update the
> > +	 * current one with the new plane configurations in the new
> > +	 * plane_state.
> 
> Also maybe document that this won't be called if there is an outstanding
> commit modifying the plane?
> 
> > +	 *
> > +	 * FIXME:
> > +	 *  - It only works for single plane updates
> > +	 *  - Async Pageflips are not supported yet
> > +	 *  - Some hm might still scan out the old buffer until the next
> 
> "Some hw"?
> 
> > +	 *  vblank, however we let go of the fb references as soon as
> > +	 *  we run this hook. For now drivers must implement their own workers
> > +	 *  for defering if needed, until a common solution is created.
> > +	 */
> 
> "deferring"
> 
> > +	void (*atomic_async_update)(struct drm_plane *plane,
> > +				    struct drm_plane_state *new_state);
> 
> Is there a simple list of what parts of drm_plane_state may change in
> this hook?  I noticed that vc4 wasn't checking that the format doesn't
> change, for example.  I'm also not sure if we're guaranteed that the
> plane-is-enabled state isn't changing, either.

I can look into building such a list. I'll do that and send a proposed
one here.

> 
> If it's "everything", we'll need to improve the vc4 async check before
> we expose this under anything but the cursor ioctl.


	Gustavo

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous plane update
  2017-06-01  2:24     ` Gustavo Padovan
@ 2017-06-12  2:28       ` Gustavo Padovan
  0 siblings, 0 replies; 16+ messages in thread
From: Gustavo Padovan @ 2017-06-12  2:28 UTC (permalink / raw)
  To: Eric Anholt; +Cc: Gustavo Padovan, intel-gfx, dri-devel, Daniel Vetter

2017-06-01 Gustavo Padovan <gustavo@padovan.org>:

> 2017-05-31 Eric Anholt <eric@anholt.net>:
> 
> > Gustavo Padovan <gustavo@padovan.org> writes:
> > 
> > > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> > >
> > > In some cases, like cursor updates, it is interesting to update the
> > > plane in an asynchronous fashion to avoid big delays. The current queued
> > > update could be still waiting for a fence to signal and thus block any
> > > subsequent update until its scan out. In cases like this if we update the
> > > cursor synchronously through the atomic API it will cause significant
> > > delays that would even be noticed by the final user.
> > >
> > > This patch creates a fast path to jump ahead the current queued state and
> > > do single planes updates without going through all atomic steps in
> > > drm_atomic_helper_commit(). We take this path for legacy cursor updates.
> > >
> > > For now only single plane updates are supported, but we plan to support
> > > multiple planes updates and async PageFlips through this interface as well
> > > in the near future.
> > 
> > Sorry for taking so long to do some review for this.
> > 
> > > ---
> > >  drivers/gpu/drm/drm_atomic.c             | 65 ++++++++++++++++++++++++++++++++
> > >  drivers/gpu/drm/drm_atomic_helper.c      | 35 +++++++++++++++++
> > >  include/drm/drm_atomic.h                 |  2 +
> > >  include/drm/drm_atomic_helper.h          |  2 +
> > >  include/drm/drm_modeset_helper_vtables.h | 48 +++++++++++++++++++++++
> > >  5 files changed, 152 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > index be62774..2a0c297 100644
> > > --- a/drivers/gpu/drm/drm_atomic.c
> > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > @@ -631,6 +631,68 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
> > >  	return 0;
> > >  }
> > >  
> > > +static bool drm_atomic_async_check(struct drm_atomic_state *state)
> > > +{
> > > +	struct drm_crtc *crtc;
> > > +	struct drm_crtc_state *crtc_state;
> > > +	struct drm_crtc_commit *commit;
> > > +	struct drm_plane *__plane, *plane = NULL;
> > > +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> > > +	const struct drm_plane_helper_funcs *funcs;
> > > +	int i, j, n_planes = 0;
> > > +
> > > +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> > > +		if (drm_atomic_crtc_needs_modeset(crtc_state))
> > > +			return false;
> > > +	}
> > > +
> > > +	for_each_new_plane_in_state(state, __plane, __plane_state, i) {
> > > +		n_planes++;
> > > +		plane = __plane;
> > > +		plane_state = __plane_state;
> > > +	}
> > > +
> > > +	/* FIXME: we support only single plane updates for now */
> > > +	if (!plane || n_planes != 1)
> > > +		return false;
> > > +
> > > +	if (!plane_state->crtc)
> > > +		return false;
> > > +
> > > +	funcs = plane->helper_private;
> > > +	if (!funcs->atomic_async_update)
> > > +		return false;
> > > +
> > > +	if (plane_state->fence)
> > > +		return false;
> > > +
> > 
> > Could you add a comment here like:
> > 
> > /* Don't do an async update if there is an outstanding commit modifying
> >  * the plane.  This prevents our async update's changes from getting
> >  * overridden by a previous synchronous update's state.
> >  */
> > 
> > (assuming I understand its intent correctly)
> > 
> > I don't understand KMS locking enough to say if this loop is actually
> > safely guaranteeing that.  If you're convinced of that, then with my
> > little cleanups this patch will be:
> 
> I'm going to check the locking again just to make sure.
> 
> > 
> > Acked-by: Eric Anholt <eric@anholt.net>
> > 
> > > +	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> > > +		if (plane->crtc != crtc)
> > > +			continue;
> > > +
> > > +		spin_lock(&crtc->commit_lock);
> > > +		commit = list_first_entry_or_null(&crtc->commit_list,
> > > +						  struct drm_crtc_commit,
> > > +						  commit_entry);
> > > +		if (!commit) {
> > > +			spin_unlock(&crtc->commit_lock);
> > > +			continue;
> > > +		}
> > > +		spin_unlock(&crtc->commit_lock);
> > > +
> > > +		if (!crtc->state->state)
> > > +			continue;
> > > +
> > > +		for_each_plane_in_state(crtc->state->state, __plane,
> > > +					__plane_state, j) {
> > > +			if (__plane == plane)
> > > +				return false;
> > > +		}
> > > +	}
> > > +
> > > +	return !funcs->atomic_async_check(plane, plane_state);
> > > +}
> > > +
> > >  static void drm_atomic_crtc_print_state(struct drm_printer *p,
> > >  		const struct drm_crtc_state *state)
> > >  {
> > > @@ -1591,6 +1653,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
> > >  		}
> > >  	}
> > >  
> > > +	if (state->legacy_cursor_update)
> > > +		state->async_update = drm_atomic_async_check(state);
> > > +
> > >  	return ret;
> > >  }
> > >  EXPORT_SYMBOL(drm_atomic_check_only);
> > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > > index 5a3c9c0..a8efdfe 100644
> > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > @@ -1235,6 +1235,30 @@ static void commit_work(struct work_struct *work)
> > >  }
> > >  
> > >  /**
> > > + * drm_atomic_helper_async_commit - commit state asynchronously
> > > + *
> > > + * This function commits a state asynchronously, i.e., not vblank
> > > + * synchronized. It should be used on a state only when
> > > + * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
> > > + * the states like normal sync commits, but just do in-place changes on the
> > > + * current state.
> > > + */
> > > +void drm_atomic_helper_async_commit(struct drm_device *dev,
> > > +				    struct drm_atomic_state *state)
> > > +{
> > > +	struct drm_plane *plane;
> > > +	struct drm_plane_state *plane_state;
> > > +	const struct drm_plane_helper_funcs *funcs;
> > > +	int i;
> > > +
> > > +	for_each_new_plane_in_state(state, plane, plane_state, i) {
> > > +		funcs = plane->helper_private;
> > > +		funcs->atomic_async_update(plane, plane_state);
> > > +	}
> > > +}
> > > +EXPORT_SYMBOL(drm_atomic_helper_async_commit);
> > > +
> > > +/**
> > >   * drm_atomic_helper_commit - commit validated state object
> > >   * @dev: DRM device
> > >   * @state: the driver state object
> > > @@ -1258,6 +1282,17 @@ int drm_atomic_helper_commit(struct drm_device *dev,
> > >  {
> > >  	int ret;
> > >  
> > > +	if (state->async_update) {
> > > +		ret = drm_atomic_helper_prepare_planes(dev, state);
> > > +		if (ret)
> > > +			return ret;
> > > +
> > > +		drm_atomic_helper_async_commit(dev, state);
> > > +		drm_atomic_helper_cleanup_planes(dev, state);
> > > +
> > > +		return 0;
> > > +	}
> > > +
> > >  	ret = drm_atomic_helper_setup_commit(state, nonblock);
> > >  	if (ret)
> > >  		return ret;
> > > diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> > > index 788daf7..70ca279 100644
> > > --- a/include/drm/drm_atomic.h
> > > +++ b/include/drm/drm_atomic.h
> > > @@ -160,6 +160,7 @@ struct __drm_connnectors_state {
> > >   * @dev: parent DRM device
> > >   * @allow_modeset: allow full modeset
> > >   * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
> > > + * @async_update: hint for asynchronous plane update
> > >   * @planes: pointer to array of structures with per-plane data
> > >   * @crtcs: pointer to array of CRTC pointers
> > >   * @num_connector: size of the @connectors and @connector_states arrays
> > > @@ -172,6 +173,7 @@ struct drm_atomic_state {
> > >  	struct drm_device *dev;
> > >  	bool allow_modeset : 1;
> > >  	bool legacy_cursor_update : 1;
> > > +	bool async_update : 1;
> > >  	struct __drm_planes_state *planes;
> > >  	struct __drm_crtcs_state *crtcs;
> > >  	int num_connector;
> > > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> > > index f0a8678..8571b51 100644
> > > --- a/include/drm/drm_atomic_helper.h
> > > +++ b/include/drm/drm_atomic_helper.h
> > > @@ -44,6 +44,8 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
> > >  int drm_atomic_helper_commit(struct drm_device *dev,
> > >  			     struct drm_atomic_state *state,
> > >  			     bool nonblock);
> > > +void drm_atomic_helper_async_commit(struct drm_device *dev,
> > > +				    struct drm_atomic_state *state);
> > >  
> > >  int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
> > >  					struct drm_atomic_state *state,
> > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > index c01c328..7964a78 100644
> > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > @@ -1048,6 +1048,54 @@ struct drm_plane_helper_funcs {
> > >  	 */
> > >  	void (*atomic_disable)(struct drm_plane *plane,
> > >  			       struct drm_plane_state *old_state);
> > > +
> > > +	/**
> > > +	 * @atomic_async_check:
> > > +	 *
> > > +	 * Drivers should set this function pointer to check if the plane state
> > > +	 * can be updated in a async fashion. Here async means "not vblank
> > > +	 * synchronized".
> > > +	 *
> > > +	 * This hook is called by drm_atomic_async_check() to establish if a
> > > +	 * given update can be committed asynchronously, that is, if it can
> > > +	 * jump ahead the state currently queued for update.
> > > +	 *
> > > +	 * RETURNS:
> > > +	 *
> > > +	 * Return 0 on success and any error returned indicates that the update
> > > +	 * can not be applied in asynchronous manner.
> > > +	 */
> > > +	int (*atomic_async_check)(struct drm_plane *plane,
> > > +				  struct drm_plane_state *state);
> > > +
> > > +	/**
> > > +	 * @atomic_async_update:
> > > +	 *
> > > +	 * Drivers should set this function pointer to perform asynchronous
> > > +	 * updates of planes, that is, jump ahead the currently queued
> > 
> > "jump ahead of the"
> > 
> > > +	 * state for and update the plane. Here async means "not vblank
> > 
> > s/for //
> > 
> > > +	 * synchronized".
> > > +	 *
> > > +	 * This hook is called by drm_atomic_helper_async_commit().
> > > +	 *
> > > +	 * An async update will happen on legacy cursor updates.
> > > +	 *
> > > +	 * Note that unlike &drm_plane_helper_funcs.atomic_update this hook
> > > +	 * takes the new &drm_plane_state as parameter. When doing async_update
> > > +	 * drivers shouldn't replace the &drm_plane_state but update the
> > > +	 * current one with the new plane configurations in the new
> > > +	 * plane_state.
> > 
> > Also maybe document that this won't be called if there is an outstanding
> > commit modifying the plane?
> > 
> > > +	 *
> > > +	 * FIXME:
> > > +	 *  - It only works for single plane updates
> > > +	 *  - Async Pageflips are not supported yet
> > > +	 *  - Some hm might still scan out the old buffer until the next
> > 
> > "Some hw"?
> > 
> > > +	 *  vblank, however we let go of the fb references as soon as
> > > +	 *  we run this hook. For now drivers must implement their own workers
> > > +	 *  for defering if needed, until a common solution is created.
> > > +	 */
> > 
> > "deferring"
> > 
> > > +	void (*atomic_async_update)(struct drm_plane *plane,
> > > +				    struct drm_plane_state *new_state);
> > 
> > Is there a simple list of what parts of drm_plane_state may change in
> > this hook?  I noticed that vc4 wasn't checking that the format doesn't
> > change, for example.  I'm also not sure if we're guaranteed that the
> > plane-is-enabled state isn't changing, either.
> 
> I can look into building such a list. I'll do that and send a proposed
> one here.

The list of things that may change on this hook really depends on the
driver, so I believe we need to improve the vc4 async check before
enabling it through the atomic ioctl.

> 
> > 
> > If it's "everything", we'll need to improve the vc4 async check before
> > we expose this under anything but the cursor ioctl.
> 
> 
> 	Gustavo
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-06-12  2:28 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-25 19:51 [PATCH RESEND 0/6] drm/atomic: add async plane update Gustavo Padovan
2017-05-25 19:51 ` [PATCH RESEND 1/6] drm/atomic: initial support for asynchronous " Gustavo Padovan
2017-05-26  8:45   ` Archit Taneja
2017-06-01  0:47   ` Eric Anholt
2017-06-01  2:24     ` Gustavo Padovan
2017-06-12  2:28       ` Gustavo Padovan
2017-05-25 19:51 ` [PATCH RESEND 2/6] drm/i915: update cursors asynchronously through atomic Gustavo Padovan
2017-05-25 19:51 ` [PATCH RESEND 3/6] drm/i915: remove intel_cursor_plane_funcs Gustavo Padovan
2017-05-25 19:51 ` [PATCH RESEND 4/6] drm/msm: update cursors asynchronously through atomic Gustavo Padovan
2017-05-26  8:44   ` Archit Taneja
2017-05-25 19:51 ` [PATCH RESEND 5/6] drm/msm: remove mdp5_cursor_plane_funcs Gustavo Padovan
2017-05-26  8:44   ` Archit Taneja
2017-05-25 19:51 ` [PATCH RESEND 6/6] drm/vc4: update cursors asynchronously through atomic Gustavo Padovan
2017-06-01  0:43   ` Eric Anholt
2017-06-01  2:07     ` Gustavo Padovan
2017-05-25 20:11 ` ✓ Fi.CI.BAT: success for drm/atomic: add async plane update Patchwork

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).