[Intel-gfx] [PATCHv2 2/5] drm/i915/skl: Add blend_func to SKL/BXT sprite planes
From: Damien LespiauThis patch adds the blend functions, and as per the blend function, updates the plane control register values V2: Add blend support for all RGB formats Fix the reg writes on plane_ctl_alpha bits. V3: Add support support for primary and cursor planes. fix an issue where the previous value was not retained, change the logic to do so. Signed-off-by: Damien Lespiau Signed-off-by: vandita kulkarni --- drivers/gpu/drm/i915/intel_display.c | 121 +-- drivers/gpu/drm/i915/intel_drv.h | 14 +++- drivers/gpu/drm/i915/intel_sprite.c | 6 +- 3 files changed, 133 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c5b9687..037407f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2921,8 +2921,29 @@ static void skl_detach_scalers(struct intel_crtc *intel_crtc) } } -u32 skl_plane_ctl_format(uint32_t pixel_format) +u32 skl_plane_ctl_format(uint32_t pixel_format, + enum per_pixel_alpha_state alpha) { + u32 plane_ctl_alpha = 0; + + if (pixel_format == DRM_FORMAT_ABGR || + pixel_format == DRM_FORMAT_ARGB) { + + switch (alpha) { + case DROP_ALPHA: + plane_ctl_alpha = PLANE_CTL_ALPHA_DISABLE; + break; + case PRE_MULTIPLIED_ALPHA: + plane_ctl_alpha = PLANE_CTL_ALPHA_SW_PREMULTIPLY; + break; + case NON_PRE_MULTIPLIED_ALPHA: + plane_ctl_alpha = PLANE_CTL_ALPHA_HW_PREMULTIPLY; + break; + default: + MISSING_CASE(alpha); + } + } + switch (pixel_format) { case DRM_FORMAT_C8: return PLANE_CTL_FORMAT_INDEXED; @@ -2938,11 +2959,11 @@ u32 skl_plane_ctl_format(uint32_t pixel_format) * DRM_FORMAT) for user-space to configure that. */ case DRM_FORMAT_ABGR: - return PLANE_CTL_FORMAT_XRGB_ | PLANE_CTL_ORDER_RGBX | - PLANE_CTL_ALPHA_SW_PREMULTIPLY; + return ((PLANE_CTL_FORMAT_XRGB_ | (PLANE_CTL_ORDER_RGBX + & (~PLANE_CTL_ALPHA_MASK))) | plane_ctl_alpha); case DRM_FORMAT_ARGB: - return PLANE_CTL_FORMAT_XRGB_ | - PLANE_CTL_ALPHA_SW_PREMULTIPLY; + return ((PLANE_CTL_FORMAT_XRGB_ & ~PLANE_CTL_ALPHA_MASK) + | plane_ctl_alpha); case DRM_FORMAT_XRGB2101010: return PLANE_CTL_FORMAT_XRGB_2101010; case DRM_FORMAT_XBGR2101010: @@ -3031,7 +3052,8 @@ static void skylake_update_primary_plane(struct drm_plane *plane, PLANE_CTL_PIPE_GAMMA_ENABLE | PLANE_CTL_PIPE_CSC_ENABLE; - plane_ctl |= skl_plane_ctl_format(fb->pixel_format); + plane_ctl |= skl_plane_ctl_format(fb->pixel_format, + plane_state->per_pixel_alpha); plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]); plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; plane_ctl |= skl_plane_ctl_rotation(rotation); @@ -3087,6 +3109,69 @@ static void skylake_update_primary_plane(struct drm_plane *plane, POSTING_READ(PLANE_SURF(pipe, 0)); } +static int intel_plane_state_check_blend(struct drm_plane_state *plane_state) +{ + struct drm_device *dev = plane_state->state->dev; + struct intel_plane_state *state = to_intel_plane_state(plane_state); + const struct drm_framebuffer *fb = plane_state->fb; + const struct drm_blend_mode *mode = >base.blend_mode; + bool has_per_pixel_blending; + + /* +* We don't install the properties pre-SKL, so this is SKL+ specific +* code for now. +*/ + if (INTEL_INFO(dev)->gen < 9) + return 0; + + if (!fb) + return 0; + + has_per_pixel_blending = fb->pixel_format == DRM_FORMAT_ABGR || + fb->pixel_format == DRM_FORMAT_RGBA || + fb->pixel_format == DRM_FORMAT_ARGB || + fb->pixel_format == DRM_FORMAT_BGRA; + + /* drop alpha for all fbs without an alpha channel */ + if (!has_per_pixel_blending) + state->per_pixel_alpha = DROP_ALPHA; + + switch (mode->func) { + /* +* The 'AUTO' behaviour is the default and keeps compatibility with +* kernels before the introduction of the blend_func property: +* - pre-multiplied alpha if the fb has an alpha channel +* - usual DRM_BLEND_FUNC(ONE, ZERO) otherwise +*/ + case
[Intel-gfx] [PATCHv2 2/5] drm/i915/skl: Add blend_func to SKL/BXT sprite planes
From: Damien LespiauThis patch adds the blend functions, and as per the blend function, updates the plane control register values V2: Add blend support for all RGB formats Fix the reg writes on plane_ctl_alpha bits. V3: Add support support for primary and cursor planes. fix an issue where the previous value was not retained, change the logic to do so. Signed-off-by: Damien Lespiau Signed-off-by: vandita kulkarni --- drivers/gpu/drm/i915/intel_display.c | 121 +-- drivers/gpu/drm/i915/intel_drv.h | 14 +++- drivers/gpu/drm/i915/intel_sprite.c | 6 +- 3 files changed, 133 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c5b9687..037407f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2921,8 +2921,29 @@ static void skl_detach_scalers(struct intel_crtc *intel_crtc) } } -u32 skl_plane_ctl_format(uint32_t pixel_format) +u32 skl_plane_ctl_format(uint32_t pixel_format, + enum per_pixel_alpha_state alpha) { + u32 plane_ctl_alpha = 0; + + if (pixel_format == DRM_FORMAT_ABGR || + pixel_format == DRM_FORMAT_ARGB) { + + switch (alpha) { + case DROP_ALPHA: + plane_ctl_alpha = PLANE_CTL_ALPHA_DISABLE; + break; + case PRE_MULTIPLIED_ALPHA: + plane_ctl_alpha = PLANE_CTL_ALPHA_SW_PREMULTIPLY; + break; + case NON_PRE_MULTIPLIED_ALPHA: + plane_ctl_alpha = PLANE_CTL_ALPHA_HW_PREMULTIPLY; + break; + default: + MISSING_CASE(alpha); + } + } + switch (pixel_format) { case DRM_FORMAT_C8: return PLANE_CTL_FORMAT_INDEXED; @@ -2938,11 +2959,11 @@ u32 skl_plane_ctl_format(uint32_t pixel_format) * DRM_FORMAT) for user-space to configure that. */ case DRM_FORMAT_ABGR: - return PLANE_CTL_FORMAT_XRGB_ | PLANE_CTL_ORDER_RGBX | - PLANE_CTL_ALPHA_SW_PREMULTIPLY; + return ((PLANE_CTL_FORMAT_XRGB_ | (PLANE_CTL_ORDER_RGBX + & (~PLANE_CTL_ALPHA_MASK))) | plane_ctl_alpha); case DRM_FORMAT_ARGB: - return PLANE_CTL_FORMAT_XRGB_ | - PLANE_CTL_ALPHA_SW_PREMULTIPLY; + return ((PLANE_CTL_FORMAT_XRGB_ & ~PLANE_CTL_ALPHA_MASK) + | plane_ctl_alpha); case DRM_FORMAT_XRGB2101010: return PLANE_CTL_FORMAT_XRGB_2101010; case DRM_FORMAT_XBGR2101010: @@ -3031,7 +3052,8 @@ static void skylake_update_primary_plane(struct drm_plane *plane, PLANE_CTL_PIPE_GAMMA_ENABLE | PLANE_CTL_PIPE_CSC_ENABLE; - plane_ctl |= skl_plane_ctl_format(fb->pixel_format); + plane_ctl |= skl_plane_ctl_format(fb->pixel_format, + plane_state->per_pixel_alpha); plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]); plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; plane_ctl |= skl_plane_ctl_rotation(rotation); @@ -3087,6 +3109,69 @@ static void skylake_update_primary_plane(struct drm_plane *plane, POSTING_READ(PLANE_SURF(pipe, 0)); } +static int intel_plane_state_check_blend(struct drm_plane_state *plane_state) +{ + struct drm_device *dev = plane_state->state->dev; + struct intel_plane_state *state = to_intel_plane_state(plane_state); + const struct drm_framebuffer *fb = plane_state->fb; + const struct drm_blend_mode *mode = >base.blend_mode; + bool has_per_pixel_blending; + + /* +* We don't install the properties pre-SKL, so this is SKL+ specific +* code for now. +*/ + if (INTEL_INFO(dev)->gen < 9) + return 0; + + if (!fb) + return 0; + + has_per_pixel_blending = fb->pixel_format == DRM_FORMAT_ABGR || + fb->pixel_format == DRM_FORMAT_RGBA || + fb->pixel_format == DRM_FORMAT_ARGB || + fb->pixel_format == DRM_FORMAT_BGRA; + + /* drop alpha for all fbs without an alpha channel */ + if (!has_per_pixel_blending) + state->per_pixel_alpha = DROP_ALPHA; + + switch (mode->func) { + /* +* The 'AUTO' behaviour is the default and keeps compatibility with +* kernels before the introduction of the blend_func property: +* - pre-multiplied alpha if the fb has an alpha channel +* - usual DRM_BLEND_FUNC(ONE, ZERO) otherwise +*/ + case