Re: [PATCH v2] drm/tegra: dc: Implement legacy blending

2017-12-22 Thread Dmitry Osipenko
On 21.12.2017 17:03, Thierry Reding wrote:
> From: Thierry Reding 
> 
> This implements alpha blending on legacy display controllers (Tegra20,
> Tegra30 and Tegra114). While it's theoretically possible to support the
> zpos property to enable userspace to specify the Z-order of each plane
> individually, this is not currently supported and the same fixed Z-
> order as previously defined is used.
> 
> Reverts commit 71835caa00e8 ("drm/tegra: fb: Force alpha formats") since
> the opaque formats are now supported.
> 
> Reported-by: Dmitry Osipenko 
> Fixes: 7772fdaef939 ("drm/tegra: Support ARGB and ABGR formats")
> Signed-off-by: Thierry Reding 
> ---
> Changes in v2:
> - properly implement blending if windows have different pixel formats
> 
>  drivers/gpu/drm/tegra/dc.c|  81 +
>  drivers/gpu/drm/tegra/dc.h|  12 
>  drivers/gpu/drm/tegra/fb.c|  12 
>  drivers/gpu/drm/tegra/plane.c | 138 
> ++
>  drivers/gpu/drm/tegra/plane.h |   8 +++
>  5 files changed, 226 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> index 2a0c1e93f82e..4507063029e0 100644
> --- a/drivers/gpu/drm/tegra/dc.c
> +++ b/drivers/gpu/drm/tegra/dc.c
> @@ -154,30 +154,53 @@ static inline u32 compute_initial_dda(unsigned int in)
>  
>  static void tegra_plane_setup_blending_legacy(struct tegra_plane *plane)
>  {
> + u32 background[3] = {
> + BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE,
> + BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE,
> + BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE,
> + };
> + u32 foreground = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255) |
> +  BLEND_COLOR_KEY_NONE;
> + u32 blendnokey = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255);
> + struct tegra_plane_state *state;
> + unsigned int i;
> +
> + state = to_tegra_plane_state(plane->base.state);
> +
> + /* alpha contribution is 1 minus sum of overlapping windows */
> + for (i = 0; i < 3; i++) {
> + if (state->dependent[i])
> + background[i] |= BLEND_CONTROL_DEPENDENT;
> + }
> +
> + /* enable alpha blending if pixel format has an alpha component */
> + if (!state->opaque)
> + foreground |= BLEND_CONTROL_ALPHA;
> +
>   /*
>* Disable blending and assume Window A is the bottom-most window,
>* Window C is the top-most window and Window B is in the middle.
>*/
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_NOKEY);
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_1WIN);
> + tegra_plane_writel(plane, blendnokey, DC_WIN_BLEND_NOKEY);
> + tegra_plane_writel(plane, foreground, DC_WIN_BLEND_1WIN);
>  
>   switch (plane->index) {
>   case 0:
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_X);
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_Y);
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_3WIN_XY);
> + tegra_plane_writel(plane, background[0], DC_WIN_BLEND_2WIN_X);
> + tegra_plane_writel(plane, background[1], DC_WIN_BLEND_2WIN_Y);
> + tegra_plane_writel(plane, background[2], DC_WIN_BLEND_3WIN_XY);
>   break;
>  
>   case 1:
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_X);
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_Y);
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_3WIN_XY);
> + tegra_plane_writel(plane, foreground, DC_WIN_BLEND_2WIN_X);
> + tegra_plane_writel(plane, background[1], DC_WIN_BLEND_2WIN_Y);
> + tegra_plane_writel(plane, background[2], DC_WIN_BLEND_3WIN_XY);
>   break;
>  
>   case 2:
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_X);
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_Y);
> - tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_3WIN_XY);
> + tegra_plane_writel(plane, foreground, DC_WIN_BLEND_2WIN_X);
> + tegra_plane_writel(plane, foreground, DC_WIN_BLEND_2WIN_Y);
> + tegra_plane_writel(plane, foreground, DC_WIN_BLEND_3WIN_XY);
>   break;
>   }
>  }
> @@ -353,6 +376,11 @@ static const u32 tegra20_primary_formats[] = {
>   DRM_FORMAT_RGBA5551,
>   DRM_FORMAT_ABGR,
>   DRM_FORMAT_ARGB,
> + /* non-native formats */
> + DRM_FORMAT_XRGB1555,
> + DRM_FORMAT_RGBX5551,
> + DRM_FORMAT_XBGR,
> + DRM_FORMAT_XRGB,
>  };
>  
>  static const u32 tegra114_primary_formats[] = {
> @@ -409,18 +437,40 @@ static int tegra_plane_atomic_check(struct drm_plane 
> *plane,
>   struct tegra_bo_tiling *tiling = _state->tiling;
>   struct tegra_plane *tegra = 

Re: [PATCH v2] drm/tegra: dc: Implement legacy blending

2017-12-22 Thread Dmitry Osipenko
On 21.12.2017 21:46, Dmitry Osipenko wrote:
> On 21.12.2017 17:03, Thierry Reding wrote:
>> From: Thierry Reding 
>>
>> This implements alpha blending on legacy display controllers (Tegra20,
>> Tegra30 and Tegra114). While it's theoretically possible to support the
>> zpos property to enable userspace to specify the Z-order of each plane
>> individually, this is not currently supported and the same fixed Z-
>> order as previously defined is used.
>>
>> Reverts commit 71835caa00e8 ("drm/tegra: fb: Force alpha formats") since
>> the opaque formats are now supported.
>>
>> Reported-by: Dmitry Osipenko 
>> Fixes: 7772fdaef939 ("drm/tegra: Support ARGB and ABGR formats")
>> Signed-off-by: Thierry Reding 
>> ---

[snip]

>> +
>> +void tegra_plane_check_dependent(struct tegra_plane *tegra,
>> + struct tegra_plane_state *state)
>> +{
>> +struct drm_plane_state *old, *new;
>> +struct drm_plane *plane;
>> +unsigned int zpos[2];
>> +unsigned int i;
>> +
>> +for (i = 0; i < 3; i++)
>> +state->dependent[i] = false;
>> +
>> +for (i = 0; i < 2; i++)
>> +zpos[i] = 0;
>> +
>> +for_each_oldnew_plane_in_state(state->base.state, plane, old, new, i) {
> 
> Somehow this works when 2 windows are blended (primary plane + cursor). But
> unfortunately this doesn't work at all in a case when 3 windows blended 
> (primary
> + video overlay + cursor), for some reason there is only one plane in the 
> state
> here, so blending dependency tracking doesn't work at all. I'll continue to 
> look
> into it, but for now I don't know why it doesn't work as expected. If you have
> any idea, please tell.

Actually, I think this code only works when all planes are updated in a single
commit. We need to handle cases when only some of the active planes are
adjusting the state.

[snip]
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/tegra: dc: Implement legacy blending

2017-12-21 Thread Thierry Reding
From: Thierry Reding 

This implements alpha blending on legacy display controllers (Tegra20,
Tegra30 and Tegra114). While it's theoretically possible to support the
zpos property to enable userspace to specify the Z-order of each plane
individually, this is not currently supported and the same fixed Z-
order as previously defined is used.

Reverts commit 71835caa00e8 ("drm/tegra: fb: Force alpha formats") since
the opaque formats are now supported.

Reported-by: Dmitry Osipenko 
Fixes: 7772fdaef939 ("drm/tegra: Support ARGB and ABGR formats")
Signed-off-by: Thierry Reding 
---
Changes in v2:
- properly implement blending if windows have different pixel formats

 drivers/gpu/drm/tegra/dc.c|  81 +
 drivers/gpu/drm/tegra/dc.h|  12 
 drivers/gpu/drm/tegra/fb.c|  12 
 drivers/gpu/drm/tegra/plane.c | 138 ++
 drivers/gpu/drm/tegra/plane.h |   8 +++
 5 files changed, 226 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 2a0c1e93f82e..4507063029e0 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -154,30 +154,53 @@ static inline u32 compute_initial_dda(unsigned int in)
 
 static void tegra_plane_setup_blending_legacy(struct tegra_plane *plane)
 {
+   u32 background[3] = {
+   BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE,
+   BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE,
+   BLEND_WEIGHT1(0) | BLEND_WEIGHT0(0) | BLEND_COLOR_KEY_NONE,
+   };
+   u32 foreground = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255) |
+BLEND_COLOR_KEY_NONE;
+   u32 blendnokey = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255);
+   struct tegra_plane_state *state;
+   unsigned int i;
+
+   state = to_tegra_plane_state(plane->base.state);
+
+   /* alpha contribution is 1 minus sum of overlapping windows */
+   for (i = 0; i < 3; i++) {
+   if (state->dependent[i])
+   background[i] |= BLEND_CONTROL_DEPENDENT;
+   }
+
+   /* enable alpha blending if pixel format has an alpha component */
+   if (!state->opaque)
+   foreground |= BLEND_CONTROL_ALPHA;
+
/*
 * Disable blending and assume Window A is the bottom-most window,
 * Window C is the top-most window and Window B is in the middle.
 */
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_NOKEY);
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_1WIN);
+   tegra_plane_writel(plane, blendnokey, DC_WIN_BLEND_NOKEY);
+   tegra_plane_writel(plane, foreground, DC_WIN_BLEND_1WIN);
 
switch (plane->index) {
case 0:
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_X);
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_Y);
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_3WIN_XY);
+   tegra_plane_writel(plane, background[0], DC_WIN_BLEND_2WIN_X);
+   tegra_plane_writel(plane, background[1], DC_WIN_BLEND_2WIN_Y);
+   tegra_plane_writel(plane, background[2], DC_WIN_BLEND_3WIN_XY);
break;
 
case 1:
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_X);
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_Y);
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_3WIN_XY);
+   tegra_plane_writel(plane, foreground, DC_WIN_BLEND_2WIN_X);
+   tegra_plane_writel(plane, background[1], DC_WIN_BLEND_2WIN_Y);
+   tegra_plane_writel(plane, background[2], DC_WIN_BLEND_3WIN_XY);
break;
 
case 2:
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_X);
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_2WIN_Y);
-   tegra_plane_writel(plane, 0x00, DC_WIN_BLEND_3WIN_XY);
+   tegra_plane_writel(plane, foreground, DC_WIN_BLEND_2WIN_X);
+   tegra_plane_writel(plane, foreground, DC_WIN_BLEND_2WIN_Y);
+   tegra_plane_writel(plane, foreground, DC_WIN_BLEND_3WIN_XY);
break;
}
 }
@@ -353,6 +376,11 @@ static const u32 tegra20_primary_formats[] = {
DRM_FORMAT_RGBA5551,
DRM_FORMAT_ABGR,
DRM_FORMAT_ARGB,
+   /* non-native formats */
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_RGBX5551,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_XRGB,
 };
 
 static const u32 tegra114_primary_formats[] = {
@@ -409,18 +437,40 @@ static int tegra_plane_atomic_check(struct drm_plane 
*plane,
struct tegra_bo_tiling *tiling = _state->tiling;
struct tegra_plane *tegra = to_tegra_plane(plane);
struct tegra_dc *dc = to_tegra_dc(state->crtc);
+   unsigned int format;
int err;
 
/* no need for