All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane
@ 2021-09-29 19:06 Simon Ser
  2021-09-29 19:06 ` [PATCH v3 2/2] amd/display: only require overlay plane to cover whole CRTC on ChromeOS Simon Ser
  2021-10-05 17:45 ` [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane Harry Wentland
  0 siblings, 2 replies; 5+ messages in thread
From: Simon Ser @ 2021-09-29 19:06 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Harry Wentland, Nicholas Kazlauskas, Bas Nieuwenhuizen

The current logic checks whether the cursor plane blending
properties match the primary plane's. However that's wrong,
because the cursor is painted on all planes underneath. If
the cursor is over the primary plane and the cursor plane,
it's painted on both pipes.

Iterate over the CRTC planes and check their scaling match
the cursor's.

Signed-off-by: Simon Ser <contact@emersion.fr>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Harry Wentland <hwentlan@amd.com>
Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 49 +++++++++++++------
 1 file changed, 34 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 3c7a8f869b40..6472c0032b54 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10505,18 +10505,18 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
 				struct drm_crtc *crtc,
 				struct drm_crtc_state *new_crtc_state)
 {
-	struct drm_plane_state *new_cursor_state, *new_primary_state;
-	int cursor_scale_w, cursor_scale_h, primary_scale_w, primary_scale_h;
+	struct drm_plane *cursor = crtc->cursor, *underlying;
+	struct drm_plane_state *new_cursor_state, *new_underlying_state;
+	int i;
+	int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h;
 
 	/* On DCE and DCN there is no dedicated hardware cursor plane. We get a
 	 * cursor per pipe but it's going to inherit the scaling and
 	 * positioning from the underlying pipe. Check the cursor plane's
-	 * blending properties match the primary plane's. */
+	 * blending properties match the underlying planes'. */
 
-	new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
-	new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary);
-	if (!new_cursor_state || !new_primary_state ||
-	    !new_cursor_state->fb || !new_primary_state->fb) {
+	new_cursor_state = drm_atomic_get_new_plane_state(state, cursor);
+	if (!new_cursor_state || !new_cursor_state->fb) {
 		return 0;
 	}
 
@@ -10525,15 +10525,34 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
 	cursor_scale_h = new_cursor_state->crtc_h * 1000 /
 			 (new_cursor_state->src_h >> 16);
 
-	primary_scale_w = new_primary_state->crtc_w * 1000 /
-			 (new_primary_state->src_w >> 16);
-	primary_scale_h = new_primary_state->crtc_h * 1000 /
-			 (new_primary_state->src_h >> 16);
+	for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) {
+		/* Narrow down to non-cursor planes on the same CRTC as the cursor */
+		if (new_underlying_state->crtc != crtc || underlying == crtc->cursor)
+			continue;
 
-	if (cursor_scale_w != primary_scale_w ||
-	    cursor_scale_h != primary_scale_h) {
-		drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n");
-		return -EINVAL;
+		/* Ignore disabled planes */
+		if (!new_underlying_state->fb)
+			continue;
+
+		underlying_scale_w = new_underlying_state->crtc_w * 1000 /
+				     (new_underlying_state->src_w >> 16);
+		underlying_scale_h = new_underlying_state->crtc_h * 1000 /
+				     (new_underlying_state->src_h >> 16);
+
+		if (cursor_scale_w != underlying_scale_w ||
+		    cursor_scale_h != underlying_scale_h) {
+			drm_dbg_atomic(crtc->dev,
+				       "Cursor [PLANE:%d:%s] scaling doesn't match underlying [PLANE:%d:%s]\n",
+				       cursor->base.id, cursor->name, underlying->base.id, underlying->name);
+			return -EINVAL;
+		}
+
+		/* If this plane covers the whole CRTC, no need to check planes underneath */
+		if (new_underlying_state->crtc_x <= 0 &&
+		    new_underlying_state->crtc_y <= 0 &&
+		    new_underlying_state->crtc_x + new_underlying_state->crtc_w >= new_crtc_state->mode.hdisplay &&
+		    new_underlying_state->crtc_y + new_underlying_state->crtc_h >= new_crtc_state->mode.vdisplay)
+			break;
 	}
 
 	return 0;
-- 
2.33.0



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

* [PATCH v3 2/2] amd/display: only require overlay plane to cover whole CRTC on ChromeOS
  2021-09-29 19:06 [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane Simon Ser
@ 2021-09-29 19:06 ` Simon Ser
  2021-10-05 17:45   ` Harry Wentland
  2021-10-05 17:45 ` [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane Harry Wentland
  1 sibling, 1 reply; 5+ messages in thread
From: Simon Ser @ 2021-09-29 19:06 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Harry Wentland, Nicholas Kazlauskas, Bas Nieuwenhuizen

Commit ddab8bd788f5 ("drm/amd/display: Fix two cursor duplication when
using overlay") changed the atomic validation code to forbid the
overlay plane from being used if it doesn't cover the whole CRTC. The
motivation is that ChromeOS uses the atomic API for everything except
the cursor plane (which uses the legacy API). Thus amdgpu must always
be prepared to enable/disable/move the cursor plane at any time without
failing (or else ChromeOS will trip over).

As discussed in [1], there's no reason why the ChromeOS limitation
should prevent other fully atomic users from taking advantage of the
overlay plane. Let's limit the check to ChromeOS.

[1]: https://lore.kernel.org/amd-gfx/JIQ_93_cHcshiIDsrMU1huBzx9P9LVQxucx8hQArpQu7Wk5DrCl_vTXj_Q20m_L-8C8A5dSpNcSJ8ehfcCrsQpfB5QG_Spn14EYkH9chtg0=@emersion.fr/

Signed-off-by: Simon Ser <contact@emersion.fr>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Harry Wentland <hwentlan@amd.com>
Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Fixes: ddab8bd788f5 ("drm/amd/display: Fix two cursor duplication when using overlay")
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6472c0032b54..f06d6e794721 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10590,6 +10590,10 @@ static int validate_overlay(struct drm_atomic_state *state)
 	struct drm_plane_state *new_plane_state;
 	struct drm_plane_state *primary_state, *overlay_state = NULL;
 
+	/* This is a workaround for ChromeOS only */
+	if (strcmp(current->comm, "chrome") != 0)
+		return 0;
+
 	/* Check if primary plane is contained inside overlay */
 	for_each_new_plane_in_state_reverse(state, plane, new_plane_state, i) {
 		if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
-- 
2.33.0



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

* Re: [PATCH v3 2/2] amd/display: only require overlay plane to cover whole CRTC on ChromeOS
  2021-09-29 19:06 ` [PATCH v3 2/2] amd/display: only require overlay plane to cover whole CRTC on ChromeOS Simon Ser
@ 2021-10-05 17:45   ` Harry Wentland
  2021-10-06 14:08     ` Simon Ser
  0 siblings, 1 reply; 5+ messages in thread
From: Harry Wentland @ 2021-10-05 17:45 UTC (permalink / raw)
  To: Simon Ser, amd-gfx
  Cc: Alex Deucher, Harry Wentland, Nicholas Kazlauskas, Bas Nieuwenhuizen



On 2021-09-29 15:06, Simon Ser wrote:
> Commit ddab8bd788f5 ("drm/amd/display: Fix two cursor duplication when
> using overlay") changed the atomic validation code to forbid the
> overlay plane from being used if it doesn't cover the whole CRTC. The
> motivation is that ChromeOS uses the atomic API for everything except
> the cursor plane (which uses the legacy API). Thus amdgpu must always
> be prepared to enable/disable/move the cursor plane at any time without
> failing (or else ChromeOS will trip over).
> 
> As discussed in [1], there's no reason why the ChromeOS limitation
> should prevent other fully atomic users from taking advantage of the
> overlay plane. Let's limit the check to ChromeOS.
> 
> [1]: https://lore.kernel.org/amd-gfx/JIQ_93_cHcshiIDsrMU1huBzx9P9LVQxucx8hQArpQu7Wk5DrCl_vTXj_Q20m_L-8C8A5dSpNcSJ8ehfcCrsQpfB5QG_Spn14EYkH9chtg0=@emersion.fr/>> 
> Signed-off-by: Simon Ser <contact@emersion.fr>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Harry Wentland <hwentlan@amd.com>
> Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Fixes: ddab8bd788f5 ("drm/amd/display: Fix two cursor duplication when using overlay")
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 6472c0032b54..f06d6e794721 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10590,6 +10590,10 @@ static int validate_overlay(struct drm_atomic_state *state)
>  	struct drm_plane_state *new_plane_state;
>  	struct drm_plane_state *primary_state, *overlay_state = NULL;
>  
> +	/* This is a workaround for ChromeOS only */
> +	if (strcmp(current->comm, "chrome") != 0)

current->comm is "DrmThread" on my ChromeOS system.

Harry

> +		return 0;
> +
>  	/* Check if primary plane is contained inside overlay */
>  	for_each_new_plane_in_state_reverse(state, plane, new_plane_state, i) {
>  		if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
> 


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

* Re: [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane
  2021-09-29 19:06 [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane Simon Ser
  2021-09-29 19:06 ` [PATCH v3 2/2] amd/display: only require overlay plane to cover whole CRTC on ChromeOS Simon Ser
@ 2021-10-05 17:45 ` Harry Wentland
  1 sibling, 0 replies; 5+ messages in thread
From: Harry Wentland @ 2021-10-05 17:45 UTC (permalink / raw)
  To: Simon Ser, amd-gfx
  Cc: Alex Deucher, Harry Wentland, Nicholas Kazlauskas, Bas Nieuwenhuizen



On 2021-09-29 15:06, Simon Ser wrote:
> The current logic checks whether the cursor plane blending
> properties match the primary plane's. However that's wrong,
> because the cursor is painted on all planes underneath. If
> the cursor is over the primary plane and the cursor plane,

Do you mean "and the underlay plane" here, instead of "and
the cursor plane"?

Harry

> it's painted on both pipes.
> 
> Iterate over the CRTC planes and check their scaling match
> the cursor's.
> 
> Signed-off-by: Simon Ser <contact@emersion.fr>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Harry Wentland <hwentlan@amd.com>
> Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 49 +++++++++++++------
>  1 file changed, 34 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 3c7a8f869b40..6472c0032b54 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10505,18 +10505,18 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
>  				struct drm_crtc *crtc,
>  				struct drm_crtc_state *new_crtc_state)
>  {
> -	struct drm_plane_state *new_cursor_state, *new_primary_state;
> -	int cursor_scale_w, cursor_scale_h, primary_scale_w, primary_scale_h;
> +	struct drm_plane *cursor = crtc->cursor, *underlying;
> +	struct drm_plane_state *new_cursor_state, *new_underlying_state;
> +	int i;
> +	int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h;
>  
>  	/* On DCE and DCN there is no dedicated hardware cursor plane. We get a
>  	 * cursor per pipe but it's going to inherit the scaling and
>  	 * positioning from the underlying pipe. Check the cursor plane's
> -	 * blending properties match the primary plane's. */
> +	 * blending properties match the underlying planes'. */
>  
> -	new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
> -	new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary);
> -	if (!new_cursor_state || !new_primary_state ||
> -	    !new_cursor_state->fb || !new_primary_state->fb) {
> +	new_cursor_state = drm_atomic_get_new_plane_state(state, cursor);
> +	if (!new_cursor_state || !new_cursor_state->fb) {
>  		return 0;
>  	}
>  
> @@ -10525,15 +10525,34 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
>  	cursor_scale_h = new_cursor_state->crtc_h * 1000 /
>  			 (new_cursor_state->src_h >> 16);
>  
> -	primary_scale_w = new_primary_state->crtc_w * 1000 /
> -			 (new_primary_state->src_w >> 16);
> -	primary_scale_h = new_primary_state->crtc_h * 1000 /
> -			 (new_primary_state->src_h >> 16);
> +	for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) {
> +		/* Narrow down to non-cursor planes on the same CRTC as the cursor */
> +		if (new_underlying_state->crtc != crtc || underlying == crtc->cursor)
> +			continue;
>  
> -	if (cursor_scale_w != primary_scale_w ||
> -	    cursor_scale_h != primary_scale_h) {
> -		drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n");
> -		return -EINVAL;
> +		/* Ignore disabled planes */
> +		if (!new_underlying_state->fb)
> +			continue;
> +
> +		underlying_scale_w = new_underlying_state->crtc_w * 1000 /
> +				     (new_underlying_state->src_w >> 16);
> +		underlying_scale_h = new_underlying_state->crtc_h * 1000 /
> +				     (new_underlying_state->src_h >> 16);
> +
> +		if (cursor_scale_w != underlying_scale_w ||
> +		    cursor_scale_h != underlying_scale_h) {
> +			drm_dbg_atomic(crtc->dev,
> +				       "Cursor [PLANE:%d:%s] scaling doesn't match underlying [PLANE:%d:%s]\n",
> +				       cursor->base.id, cursor->name, underlying->base.id, underlying->name);
> +			return -EINVAL;
> +		}
> +
> +		/* If this plane covers the whole CRTC, no need to check planes underneath */
> +		if (new_underlying_state->crtc_x <= 0 &&
> +		    new_underlying_state->crtc_y <= 0 &&
> +		    new_underlying_state->crtc_x + new_underlying_state->crtc_w >= new_crtc_state->mode.hdisplay &&
> +		    new_underlying_state->crtc_y + new_underlying_state->crtc_h >= new_crtc_state->mode.vdisplay)
> +			break;
>  	}
>  
>  	return 0;
> 


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

* Re: [PATCH v3 2/2] amd/display: only require overlay plane to cover whole CRTC on ChromeOS
  2021-10-05 17:45   ` Harry Wentland
@ 2021-10-06 14:08     ` Simon Ser
  0 siblings, 0 replies; 5+ messages in thread
From: Simon Ser @ 2021-10-06 14:08 UTC (permalink / raw)
  To: Harry Wentland
  Cc: amd-gfx, Alex Deucher, Harry Wentland, Nicholas Kazlauskas,
	Bas Nieuwenhuizen

> current->comm is "DrmThread" on my ChromeOS system.

Oops! I forgot that current->comm could be overwritten by user-space. Sent v4
which should address this by checking the executable name too.

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

end of thread, other threads:[~2021-10-06 14:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-29 19:06 [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane Simon Ser
2021-09-29 19:06 ` [PATCH v3 2/2] amd/display: only require overlay plane to cover whole CRTC on ChromeOS Simon Ser
2021-10-05 17:45   ` Harry Wentland
2021-10-06 14:08     ` Simon Ser
2021-10-05 17:45 ` [PATCH v3 1/2] amd/display: check cursor plane matches underlying plane Harry Wentland

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.