Signed-off-by: Maarten Lankhorst <maarten.lankho...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |  2 +
 drivers/gpu/drm/i915/intel_display.c | 67 ++++++++++++++++++++--------
 drivers/gpu/drm/i915/intel_drv.h     |  2 +
 drivers/gpu/drm/i915/intel_fbc.c     |  4 ++
 drivers/gpu/drm/i915/intel_sprite.c  | 24 +++++++++-
 5 files changed, 79 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 327829cc61f8..23f0cb0fad0e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6425,8 +6425,10 @@ enum {
 #define _PLANE_KEYVAL_2_A                      0x70294
 #define _PLANE_KEYMSK_1_A                      0x70198
 #define _PLANE_KEYMSK_2_A                      0x70298
+#define  PLANE_KEYMSK_ALPHA_ENABLE             (1 << 31)
 #define _PLANE_KEYMAX_1_A                      0x701a0
 #define _PLANE_KEYMAX_2_A                      0x702a0
+#define  PLANE_KEYMAX_ALPHA_SHIFT              24
 #define _PLANE_AUX_DIST_1_A                    0x701c0
 #define _PLANE_AUX_DIST_2_A                    0x702c0
 #define _PLANE_AUX_OFFSET_1_A                  0x701c4
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index d48256f89a50..8ddff09c3110 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3170,6 +3170,21 @@ int skl_check_plane_surface(const struct 
intel_crtc_state *crtc_state,
                return -EINVAL;
        }
 
+       /* HW only has 8 bits pixel precision, disable plane if invisible */
+       if (!(plane_state->base.alpha >> 8)) {
+               plane_state->base.visible = false;
+               return 0;
+       }
+
+       if (plane_state->base.alpha < 0xff00) {
+               plane_state->flags |= PLANE_ALPHA_ENABLED;
+
+               /* FBC cannot be enabled with per pixel alpha */
+               if (plane_state->base.pixel_blend_mode != 
DRM_MODE_BLEND_PIXEL_NONE &&
+                   fb->format->has_alpha)
+                       plane_state->flags |= PLANE_ALPHA_NO_FBC;
+       }
+
        if (!plane_state->base.visible)
                return 0;
 
@@ -3496,30 +3511,39 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format)
        return 0;
 }
 
-/*
- * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
- * to be already pre-multiplied. We need to add a knob (or a different
- * DRM_FORMAT) for user-space to configure that.
- */
-static u32 skl_plane_ctl_alpha(uint32_t pixel_format)
+static u32 skl_plane_ctl_alpha(const struct intel_plane_state *plane_state)
 {
-       switch (pixel_format) {
-       case DRM_FORMAT_ABGR8888:
-       case DRM_FORMAT_ARGB8888:
+       if (!plane_state->base.fb->format->has_alpha)
+               return PLANE_CTL_ALPHA_DISABLE;
+
+       switch (plane_state->base.pixel_blend_mode) {
+       case DRM_MODE_BLEND_PIXEL_NONE:
+               return PLANE_CTL_ALPHA_DISABLE;
+       case DRM_MODE_BLEND_PREMULTI:
                return PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+       case DRM_MODE_BLEND_COVERAGE:
+               return PLANE_CTL_ALPHA_HW_PREMULTIPLY;
        default:
-               return PLANE_CTL_ALPHA_DISABLE;
+               MISSING_CASE(plane_state->base.pixel_blend_mode);
+               return 0;
        }
 }
 
-static u32 glk_plane_color_ctl_alpha(uint32_t pixel_format)
+static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state 
*plane_state)
 {
-       switch (pixel_format) {
-       case DRM_FORMAT_ABGR8888:
-       case DRM_FORMAT_ARGB8888:
+       if (!plane_state->base.fb->format->has_alpha)
+               return PLANE_COLOR_ALPHA_DISABLE;
+
+       switch (plane_state->base.pixel_blend_mode) {
+       case DRM_MODE_BLEND_PIXEL_NONE:
+               return PLANE_COLOR_ALPHA_DISABLE;
+       case DRM_MODE_BLEND_PREMULTI:
                return PLANE_COLOR_ALPHA_SW_PREMULTIPLY;
+       case DRM_MODE_BLEND_COVERAGE:
+               return PLANE_COLOR_ALPHA_HW_PREMULTIPLY;
        default:
-               return PLANE_COLOR_ALPHA_DISABLE;
+               MISSING_CASE(plane_state->base.pixel_blend_mode);
+               return 0;
        }
 }
 
@@ -3595,7 +3619,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state 
*crtc_state,
        plane_ctl = PLANE_CTL_ENABLE;
 
        if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) {
-               plane_ctl |= skl_plane_ctl_alpha(fb->format->format);
+               plane_ctl |= skl_plane_ctl_alpha(plane_state);
                plane_ctl |=
                        PLANE_CTL_PIPE_GAMMA_ENABLE |
                        PLANE_CTL_PIPE_CSC_ENABLE |
@@ -3637,7 +3661,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state 
*crtc_state,
                plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
        }
        plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
-       plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
+       plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
 
        if (intel_format_is_yuv(fb->format->format)) {
                if (fb->format->format == DRM_FORMAT_NV12) {
@@ -13623,7 +13647,7 @@ intel_primary_plane_create(struct drm_i915_private 
*dev_priv, enum pipe pipe)
                                                   DRM_MODE_ROTATE_0,
                                                   supported_rotations);
 
-       if (INTEL_GEN(dev_priv) >= 9)
+       if (INTEL_GEN(dev_priv) >= 9) {
                drm_plane_create_color_properties(&primary->base,
                                                  BIT(DRM_COLOR_YCBCR_BT601) |
                                                  BIT(DRM_COLOR_YCBCR_BT709),
@@ -13632,6 +13656,13 @@ intel_primary_plane_create(struct drm_i915_private 
*dev_priv, enum pipe pipe)
                                                  DRM_COLOR_YCBCR_BT709,
                                                  
DRM_COLOR_YCBCR_LIMITED_RANGE);
 
+               drm_plane_create_alpha_property(&primary->base);
+               drm_plane_create_blend_mode_property(&primary->base,
+                                                    
BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+                                                    
BIT(DRM_MODE_BLEND_PREMULTI) |
+                                                    
BIT(DRM_MODE_BLEND_COVERAGE));
+       }
+
        drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
 
        return primary;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2dc01be0c7cc..675dbe927a06 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -500,6 +500,8 @@ struct intel_plane_state {
        struct i915_vma *vma;
        unsigned long flags;
 #define PLANE_HAS_FENCE BIT(0)
+#define PLANE_ALPHA_ENABLED BIT(1)
+#define PLANE_ALPHA_NO_FBC BIT(2)
 
        struct {
                u32 offset;
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 1f2f41e67dcd..20a2dba78cad 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -732,6 +732,10 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
                fbc->no_fbc_reason = "framebuffer not tiled or fenced";
                return false;
        }
+       if (cache->flags & PLANE_ALPHA_NO_FBC) {
+               fbc->no_fbc_reason = "per pixel alpha blending enabled";
+               return false;
+       }
        if (INTEL_GEN(dev_priv) <= 4 && !IS_G4X(dev_priv) &&
            cache->plane.rotation != DRM_MODE_ROTATE_0) {
                fbc->no_fbc_reason = "rotation unsupported";
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 0b1bd5de5192..4fcc7ce09a9c 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -254,6 +254,7 @@ skl_update_plane(struct intel_plane *plane,
        uint32_t y = plane_state->main.y;
        uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
        uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
+       u32 keymsk = 0, keymax = 0;
 
        /* Sizes are 0 based */
        src_w--;
@@ -267,10 +268,20 @@ skl_update_plane(struct intel_plane *plane,
 
        if (key->flags) {
                I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
-               I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value);
-               I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), key->channel_mask);
+
+               keymax = key->max_value & 0xffffff;
+               keymsk |= key->channel_mask & 0x3ffffff;
        }
 
+       keymax |= (plane_state->base.alpha >> 8) << PLANE_KEYMAX_ALPHA_SHIFT;
+
+       if (plane_state->flags & PLANE_ALPHA_ENABLED ||
+           plane_state->base.fb->format->has_alpha)
+               keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
+
+       I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
+       I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
+
        I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
        I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
        I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
@@ -1525,6 +1536,15 @@ intel_sprite_plane_create(struct drm_i915_private 
*dev_priv,
                                          DRM_COLOR_YCBCR_BT709,
                                          DRM_COLOR_YCBCR_LIMITED_RANGE);
 
+       if (INTEL_GEN(dev_priv) >= 9) {
+               drm_plane_create_alpha_property(&intel_plane->base);
+
+               drm_plane_create_blend_mode_property(&intel_plane->base,
+                                                    
BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+                                                    
BIT(DRM_MODE_BLEND_PREMULTI) |
+                                                    
BIT(DRM_MODE_BLEND_COVERAGE));
+       }
+
        drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
 
        return intel_plane;
-- 
2.17.1

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

Reply via email to