All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2 0/7] drm: asynchronous atomic plane update
@ 2017-04-27 15:15 Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 1/7] drm/atomic: initial support for asynchronous " Gustavo Padovan
                   ` (8 more replies)
  0 siblings, 9 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan

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

Hi,

Second take of Asynchronous Plane Updates over Atomic. Here I looked
to msm, vc4 and i915 to identify a common pattern to create atomic helpers
for async updates. So in patch 1 drm_atomic_async_check() and
drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
->atomic_async_check() and ->atomic_async_commit().

For now we only support async update for one plane at a time. Also the async
update can't modify the CRTC so no modesets are allowed.

Then the other patches add support for it in the drivers. I did virtio mostly
for testing. i915 have been converted and I've been using it without any
problem. IGT tests seems to be fine, but there are somewhat random failures
with or without the async update changes. msm and vc4 are only compile-tested.
So I think this needs more testing

I started IGT changes to test the Atomic IOCTL with the new flag:

https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/

v2:

Apart from all comments on v1 one extra change I made was to remove the
constraint of only updating the plane if the queued state didn't touch
that plane. I believe it was a too cautious of a change, furthermore this
constraint was affecting throughput negatively on i915.

TODO

 - improve i-g-t tests where needed
 - support async page flips (that can be done after uptreaming this part)
 - figure out what to do for hw that do not update the plane until the next
 vblank. Maybe wait and see what they do and them extract helpers?

Comments are welcome!

Gustavo Padovan (7):
  drm/atomic: initial support for asynchronous plane update
  drm/virtio: support async cursor updates
  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              |  50 ++++++++++
 drivers/gpu/drm/drm_atomic_helper.c       |  48 +++++++++
 drivers/gpu/drm/i915/intel_atomic_plane.c |  52 ++++++++++
 drivers/gpu/drm/i915/intel_display.c      | 158 ++++-------------------------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 161 ++++++++++--------------------
 drivers/gpu/drm/vc4/vc4_plane.c           |  94 +++++------------
 drivers/gpu/drm/virtio/virtgpu_plane.c    |  42 ++++++++
 include/drm/drm_atomic.h                  |   2 +
 include/drm/drm_atomic_helper.h           |   2 +
 include/drm/drm_modeset_helper_vtables.h  |  45 +++++++++
 include/uapi/drm/drm_mode.h               |   4 +-
 11 files changed, 343 insertions(+), 315 deletions(-)

-- 
2.9.3

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

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

* [RFC v2 1/7] drm/atomic: initial support for asynchronous plane update
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
@ 2017-04-27 15:15 ` Gustavo Padovan
  2017-04-27 15:37   ` Ville Syrjälä
  2017-04-27 15:15 ` [RFC v2 2/7] drm/virtio: support async cursor updates Gustavo Padovan
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, 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 step in
drm_atomic_helper_commit().

We take this path for legacy cursor updates. Users can also set the
DRM_MODE_ATOMIC_ASYNC_UPDATE flag on atomic 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.

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             | 50 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_atomic_helper.c      | 48 ++++++++++++++++++++++++++++++
 include/drm/drm_atomic.h                 |  2 ++
 include/drm/drm_atomic_helper.h          |  2 ++
 include/drm/drm_modeset_helper_vtables.h | 45 ++++++++++++++++++++++++++++
 include/uapi/drm/drm_mode.h              |  4 ++-
 6 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 30229ab..7b60cf8 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -77,6 +77,7 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
 	 * setting this appropriately?
 	 */
 	state->allow_modeset = true;
+	state->async_update = true;
 
 	state->crtcs = kcalloc(dev->mode_config.num_crtc,
 			       sizeof(*state->crtcs), GFP_KERNEL);
@@ -631,6 +632,51 @@ 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_plane *__plane, *plane = NULL;
+	struct drm_plane_state *__plane_state, *plane_state = NULL;
+	const struct drm_plane_helper_funcs *funcs;
+	int i, 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 single plane updates for now */
+	if (!plane || n_planes != 1)
+		return false;
+
+	funcs = plane->helper_private;
+	if (!funcs->atomic_async_update)
+		return false;
+
+	if (plane_state->fence)
+		return false;
+
+	if (!plane->state->crtc || (plane->state->crtc != plane_state->crtc))
+		return false;
+
+	/* No configuring new scaling in the async path. */
+	if (plane->state->crtc_w != plane_state->crtc_w ||
+	    plane->state->crtc_h != plane_state->crtc_h ||
+	    plane->state->src_w != plane_state->src_w ||
+	    plane->state->src_h != plane_state->src_h) {
+		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 +1637,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
 		}
 	}
 
+	if (state->async_update || state->legacy_cursor_update)
+		state->async_update = drm_atomic_async_check(state);
+
 	return ret;
 }
 EXPORT_SYMBOL(drm_atomic_check_only);
@@ -2132,6 +2181,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 
 	state->acquire_ctx = &ctx;
 	state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
+	state->async_update = !!(arg->flags & DRM_MODE_ATOMIC_ASYNC_UPDATE);
 
 retry:
 	plane_mask = 0;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 5a3c9c0..73cd07d 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1235,6 +1235,43 @@ 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() succeds. Async commits are not supposed to swap the
+ * states like normal sync commits, but just do in-place change 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) {
+		struct drm_framebuffer *old_fb;
+
+		funcs = plane->helper_private;
+		funcs->atomic_async_update(plane, plane_state);
+
+		plane->state->src_x = plane_state->src_x;
+		plane->state->src_y = plane_state->src_y;
+		plane->state->crtc_x = plane_state->crtc_x;
+		plane->state->crtc_y = plane_state->crtc_y;
+
+		if (plane->state->fb != plane_state->fb) {
+			old_fb = plane->state->fb;
+			plane->state->fb = plane_state->fb;
+			plane_state->fb = old_fb;
+		}
+	}
+}
+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 +1295,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..b28ffa2 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -1048,6 +1048,51 @@ 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.
+	 *
+	 * FIXME:
+	 *  - It only works for single plane updates
+	 *  - Async Pageflips are not supported yet
+	 */
+	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 if the user set the
+	 * DRM_MODE_ATOMIC_ASYNC_UPDATE flag or 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.
+	 */
+	void (*atomic_async_update)(struct drm_plane *plane,
+				    struct drm_plane_state *new_state);
 };
 
 /**
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 8c67fc0..7c067ca 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -646,13 +646,15 @@ struct drm_mode_destroy_dumb {
 #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
 #define DRM_MODE_ATOMIC_NONBLOCK  0x0200
 #define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
+#define DRM_MODE_ATOMIC_ASYNC_UPDATE 0x0800
 
 #define DRM_MODE_ATOMIC_FLAGS (\
 		DRM_MODE_PAGE_FLIP_EVENT |\
 		DRM_MODE_PAGE_FLIP_ASYNC |\
 		DRM_MODE_ATOMIC_TEST_ONLY |\
 		DRM_MODE_ATOMIC_NONBLOCK |\
-		DRM_MODE_ATOMIC_ALLOW_MODESET)
+		DRM_MODE_ATOMIC_ALLOW_MODESET |\
+		DRM_MODE_ATOMIC_ASYNC_UPDATE)
 
 struct drm_mode_atomic {
 	__u32 flags;
-- 
2.9.3

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

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

* [RFC v2 2/7] drm/virtio: support async cursor updates
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 1/7] drm/atomic: initial support for asynchronous " Gustavo Padovan
@ 2017-04-27 15:15 ` Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic Gustavo Padovan
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan

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

Short circuit the update path for cursors and use the drm async update
infrastructure.

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

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>

---
I wrote this mostly for testing purposes, not sure if its something that
we actually need for virtio.
---
 drivers/gpu/drm/virtio/virtgpu_plane.c | 42 ++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 76d5fed..783f146 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -260,6 +260,46 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
 	virtio_gpu_cursor_ping(vgdev, output);
 }
 
+static int virtio_gpu_cursor_plane_async_check(struct drm_plane *plane,
+					       struct drm_plane_state *new_state)
+{
+	struct virtio_gpu_output *output;
+
+	if (!plane->state->crtc)
+		return -EINVAL;
+
+	output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
+	if (!output)
+		return -EINVAL;
+
+	if (plane->state->fb != new_state->fb)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void virtio_gpu_cursor_plane_async_update(struct drm_plane *plane,
+						 struct drm_plane_state *new_state)
+{
+	struct drm_device *dev = plane->dev;
+	struct virtio_gpu_device *vgdev = dev->dev_private;
+	struct virtio_gpu_output *output = NULL;
+
+	output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
+	if (WARN_ON(!output))
+		return;
+
+	if (plane->state->fb != new_state->fb)
+		return;
+
+	DRM_DEBUG("move +%d+%d\n", new_state->crtc_x, new_state->crtc_y);
+
+	output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR);
+	output->cursor.pos.x = cpu_to_le32(new_state->crtc_x);
+	output->cursor.pos.y = cpu_to_le32(new_state->crtc_y);
+	virtio_gpu_cursor_ping(vgdev, output);
+}
+
 static const struct drm_plane_helper_funcs virtio_gpu_primary_helper_funcs = {
 	.atomic_check		= virtio_gpu_plane_atomic_check,
 	.atomic_update		= virtio_gpu_primary_plane_update,
@@ -268,6 +308,8 @@ static const struct drm_plane_helper_funcs virtio_gpu_primary_helper_funcs = {
 static const struct drm_plane_helper_funcs virtio_gpu_cursor_helper_funcs = {
 	.atomic_check		= virtio_gpu_plane_atomic_check,
 	.atomic_update		= virtio_gpu_cursor_plane_update,
+	.atomic_async_check	= virtio_gpu_cursor_plane_async_check,
+	.atomic_async_update	= virtio_gpu_cursor_plane_async_update,
 };
 
 struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
-- 
2.9.3

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

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

* [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 1/7] drm/atomic: initial support for asynchronous " Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 2/7] drm/virtio: support async cursor updates Gustavo Padovan
@ 2017-04-27 15:15 ` Gustavo Padovan
  2017-04-27 15:41   ` Ville Syrjälä
  2017-04-27 15:15 ` [RFC v2 4/7] drm/i915: remove intel_cursor_plane_funcs Gustavo Padovan
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, 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.

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 |  52 +++++++++++
 drivers/gpu/drm/i915/intel_display.c      | 147 +++++-------------------------
 2 files changed, 73 insertions(+), 126 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index cfb4729..c5d0596 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -246,11 +246,63 @@ 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;
+
+	/* Only changing fb should be in the fastpath.  */
+	if (!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;
+
+	i915_gem_track_fb(intel_fb_obj(plane->state->fb),
+			  intel_fb_obj(new_state->fb),
+			  intel_plane->frontbuffer_bit);
+
+	*to_intel_plane_state(plane->state) = *to_intel_plane_state(new_state);
+	to_intel_plane_state(new_state)->vma =
+					to_intel_plane_state(plane->state)->vma;
+
+	plane->state->visible = new_state->visible;
+
+	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(new_state));
+	} else {
+		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
+		intel_plane->disable_plane(plane, crtc);
+	}
+}
+
 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 e217d04..c854c87 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12993,13 +12993,29 @@ static int intel_atomic_commit(struct drm_device *dev,
 	int ret = 0;
 
 	/*
-	 * The intel_legacy_cursor_update() fast path takes care
+	 * 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);
+
+		mutex_lock(&dev->struct_mutex);
+		drm_atomic_helper_cleanup_planes(dev, state);
+		mutex_unlock(&dev->struct_mutex);
+		return 0;
+	}
+
 	if (INTEL_GEN(dev_priv) < 9)
 		state->legacy_cursor_update = false;
 
@@ -13141,6 +13157,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		}
 	}
 
+	if (new_state->state->async_update)
+		return 0;
+
 	if (!obj && !old_obj)
 		return 0;
 
@@ -13360,132 +13379,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.3

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

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

* [RFC v2 4/7] drm/i915: remove intel_cursor_plane_funcs
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
                   ` (2 preceding siblings ...)
  2017-04-27 15:15 ` [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-04-27 15:15 ` Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 5/7] drm/msm: update cursors asynchronously through atomic Gustavo Padovan
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan, 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 c854c87..26d20e5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13379,17 +13379,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)
 {
@@ -13636,7 +13625,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.3

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

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

* [RFC v2 5/7] drm/msm: update cursors asynchronously through atomic
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
                   ` (3 preceding siblings ...)
  2017-04-27 15:15 ` [RFC v2 4/7] drm/i915: remove intel_cursor_plane_funcs Gustavo Padovan
@ 2017-04-27 15:15 ` Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 6/7] drm/msm: remove mdp5_cursor_plane_funcs Gustavo Padovan
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan

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.

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

Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 137 +++++++++++-------------------
 1 file changed, 50 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 60a5451..d232bd5 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -31,15 +31,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 void set_scanout_locked(struct drm_plane *plane,
 		struct drm_framebuffer *fb);
 
@@ -253,7 +244,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,
@@ -430,11 +421,60 @@ 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 (!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)
+{
+	if (plane_enabled(new_state)) {
+		struct mdp5_ctl *ctl;
+		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, 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 drm_plane *plane,
@@ -882,83 +922,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;
-
-		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, 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);
-}
-
 enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane)
 {
 	struct mdp5_plane_state *pstate = to_mdp5_plane_state(plane->state);
-- 
2.9.3

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

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

* [RFC v2 6/7] drm/msm: remove mdp5_cursor_plane_funcs
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
                   ` (4 preceding siblings ...)
  2017-04-27 15:15 ` [RFC v2 5/7] drm/msm: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-04-27 15:15 ` Gustavo Padovan
  2017-04-27 15:15 ` [RFC v2 7/7] drm/vc4: update cursors asynchronously through atomic Gustavo Padovan
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan

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>
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 d232bd5..563bad5 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -243,19 +243,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)
 {
@@ -961,16 +948,9 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
 	mdp5_plane->nformats = mdp_get_formats(mdp5_plane->formats,
 		ARRAY_SIZE(mdp5_plane->formats), false);
 
-	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.3

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

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

* [RFC v2 7/7] drm/vc4: update cursors asynchronously through atomic
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
                   ` (5 preceding siblings ...)
  2017-04-27 15:15 ` [RFC v2 6/7] drm/msm: remove mdp5_cursor_plane_funcs Gustavo Padovan
@ 2017-04-27 15:15 ` Gustavo Padovan
  2017-04-27 16:10 ` [RFC v2 0/7] drm: asynchronous atomic plane update Ville Syrjälä
  2017-05-09 14:02 ` Ville Syrjälä
  8 siblings, 0 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 15:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Gustavo Padovan

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.

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>
---
 drivers/gpu/drm/vc4/vc4_plane.c | 94 ++++++++++++-----------------------------
 1 file changed, 26 insertions(+), 68 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index d34cd53..c42c610 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -735,70 +735,25 @@ 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)
+static int vc4_plane_atomic_async_check(struct drm_plane *plane,
+					struct drm_plane_state *state)
 {
-	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)
-{
-	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)
-		goto out;
-
-	/* 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 (plane != state->crtc->cursor)
+		return -EINVAL;
 
-	if (fb != plane_state->fb) {
-		drm_atomic_set_fb_for_plane(plane->state, fb);
-		vc4_plane_async_set_fb(plane, fb);
-	}
+	if (!plane->state)
+		return -EINVAL;
 
-	/* 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;
+	return 0;
+}
 
-	/* Allow changing the start position within the cursor BO, if
-	 * that matters.
-	 */
-	plane_state->src_x = src_x;
-	plane_state->src_y = src_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);
 
-	/* 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 +765,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.3

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

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

* Re: [RFC v2 1/7] drm/atomic: initial support for asynchronous plane update
  2017-04-27 15:15 ` [RFC v2 1/7] drm/atomic: initial support for asynchronous " Gustavo Padovan
@ 2017-04-27 15:37   ` Ville Syrjälä
  2017-04-27 19:35     ` Gustavo Padovan
  0 siblings, 1 reply; 22+ messages in thread
From: Ville Syrjälä @ 2017-04-27 15:37 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: Gustavo Padovan, dri-devel, Daniel Vetter

On Thu, Apr 27, 2017 at 12:15:13PM -0300, 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 step in
> drm_atomic_helper_commit().
> 
> We take this path for legacy cursor updates. Users can also set the
> DRM_MODE_ATOMIC_ASYNC_UPDATE flag on atomic 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.
> 
> 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             | 50 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_atomic_helper.c      | 48 ++++++++++++++++++++++++++++++
>  include/drm/drm_atomic.h                 |  2 ++
>  include/drm/drm_atomic_helper.h          |  2 ++
>  include/drm/drm_modeset_helper_vtables.h | 45 ++++++++++++++++++++++++++++
>  include/uapi/drm/drm_mode.h              |  4 ++-
>  6 files changed, 150 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 30229ab..7b60cf8 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -77,6 +77,7 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
>  	 * setting this appropriately?
>  	 */
>  	state->allow_modeset = true;
> +	state->async_update = true;
>  
>  	state->crtcs = kcalloc(dev->mode_config.num_crtc,
>  			       sizeof(*state->crtcs), GFP_KERNEL);
> @@ -631,6 +632,51 @@ 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_plane *__plane, *plane = NULL;
> +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> +	const struct drm_plane_helper_funcs *funcs;
> +	int i, 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 single plane updates for now */
> +	if (!plane || n_planes != 1)
> +		return false;
> +
> +	funcs = plane->helper_private;
> +	if (!funcs->atomic_async_update)
> +		return false;
> +
> +	if (plane_state->fence)
> +		return false;
> +
> +	if (!plane->state->crtc || (plane->state->crtc != plane_state->crtc))
> +		return false;
> +
> +	/* No configuring new scaling in the async path. */

Those checks aren't really about scaling. Well, they are also about
scaling, but they're mainly about changing size.

What I don't really understand is why we're enforcing these restrictions
in the core but leaving other restrictions up to the driver. I don't see
size changes as anything really special compared to many of the other
restrictions that would now be up to each driver.

If you're really after some lowest common denominator as far as
exposed capabilities are concerned then I think the core should do
more checking. OTOH if you're not interested limiting what each
driver exposes then I don't see why the core checks anything at all.

> +	if (plane->state->crtc_w != plane_state->crtc_w ||
> +	    plane->state->crtc_h != plane_state->crtc_h ||
> +	    plane->state->src_w != plane_state->src_w ||
> +	    plane->state->src_h != plane_state->src_h) {
> +		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)
>  {
<snip> 
>  /**
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 8c67fc0..7c067ca 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -646,13 +646,15 @@ struct drm_mode_destroy_dumb {
>  #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
>  #define DRM_MODE_ATOMIC_NONBLOCK  0x0200
>  #define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
> +#define DRM_MODE_ATOMIC_ASYNC_UPDATE 0x0800

What exactly is that flag supposed to mean?

>  
>  #define DRM_MODE_ATOMIC_FLAGS (\
>  		DRM_MODE_PAGE_FLIP_EVENT |\
>  		DRM_MODE_PAGE_FLIP_ASYNC |\
>  		DRM_MODE_ATOMIC_TEST_ONLY |\
>  		DRM_MODE_ATOMIC_NONBLOCK |\
> -		DRM_MODE_ATOMIC_ALLOW_MODESET)
> +		DRM_MODE_ATOMIC_ALLOW_MODESET |\
> +		DRM_MODE_ATOMIC_ASYNC_UPDATE)
>  
>  struct drm_mode_atomic {
>  	__u32 flags;
> -- 
> 2.9.3
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic
  2017-04-27 15:15 ` [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-04-27 15:41   ` Ville Syrjälä
  2017-04-27 19:39     ` Gustavo Padovan
  0 siblings, 1 reply; 22+ messages in thread
From: Ville Syrjälä @ 2017-04-27 15:41 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: Gustavo Padovan, dri-devel, Daniel Vetter

On Thu, Apr 27, 2017 at 12:15:15PM -0300, 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
> intel_legacy_cursor_update() did but through atomic.
> 
> 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 |  52 +++++++++++
>  drivers/gpu/drm/i915/intel_display.c      | 147 +++++-------------------------
>  2 files changed, 73 insertions(+), 126 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index cfb4729..c5d0596 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -246,11 +246,63 @@ 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;
> +
> +	/* Only changing fb should be in the fastpath.  */

No, we want cursor movement there as well. It's somewhat impossible
to see from this code now that the core has the size checks. But even
so the comment should not lie.

> +	if (!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;
> +
> +	i915_gem_track_fb(intel_fb_obj(plane->state->fb),
> +			  intel_fb_obj(new_state->fb),
> +			  intel_plane->frontbuffer_bit);
> +
> +	*to_intel_plane_state(plane->state) = *to_intel_plane_state(new_state);
> +	to_intel_plane_state(new_state)->vma =
> +					to_intel_plane_state(plane->state)->vma;
> +
> +	plane->state->visible = new_state->visible;
> +
> +	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(new_state));
> +	} else {
> +		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
> +		intel_plane->disable_plane(plane, crtc);
> +	}
> +}
> +
>  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,

NAK. We don't want these "async" updates for anything but cursors.

>  };
>  
>  /**
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index e217d04..c854c87 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12993,13 +12993,29 @@ static int intel_atomic_commit(struct drm_device *dev,
>  	int ret = 0;
>  
>  	/*
> -	 * The intel_legacy_cursor_update() fast path takes care
> +	 * 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);
> +
> +		mutex_lock(&dev->struct_mutex);
> +		drm_atomic_helper_cleanup_planes(dev, state);
> +		mutex_unlock(&dev->struct_mutex);
> +		return 0;
> +	}
> +
>  	if (INTEL_GEN(dev_priv) < 9)
>  		state->legacy_cursor_update = false;
>  
> @@ -13141,6 +13157,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>  		}
>  	}
>  
> +	if (new_state->state->async_update)
> +		return 0;
> +
>  	if (!obj && !old_obj)
>  		return 0;
>  
> @@ -13360,132 +13379,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.3
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC v2 0/7] drm: asynchronous atomic plane update
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
                   ` (6 preceding siblings ...)
  2017-04-27 15:15 ` [RFC v2 7/7] drm/vc4: update cursors asynchronously through atomic Gustavo Padovan
@ 2017-04-27 16:10 ` Ville Syrjälä
  2017-04-27 18:36   ` Gustavo Padovan
  2017-05-09 14:02 ` Ville Syrjälä
  8 siblings, 1 reply; 22+ messages in thread
From: Ville Syrjälä @ 2017-04-27 16:10 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: Gustavo Padovan, dri-devel

On Thu, Apr 27, 2017 at 12:15:12PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.com>
> 
> Hi,
> 
> Second take of Asynchronous Plane Updates over Atomic. Here I looked
> to msm, vc4 and i915 to identify a common pattern to create atomic helpers
> for async updates. So in patch 1 drm_atomic_async_check() and
> drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
> ->atomic_async_check() and ->atomic_async_commit().
> 
> For now we only support async update for one plane at a time. Also the async
> update can't modify the CRTC so no modesets are allowed.
> 
> Then the other patches add support for it in the drivers. I did virtio mostly
> for testing. i915 have been converted and I've been using it without any
> problem. IGT tests seems to be fine, but there are somewhat random failures
> with or without the async update changes. msm and vc4 are only compile-tested.
> So I think this needs more testing
> 
> I started IGT changes to test the Atomic IOCTL with the new flag:
> 
> https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/
> 
> v2:
> 
> Apart from all comments on v1 one extra change I made was to remove the
> constraint of only updating the plane if the queued state didn't touch
> that plane. I believe it was a too cautious of a change, furthermore this
> constraint was affecting throughput negatively on i915.

So you're now allowing reordering the updates? As in update A is
scheduled before update B, but update B happens before update A.
That is not a good idea.

> 
> TODO
> 
>  - improve i-g-t tests where needed
>  - support async page flips (that can be done after uptreaming this part)
>  - figure out what to do for hw that do not update the plane until the next
>  vblank. Maybe wait and see what they do and them extract helpers?
> 
> Comments are welcome!
> 
> Gustavo Padovan (7):
>   drm/atomic: initial support for asynchronous plane update
>   drm/virtio: support async cursor updates
>   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              |  50 ++++++++++
>  drivers/gpu/drm/drm_atomic_helper.c       |  48 +++++++++
>  drivers/gpu/drm/i915/intel_atomic_plane.c |  52 ++++++++++
>  drivers/gpu/drm/i915/intel_display.c      | 158 ++++-------------------------
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 161 ++++++++++--------------------
>  drivers/gpu/drm/vc4/vc4_plane.c           |  94 +++++------------
>  drivers/gpu/drm/virtio/virtgpu_plane.c    |  42 ++++++++
>  include/drm/drm_atomic.h                  |   2 +
>  include/drm/drm_atomic_helper.h           |   2 +
>  include/drm/drm_modeset_helper_vtables.h  |  45 +++++++++
>  include/uapi/drm/drm_mode.h               |   4 +-
>  11 files changed, 343 insertions(+), 315 deletions(-)
> 
> -- 
> 2.9.3
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC v2 0/7] drm: asynchronous atomic plane update
  2017-04-27 16:10 ` [RFC v2 0/7] drm: asynchronous atomic plane update Ville Syrjälä
@ 2017-04-27 18:36   ` Gustavo Padovan
  2017-04-28  8:53     ` Ville Syrjälä
  0 siblings, 1 reply; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 18:36 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Gustavo Padovan, dri-devel

2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:

> On Thu, Apr 27, 2017 at 12:15:12PM -0300, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> > 
> > Hi,
> > 
> > Second take of Asynchronous Plane Updates over Atomic. Here I looked
> > to msm, vc4 and i915 to identify a common pattern to create atomic helpers
> > for async updates. So in patch 1 drm_atomic_async_check() and
> > drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
> > ->atomic_async_check() and ->atomic_async_commit().
> > 
> > For now we only support async update for one plane at a time. Also the async
> > update can't modify the CRTC so no modesets are allowed.
> > 
> > Then the other patches add support for it in the drivers. I did virtio mostly
> > for testing. i915 have been converted and I've been using it without any
> > problem. IGT tests seems to be fine, but there are somewhat random failures
> > with or without the async update changes. msm and vc4 are only compile-tested.
> > So I think this needs more testing
> > 
> > I started IGT changes to test the Atomic IOCTL with the new flag:
> > 
> > https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/
> > 
> > v2:
> > 
> > Apart from all comments on v1 one extra change I made was to remove the
> > constraint of only updating the plane if the queued state didn't touch
> > that plane. I believe it was a too cautious of a change, furthermore this
> > constraint was affecting throughput negatively on i915.
> 
> So you're now allowing reordering the updates? As in update A is
> scheduled before update B, but update B happens before update A.
> That is not a good idea.

That is what already happens with legacy cursor updates. They jump ahead
the scheduled update and apply the cursor update. What we propose here
is to do this over atomic when DRM_MODE_ATOMIC_ASYNC_UPDATE flag is set.
Async PageFlips should use the same infrastructure in the future.

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

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

* Re: [RFC v2 1/7] drm/atomic: initial support for asynchronous plane update
  2017-04-27 15:37   ` Ville Syrjälä
@ 2017-04-27 19:35     ` Gustavo Padovan
  2017-04-28  8:57       ` Ville Syrjälä
  0 siblings, 1 reply; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 19:35 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Gustavo Padovan, dri-devel, Daniel Vetter

Hi Ville,

2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:

> On Thu, Apr 27, 2017 at 12:15:13PM -0300, 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 step in
> > drm_atomic_helper_commit().
> > 
> > We take this path for legacy cursor updates. Users can also set the
> > DRM_MODE_ATOMIC_ASYNC_UPDATE flag on atomic 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.
> > 
> > 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             | 50 ++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/drm_atomic_helper.c      | 48 ++++++++++++++++++++++++++++++
> >  include/drm/drm_atomic.h                 |  2 ++
> >  include/drm/drm_atomic_helper.h          |  2 ++
> >  include/drm/drm_modeset_helper_vtables.h | 45 ++++++++++++++++++++++++++++
> >  include/uapi/drm/drm_mode.h              |  4 ++-
> >  6 files changed, 150 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 30229ab..7b60cf8 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -77,6 +77,7 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
> >  	 * setting this appropriately?
> >  	 */
> >  	state->allow_modeset = true;
> > +	state->async_update = true;
> >  
> >  	state->crtcs = kcalloc(dev->mode_config.num_crtc,
> >  			       sizeof(*state->crtcs), GFP_KERNEL);
> > @@ -631,6 +632,51 @@ 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_plane *__plane, *plane = NULL;
> > +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> > +	const struct drm_plane_helper_funcs *funcs;
> > +	int i, 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 single plane updates for now */
> > +	if (!plane || n_planes != 1)
> > +		return false;
> > +
> > +	funcs = plane->helper_private;
> > +	if (!funcs->atomic_async_update)
> > +		return false;
> > +
> > +	if (plane_state->fence)
> > +		return false;
> > +
> > +	if (!plane->state->crtc || (plane->state->crtc != plane_state->crtc))
> > +		return false;
> > +
> > +	/* No configuring new scaling in the async path. */
> 
> Those checks aren't really about scaling. Well, they are also about
> scaling, but they're mainly about changing size.

I just copied the comment from the previous code in the drivers...
I can fix it.

> 
> What I don't really understand is why we're enforcing these restrictions
> in the core but leaving other restrictions up to the driver. I don't see
> size changes as anything really special compared to many of the other
> restrictions that would now be up to each driver.

Because I extracted what was common between msm, vc4 and i915 on their
legacy cursor update calls. I didn't want to enforce anything else in
core for now.

> 
> If you're really after some lowest common denominator as far as
> exposed capabilities are concerned then I think the core should do
> more checking. OTOH if you're not interested limiting what each
> driver exposes then I don't see why the core checks anything at all.

I think a common denominator is what we want but we only have 3 drivers
using it at the moment. We can look for more checks that shoud be done
is core. Any suggestions?

> 
> > +	if (plane->state->crtc_w != plane_state->crtc_w ||
> > +	    plane->state->crtc_h != plane_state->crtc_h ||
> > +	    plane->state->src_w != plane_state->src_w ||
> > +	    plane->state->src_h != plane_state->src_h) {
> > +		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)
> >  {
> <snip> 
> >  /**
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 8c67fc0..7c067ca 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -646,13 +646,15 @@ struct drm_mode_destroy_dumb {
> >  #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
> >  #define DRM_MODE_ATOMIC_NONBLOCK  0x0200
> >  #define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
> > +#define DRM_MODE_ATOMIC_ASYNC_UPDATE 0x0800
> 
> What exactly is that flag supposed to mean?

I don't think I provided a good explanation for it, sorry. This flag
tells core to jump ahead the queued update if the conditions in 
drm_atomic_async_check() are met. Useful for cursors and async PageFlips
over the atomic ioctl.

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

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

* Re: [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic
  2017-04-27 15:41   ` Ville Syrjälä
@ 2017-04-27 19:39     ` Gustavo Padovan
  2017-04-28  8:58       ` Ville Syrjälä
  0 siblings, 1 reply; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-27 19:39 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Gustavo Padovan, dri-devel, Daniel Vetter

Hi Ville,

2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:

> On Thu, Apr 27, 2017 at 12:15:15PM -0300, 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
> > intel_legacy_cursor_update() did but through atomic.
> > 
> > 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 |  52 +++++++++++
> >  drivers/gpu/drm/i915/intel_display.c      | 147 +++++-------------------------
> >  2 files changed, 73 insertions(+), 126 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > index cfb4729..c5d0596 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > @@ -246,11 +246,63 @@ 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;
> > +
> > +	/* Only changing fb should be in the fastpath.  */
> 
> No, we want cursor movement there as well. It's somewhat impossible
> to see from this code now that the core has the size checks. But even
> so the comment should not lie.

Sure, I'll fix the comment.

> 
> > +	if (!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;
> > +
> > +	i915_gem_track_fb(intel_fb_obj(plane->state->fb),
> > +			  intel_fb_obj(new_state->fb),
> > +			  intel_plane->frontbuffer_bit);
> > +
> > +	*to_intel_plane_state(plane->state) = *to_intel_plane_state(new_state);
> > +	to_intel_plane_state(new_state)->vma =
> > +					to_intel_plane_state(plane->state)->vma;
> > +
> > +	plane->state->visible = new_state->visible;
> > +
> > +	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(new_state));
> > +	} else {
> > +		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
> > +		intel_plane->disable_plane(plane, crtc);
> > +	}
> > +}
> > +
> >  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,
> 
> NAK. We don't want these "async" updates for anything but cursors.

Yes, we do. Async PageFlips will go through here as well. That seems a
VR requirement as well.

Gustavo

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

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

* Re: [RFC v2 0/7] drm: asynchronous atomic plane update
  2017-04-27 18:36   ` Gustavo Padovan
@ 2017-04-28  8:53     ` Ville Syrjälä
  2017-04-28 14:28       ` Gustavo Padovan
  0 siblings, 1 reply; 22+ messages in thread
From: Ville Syrjälä @ 2017-04-28  8:53 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel, Gustavo Padovan

On Thu, Apr 27, 2017 at 03:36:50PM -0300, Gustavo Padovan wrote:
> 2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:
> 
> > On Thu, Apr 27, 2017 at 12:15:12PM -0300, Gustavo Padovan wrote:
> > > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> > > 
> > > Hi,
> > > 
> > > Second take of Asynchronous Plane Updates over Atomic. Here I looked
> > > to msm, vc4 and i915 to identify a common pattern to create atomic helpers
> > > for async updates. So in patch 1 drm_atomic_async_check() and
> > > drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
> > > ->atomic_async_check() and ->atomic_async_commit().
> > > 
> > > For now we only support async update for one plane at a time. Also the async
> > > update can't modify the CRTC so no modesets are allowed.
> > > 
> > > Then the other patches add support for it in the drivers. I did virtio mostly
> > > for testing. i915 have been converted and I've been using it without any
> > > problem. IGT tests seems to be fine, but there are somewhat random failures
> > > with or without the async update changes. msm and vc4 are only compile-tested.
> > > So I think this needs more testing
> > > 
> > > I started IGT changes to test the Atomic IOCTL with the new flag:
> > > 
> > > https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/
> > > 
> > > v2:
> > > 
> > > Apart from all comments on v1 one extra change I made was to remove the
> > > constraint of only updating the plane if the queued state didn't touch
> > > that plane. I believe it was a too cautious of a change, furthermore this
> > > constraint was affecting throughput negatively on i915.
> > 
> > So you're now allowing reordering the updates? As in update A is
> > scheduled before update B, but update B happens before update A.
> > That is not a good idea.
> 
> That is what already happens with legacy cursor updates. They jump ahead
> the scheduled update and apply the cursor update.

Well, that's clearly a bug then. They are supposed to be able to jump
ahead of other planes, but not themselves.

I think the real problem is having just one timeline for the entire
crtc. The proper solution would be to have a timeline for each plane.

> What we propose here
> is to do this over atomic when DRM_MODE_ATOMIC_ASYNC_UPDATE flag is set.

The cursor thing is a hack. Using it as a guideline for something else
is not a good idea IMO. Reordering, apart from being totally unexpected
would also cause all sorts of problems because the hardware state at
the time of the programming the hardware won't match what you checked
against in your async check function.

> Async PageFlips should use the same infrastructure in the future.

I don't quite see why you have to build a parallel infrastructure for
this stuff. If the driver would do things properly then it could just
as well do this stuff from the normal path as well. So I figured the
point of all this was just to unify the hacks to one place pretty much.
Expanding the hacks to some kind of big infrastrucure is not something
I'd do.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC v2 1/7] drm/atomic: initial support for asynchronous plane update
  2017-04-27 19:35     ` Gustavo Padovan
@ 2017-04-28  8:57       ` Ville Syrjälä
  2017-04-28 14:04         ` Gustavo Padovan
  0 siblings, 1 reply; 22+ messages in thread
From: Ville Syrjälä @ 2017-04-28  8:57 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel, Gustavo Padovan, Daniel Vetter

On Thu, Apr 27, 2017 at 04:35:37PM -0300, Gustavo Padovan wrote:
> Hi Ville,
> 
> 2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:
> 
> > On Thu, Apr 27, 2017 at 12:15:13PM -0300, 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 step in
> > > drm_atomic_helper_commit().
> > > 
> > > We take this path for legacy cursor updates. Users can also set the
> > > DRM_MODE_ATOMIC_ASYNC_UPDATE flag on atomic 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.
> > > 
> > > 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             | 50 ++++++++++++++++++++++++++++++++
> > >  drivers/gpu/drm/drm_atomic_helper.c      | 48 ++++++++++++++++++++++++++++++
> > >  include/drm/drm_atomic.h                 |  2 ++
> > >  include/drm/drm_atomic_helper.h          |  2 ++
> > >  include/drm/drm_modeset_helper_vtables.h | 45 ++++++++++++++++++++++++++++
> > >  include/uapi/drm/drm_mode.h              |  4 ++-
> > >  6 files changed, 150 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > index 30229ab..7b60cf8 100644
> > > --- a/drivers/gpu/drm/drm_atomic.c
> > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > @@ -77,6 +77,7 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
> > >  	 * setting this appropriately?
> > >  	 */
> > >  	state->allow_modeset = true;
> > > +	state->async_update = true;
> > >  
> > >  	state->crtcs = kcalloc(dev->mode_config.num_crtc,
> > >  			       sizeof(*state->crtcs), GFP_KERNEL);
> > > @@ -631,6 +632,51 @@ 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_plane *__plane, *plane = NULL;
> > > +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> > > +	const struct drm_plane_helper_funcs *funcs;
> > > +	int i, 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 single plane updates for now */
> > > +	if (!plane || n_planes != 1)
> > > +		return false;
> > > +
> > > +	funcs = plane->helper_private;
> > > +	if (!funcs->atomic_async_update)
> > > +		return false;
> > > +
> > > +	if (plane_state->fence)
> > > +		return false;
> > > +
> > > +	if (!plane->state->crtc || (plane->state->crtc != plane_state->crtc))
> > > +		return false;
> > > +
> > > +	/* No configuring new scaling in the async path. */
> > 
> > Those checks aren't really about scaling. Well, they are also about
> > scaling, but they're mainly about changing size.
> 
> I just copied the comment from the previous code in the drivers...
> I can fix it.
> 
> > 
> > What I don't really understand is why we're enforcing these restrictions
> > in the core but leaving other restrictions up to the driver. I don't see
> > size changes as anything really special compared to many of the other
> > restrictions that would now be up to each driver.
> 
> Because I extracted what was common between msm, vc4 and i915 on their
> legacy cursor update calls. I didn't want to enforce anything else in
> core for now.
> 
> > 
> > If you're really after some lowest common denominator as far as
> > exposed capabilities are concerned then I think the core should do
> > more checking. OTOH if you're not interested limiting what each
> > driver exposes then I don't see why the core checks anything at all.
> 
> I think a common denominator is what we want but we only have 3 drivers
> using it at the moment. We can look for more checks that shoud be done
> is core. Any suggestions?

My suggestion is that we should come up with some proper justification
for the checks that are done by the core. Otherwise I think all the
checks should be in the drivers because the drivers can actually
justify them, or at least they should be able to.

> 
> > 
> > > +	if (plane->state->crtc_w != plane_state->crtc_w ||
> > > +	    plane->state->crtc_h != plane_state->crtc_h ||
> > > +	    plane->state->src_w != plane_state->src_w ||
> > > +	    plane->state->src_h != plane_state->src_h) {
> > > +		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)
> > >  {
> > <snip> 
> > >  /**
> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > index 8c67fc0..7c067ca 100644
> > > --- a/include/uapi/drm/drm_mode.h
> > > +++ b/include/uapi/drm/drm_mode.h
> > > @@ -646,13 +646,15 @@ struct drm_mode_destroy_dumb {
> > >  #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
> > >  #define DRM_MODE_ATOMIC_NONBLOCK  0x0200
> > >  #define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
> > > +#define DRM_MODE_ATOMIC_ASYNC_UPDATE 0x0800
> > 
> > What exactly is that flag supposed to mean?
> 
> I don't think I provided a good explanation for it, sorry. This flag
> tells core to jump ahead the queued update if the conditions in 
> drm_atomic_async_check() are met. Useful for cursors and async PageFlips
> over the atomic ioctl.

IMO mixing nea uapi in this patch is a mistake. It should be separate
and the intent of the new flag should be well documented.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic
  2017-04-27 19:39     ` Gustavo Padovan
@ 2017-04-28  8:58       ` Ville Syrjälä
  0 siblings, 0 replies; 22+ messages in thread
From: Ville Syrjälä @ 2017-04-28  8:58 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel, Gustavo Padovan, Daniel Vetter

On Thu, Apr 27, 2017 at 04:39:47PM -0300, Gustavo Padovan wrote:
> Hi Ville,
> 
> 2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:
> 
> > On Thu, Apr 27, 2017 at 12:15:15PM -0300, 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
> > > intel_legacy_cursor_update() did but through atomic.
> > > 
> > > 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 |  52 +++++++++++
> > >  drivers/gpu/drm/i915/intel_display.c      | 147 +++++-------------------------
> > >  2 files changed, 73 insertions(+), 126 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > > index cfb4729..c5d0596 100644
> > > --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> > > +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> > > @@ -246,11 +246,63 @@ 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;
> > > +
> > > +	/* Only changing fb should be in the fastpath.  */
> > 
> > No, we want cursor movement there as well. It's somewhat impossible
> > to see from this code now that the core has the size checks. But even
> > so the comment should not lie.
> 
> Sure, I'll fix the comment.
> 
> > 
> > > +	if (!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;
> > > +
> > > +	i915_gem_track_fb(intel_fb_obj(plane->state->fb),
> > > +			  intel_fb_obj(new_state->fb),
> > > +			  intel_plane->frontbuffer_bit);
> > > +
> > > +	*to_intel_plane_state(plane->state) = *to_intel_plane_state(new_state);
> > > +	to_intel_plane_state(new_state)->vma =
> > > +					to_intel_plane_state(plane->state)->vma;
> > > +
> > > +	plane->state->visible = new_state->visible;
> > > +
> > > +	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(new_state));
> > > +	} else {
> > > +		trace_intel_disable_plane(plane, to_intel_crtc(crtc));
> > > +		intel_plane->disable_plane(plane, crtc);
> > > +	}
> > > +}
> > > +
> > >  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,
> > 
> > NAK. We don't want these "async" updates for anything but cursors.
> 
> Yes, we do. Async PageFlips will go through here as well. That seems a
> VR requirement as well.

i915 can't handle this currently. So no, we don't want this.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC v2 1/7] drm/atomic: initial support for asynchronous plane update
  2017-04-28  8:57       ` Ville Syrjälä
@ 2017-04-28 14:04         ` Gustavo Padovan
  0 siblings, 0 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-28 14:04 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Gustavo Padovan, dri-devel, Daniel Vetter

Hi Ville,

2017-04-28 Ville Syrjälä <ville.syrjala@linux.intel.com>:

> On Thu, Apr 27, 2017 at 04:35:37PM -0300, Gustavo Padovan wrote:
> > Hi Ville,
> > 
> > 2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:
> > 
> > > On Thu, Apr 27, 2017 at 12:15:13PM -0300, 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 step in
> > > > drm_atomic_helper_commit().
> > > > 
> > > > We take this path for legacy cursor updates. Users can also set the
> > > > DRM_MODE_ATOMIC_ASYNC_UPDATE flag on atomic 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.
> > > > 
> > > > 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             | 50 ++++++++++++++++++++++++++++++++
> > > >  drivers/gpu/drm/drm_atomic_helper.c      | 48 ++++++++++++++++++++++++++++++
> > > >  include/drm/drm_atomic.h                 |  2 ++
> > > >  include/drm/drm_atomic_helper.h          |  2 ++
> > > >  include/drm/drm_modeset_helper_vtables.h | 45 ++++++++++++++++++++++++++++
> > > >  include/uapi/drm/drm_mode.h              |  4 ++-
> > > >  6 files changed, 150 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > > index 30229ab..7b60cf8 100644
> > > > --- a/drivers/gpu/drm/drm_atomic.c
> > > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > > @@ -77,6 +77,7 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
> > > >  	 * setting this appropriately?
> > > >  	 */
> > > >  	state->allow_modeset = true;
> > > > +	state->async_update = true;
> > > >  
> > > >  	state->crtcs = kcalloc(dev->mode_config.num_crtc,
> > > >  			       sizeof(*state->crtcs), GFP_KERNEL);
> > > > @@ -631,6 +632,51 @@ 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_plane *__plane, *plane = NULL;
> > > > +	struct drm_plane_state *__plane_state, *plane_state = NULL;
> > > > +	const struct drm_plane_helper_funcs *funcs;
> > > > +	int i, 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 single plane updates for now */
> > > > +	if (!plane || n_planes != 1)
> > > > +		return false;
> > > > +
> > > > +	funcs = plane->helper_private;
> > > > +	if (!funcs->atomic_async_update)
> > > > +		return false;
> > > > +
> > > > +	if (plane_state->fence)
> > > > +		return false;
> > > > +
> > > > +	if (!plane->state->crtc || (plane->state->crtc != plane_state->crtc))
> > > > +		return false;
> > > > +
> > > > +	/* No configuring new scaling in the async path. */
> > > 
> > > Those checks aren't really about scaling. Well, they are also about
> > > scaling, but they're mainly about changing size.
> > 
> > I just copied the comment from the previous code in the drivers...
> > I can fix it.
> > 
> > > 
> > > What I don't really understand is why we're enforcing these restrictions
> > > in the core but leaving other restrictions up to the driver. I don't see
> > > size changes as anything really special compared to many of the other
> > > restrictions that would now be up to each driver.
> > 
> > Because I extracted what was common between msm, vc4 and i915 on their
> > legacy cursor update calls. I didn't want to enforce anything else in
> > core for now.
> > 
> > > 
> > > If you're really after some lowest common denominator as far as
> > > exposed capabilities are concerned then I think the core should do
> > > more checking. OTOH if you're not interested limiting what each
> > > driver exposes then I don't see why the core checks anything at all.
> > 
> > I think a common denominator is what we want but we only have 3 drivers
> > using it at the moment. We can look for more checks that shoud be done
> > is core. Any suggestions?
> 
> My suggestion is that we should come up with some proper justification
> for the checks that are done by the core. Otherwise I think all the
> checks should be in the drivers because the drivers can actually
> justify them, or at least they should be able to.

I agree with you, we can't just mix these checks. I'll move the drivers
one and keep only the core ones here.

> 
> > 
> > > 
> > > > +	if (plane->state->crtc_w != plane_state->crtc_w ||
> > > > +	    plane->state->crtc_h != plane_state->crtc_h ||
> > > > +	    plane->state->src_w != plane_state->src_w ||
> > > > +	    plane->state->src_h != plane_state->src_h) {
> > > > +		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)
> > > >  {
> > > <snip> 
> > > >  /**
> > > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > > index 8c67fc0..7c067ca 100644
> > > > --- a/include/uapi/drm/drm_mode.h
> > > > +++ b/include/uapi/drm/drm_mode.h
> > > > @@ -646,13 +646,15 @@ struct drm_mode_destroy_dumb {
> > > >  #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
> > > >  #define DRM_MODE_ATOMIC_NONBLOCK  0x0200
> > > >  #define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
> > > > +#define DRM_MODE_ATOMIC_ASYNC_UPDATE 0x0800
> > > 
> > > What exactly is that flag supposed to mean?
> > 
> > I don't think I provided a good explanation for it, sorry. This flag
> > tells core to jump ahead the queued update if the conditions in 
> > drm_atomic_async_check() are met. Useful for cursors and async PageFlips
> > over the atomic ioctl.
> 
> IMO mixing nea uapi in this patch is a mistake. It should be separate
> and the intent of the new flag should be well documented.

Yes, a separated patch is a good idea.

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

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

* Re: [RFC v2 0/7] drm: asynchronous atomic plane update
  2017-04-28  8:53     ` Ville Syrjälä
@ 2017-04-28 14:28       ` Gustavo Padovan
  0 siblings, 0 replies; 22+ messages in thread
From: Gustavo Padovan @ 2017-04-28 14:28 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Gustavo Padovan, dri-devel

2017-04-28 Ville Syrjälä <ville.syrjala@linux.intel.com>:

> On Thu, Apr 27, 2017 at 03:36:50PM -0300, Gustavo Padovan wrote:
> > 2017-04-27 Ville Syrjälä <ville.syrjala@linux.intel.com>:
> > 
> > > On Thu, Apr 27, 2017 at 12:15:12PM -0300, Gustavo Padovan wrote:
> > > > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> > > > 
> > > > Hi,
> > > > 
> > > > Second take of Asynchronous Plane Updates over Atomic. Here I looked
> > > > to msm, vc4 and i915 to identify a common pattern to create atomic helpers
> > > > for async updates. So in patch 1 drm_atomic_async_check() and
> > > > drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
> > > > ->atomic_async_check() and ->atomic_async_commit().
> > > > 
> > > > For now we only support async update for one plane at a time. Also the async
> > > > update can't modify the CRTC so no modesets are allowed.
> > > > 
> > > > Then the other patches add support for it in the drivers. I did virtio mostly
> > > > for testing. i915 have been converted and I've been using it without any
> > > > problem. IGT tests seems to be fine, but there are somewhat random failures
> > > > with or without the async update changes. msm and vc4 are only compile-tested.
> > > > So I think this needs more testing
> > > > 
> > > > I started IGT changes to test the Atomic IOCTL with the new flag:
> > > > 
> > > > https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/
> > > > 
> > > > v2:
> > > > 
> > > > Apart from all comments on v1 one extra change I made was to remove the
> > > > constraint of only updating the plane if the queued state didn't touch
> > > > that plane. I believe it was a too cautious of a change, furthermore this
> > > > constraint was affecting throughput negatively on i915.
> > > 
> > > So you're now allowing reordering the updates? As in update A is
> > > scheduled before update B, but update B happens before update A.
> > > That is not a good idea.
> > 
> > That is what already happens with legacy cursor updates. They jump ahead
> > the scheduled update and apply the cursor update.
> 
> Well, that's clearly a bug then. They are supposed to be able to jump
> ahead of other planes, but not themselves.

Right, maybe I didn't checked this correctly. Removing that was a
mistake, I blame my lack of knowledge of such a big subsystem :)
I'll bring that code back.

> 
> I think the real problem is having just one timeline for the entire
> crtc. The proper solution would be to have a timeline for each plane.
> 
> > What we propose here
> > is to do this over atomic when DRM_MODE_ATOMIC_ASYNC_UPDATE flag is set.
> 
> The cursor thing is a hack. Using it as a guideline for something else
> is not a good idea IMO. Reordering, apart from being totally unexpected
> would also cause all sorts of problems because the hardware state at
> the time of the programming the hardware won't match what you checked
> against in your async check function.
> 
> > Async PageFlips should use the same infrastructure in the future.
> 
> I don't quite see why you have to build a parallel infrastructure for
> this stuff. If the driver would do things properly then it could just
> as well do this stuff from the normal path as well. So I figured the
> point of all this was just to unify the hacks to one place pretty much.
> Expanding the hacks to some kind of big infrastrucure is not something
> I'd do.

The issue I wanted to solve in the first place was to create a way to
update cursors over the atomic ioctl as fast (or relatively fast) as
the legacy update. Then discussing this with Daniel Vetter he suggested
to solve a bigger problem: add generic async plane update that would
benefit cursors, async PageFlips (vc4 already has it) and VR (but I
don't really know all the needs for VR).

Gustavo


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

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

* Re: [RFC v2 0/7] drm: asynchronous atomic plane update
  2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
                   ` (7 preceding siblings ...)
  2017-04-27 16:10 ` [RFC v2 0/7] drm: asynchronous atomic plane update Ville Syrjälä
@ 2017-05-09 14:02 ` Ville Syrjälä
  2017-05-11 19:29   ` Gustavo Padovan
  8 siblings, 1 reply; 22+ messages in thread
From: Ville Syrjälä @ 2017-05-09 14:02 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: Gustavo Padovan, dri-devel

On Thu, Apr 27, 2017 at 12:15:12PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.com>
> 
> Hi,
> 
> Second take of Asynchronous Plane Updates over Atomic. Here I looked
> to msm, vc4 and i915 to identify a common pattern to create atomic helpers
> for async updates. So in patch 1 drm_atomic_async_check() and
> drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
> ->atomic_async_check() and ->atomic_async_commit().
> 
> For now we only support async update for one plane at a time. Also the async
> update can't modify the CRTC so no modesets are allowed.
> 
> Then the other patches add support for it in the drivers. I did virtio mostly
> for testing. i915 have been converted and I've been using it without any
> problem. IGT tests seems to be fine, but there are somewhat random failures
> with or without the async update changes. msm and vc4 are only compile-tested.
> So I think this needs more testing
> 
> I started IGT changes to test the Atomic IOCTL with the new flag:
> 
> https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/

BTW I also realized recently that this is probably not going to work
w.r.t. per-crtc out fences. I know we agrees earlier that the
"return -1" trick would work, but now that I think about it again,
I don't think it actually will work when combined with non-blocking
commits since we can't decide whether to return -1 or a fence
until the commit has actually been performed.

> 
> v2:
> 
> Apart from all comments on v1 one extra change I made was to remove the
> constraint of only updating the plane if the queued state didn't touch
> that plane. I believe it was a too cautious of a change, furthermore this
> constraint was affecting throughput negatively on i915.
> 
> TODO
> 
>  - improve i-g-t tests where needed
>  - support async page flips (that can be done after uptreaming this part)
>  - figure out what to do for hw that do not update the plane until the next
>  vblank. Maybe wait and see what they do and them extract helpers?
> 
> Comments are welcome!
> 
> Gustavo Padovan (7):
>   drm/atomic: initial support for asynchronous plane update
>   drm/virtio: support async cursor updates
>   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              |  50 ++++++++++
>  drivers/gpu/drm/drm_atomic_helper.c       |  48 +++++++++
>  drivers/gpu/drm/i915/intel_atomic_plane.c |  52 ++++++++++
>  drivers/gpu/drm/i915/intel_display.c      | 158 ++++-------------------------
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 161 ++++++++++--------------------
>  drivers/gpu/drm/vc4/vc4_plane.c           |  94 +++++------------
>  drivers/gpu/drm/virtio/virtgpu_plane.c    |  42 ++++++++
>  include/drm/drm_atomic.h                  |   2 +
>  include/drm/drm_atomic_helper.h           |   2 +
>  include/drm/drm_modeset_helper_vtables.h  |  45 +++++++++
>  include/uapi/drm/drm_mode.h               |   4 +-
>  11 files changed, 343 insertions(+), 315 deletions(-)
> 
> -- 
> 2.9.3
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC v2 0/7] drm: asynchronous atomic plane update
  2017-05-09 14:02 ` Ville Syrjälä
@ 2017-05-11 19:29   ` Gustavo Padovan
  2017-05-12  9:04     ` Ville Syrjälä
  0 siblings, 1 reply; 22+ messages in thread
From: Gustavo Padovan @ 2017-05-11 19:29 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Gustavo Padovan, dri-devel

2017-05-09 Ville Syrjälä <ville.syrjala@linux.intel.com>:

> On Thu, Apr 27, 2017 at 12:15:12PM -0300, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> > 
> > Hi,
> > 
> > Second take of Asynchronous Plane Updates over Atomic. Here I looked
> > to msm, vc4 and i915 to identify a common pattern to create atomic helpers
> > for async updates. So in patch 1 drm_atomic_async_check() and
> > drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
> > ->atomic_async_check() and ->atomic_async_commit().
> > 
> > For now we only support async update for one plane at a time. Also the async
> > update can't modify the CRTC so no modesets are allowed.
> > 
> > Then the other patches add support for it in the drivers. I did virtio mostly
> > for testing. i915 have been converted and I've been using it without any
> > problem. IGT tests seems to be fine, but there are somewhat random failures
> > with or without the async update changes. msm and vc4 are only compile-tested.
> > So I think this needs more testing
> > 
> > I started IGT changes to test the Atomic IOCTL with the new flag:
> > 
> > https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/
> 
> BTW I also realized recently that this is probably not going to work
> w.r.t. per-crtc out fences. I know we agrees earlier that the
> "return -1" trick would work, but now that I think about it again,
> I don't think it actually will work when combined with non-blocking
> commits since we can't decide whether to return -1 or a fence
> until the commit has actually been performed.

What we agreed wasn't that the 1st request was going to return the
out-fence and the subsequent requests modifying that request would
return -1. How does that change with non-blocking?

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

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

* Re: [RFC v2 0/7] drm: asynchronous atomic plane update
  2017-05-11 19:29   ` Gustavo Padovan
@ 2017-05-12  9:04     ` Ville Syrjälä
  0 siblings, 0 replies; 22+ messages in thread
From: Ville Syrjälä @ 2017-05-12  9:04 UTC (permalink / raw)
  To: Gustavo Padovan, dri-devel, Gustavo Padovan

On Thu, May 11, 2017 at 04:29:56PM -0300, Gustavo Padovan wrote:
> 2017-05-09 Ville Syrjälä <ville.syrjala@linux.intel.com>:
> 
> > On Thu, Apr 27, 2017 at 12:15:12PM -0300, Gustavo Padovan wrote:
> > > From: Gustavo Padovan <gustavo.padovan@collabora.com>
> > > 
> > > Hi,
> > > 
> > > Second take of Asynchronous Plane Updates over Atomic. Here I looked
> > > to msm, vc4 and i915 to identify a common pattern to create atomic helpers
> > > for async updates. So in patch 1 drm_atomic_async_check() and
> > > drm_atomic_helper_async_commit() are introduced along with driver's plane hooks:
> > > ->atomic_async_check() and ->atomic_async_commit().
> > > 
> > > For now we only support async update for one plane at a time. Also the async
> > > update can't modify the CRTC so no modesets are allowed.
> > > 
> > > Then the other patches add support for it in the drivers. I did virtio mostly
> > > for testing. i915 have been converted and I've been using it without any
> > > problem. IGT tests seems to be fine, but there are somewhat random failures
> > > with or without the async update changes. msm and vc4 are only compile-tested.
> > > So I think this needs more testing
> > > 
> > > I started IGT changes to test the Atomic IOCTL with the new flag:
> > > 
> > > https://git.collabora.com/cgit/user/padovan/intel-gpu-tools.git/
> > 
> > BTW I also realized recently that this is probably not going to work
> > w.r.t. per-crtc out fences. I know we agrees earlier that the
> > "return -1" trick would work, but now that I think about it again,
> > I don't think it actually will work when combined with non-blocking
> > commits since we can't decide whether to return -1 or a fence
> > until the commit has actually been performed.
> 
> What we agreed wasn't that the 1st request was going to return the

I presume you meant "was"

> out-fence and the subsequent requests modifying that request would
> return -1. How does that change with non-blocking?

With non-blocking the commit happens after the ioctl has returned to
userspace, so it's too late to return the -1.

I suppose one option would be to avoid in fences altogether. So we'd
do the synchronization in userspace, and then do a blocking commit
without in fences to get the out fence. But that would open the
thing up to more scheduling latencies and whatnot since userspace
would have to be involved more.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2017-05-12  9:04 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-27 15:15 [RFC v2 0/7] drm: asynchronous atomic plane update Gustavo Padovan
2017-04-27 15:15 ` [RFC v2 1/7] drm/atomic: initial support for asynchronous " Gustavo Padovan
2017-04-27 15:37   ` Ville Syrjälä
2017-04-27 19:35     ` Gustavo Padovan
2017-04-28  8:57       ` Ville Syrjälä
2017-04-28 14:04         ` Gustavo Padovan
2017-04-27 15:15 ` [RFC v2 2/7] drm/virtio: support async cursor updates Gustavo Padovan
2017-04-27 15:15 ` [RFC v2 3/7] drm/i915: update cursors asynchronously through atomic Gustavo Padovan
2017-04-27 15:41   ` Ville Syrjälä
2017-04-27 19:39     ` Gustavo Padovan
2017-04-28  8:58       ` Ville Syrjälä
2017-04-27 15:15 ` [RFC v2 4/7] drm/i915: remove intel_cursor_plane_funcs Gustavo Padovan
2017-04-27 15:15 ` [RFC v2 5/7] drm/msm: update cursors asynchronously through atomic Gustavo Padovan
2017-04-27 15:15 ` [RFC v2 6/7] drm/msm: remove mdp5_cursor_plane_funcs Gustavo Padovan
2017-04-27 15:15 ` [RFC v2 7/7] drm/vc4: update cursors asynchronously through atomic Gustavo Padovan
2017-04-27 16:10 ` [RFC v2 0/7] drm: asynchronous atomic plane update Ville Syrjälä
2017-04-27 18:36   ` Gustavo Padovan
2017-04-28  8:53     ` Ville Syrjälä
2017-04-28 14:28       ` Gustavo Padovan
2017-05-09 14:02 ` Ville Syrjälä
2017-05-11 19:29   ` Gustavo Padovan
2017-05-12  9:04     ` Ville Syrjälä

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.