Add validation in atomic_check to ensure YUV formats are used with an active (non-bypassed) CSC colorop as the first colorop in the pipeline.
Update atomic_update to set the YUV conversion matrix based on the CSC colorop's color_encoding and color_range properties when using the color pipeline. Falls back to legacy COLOR_ENCODING/COLOR_RANGE plane properties when not using color pipeline. Co-developed by Claude Sonnet 4.5. Signed-off-by: Harry Wentland <[email protected]> --- drivers/gpu/drm/vkms/vkms_plane.c | 50 +++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index ca7aee101a95..0be6ec813b4c 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -6,10 +6,12 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> +#include <drm/drm_fixed.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_print.h> +#include <drm/drm_colorop.h> #include "vkms_drv.h" #include "vkms_formats.h" @@ -148,8 +150,27 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, frame_info->rotation = new_state->rotation; vkms_plane_state->pixel_read_line = get_pixel_read_line_function(fmt); - get_conversion_matrix_to_argb_u16(fmt, new_state->color_encoding, new_state->color_range, - &vkms_plane_state->conversion_matrix); + + if (!new_state->color_pipeline) { + get_conversion_matrix_to_argb_u16(fmt, new_state->color_encoding, + new_state->color_range, + &vkms_plane_state->conversion_matrix); + } else { + struct drm_colorop *colorop = new_state->color_pipeline; + struct drm_colorop_state *colorop_state = NULL; + + if (colorop && colorop->type == DRM_COLOROP_CSC) { + colorop_state = drm_atomic_get_new_colorop_state(state, + colorop); + } + + if (colorop_state && !colorop_state->bypass) { + get_conversion_matrix_to_argb_u16(fmt, + colorop_state->color_encoding, + colorop_state->color_range, + &vkms_plane_state->conversion_matrix); + } + } } static int vkms_plane_atomic_check(struct drm_plane *plane, @@ -175,6 +196,31 @@ static int vkms_plane_atomic_check(struct drm_plane *plane, if (ret != 0) return ret; + if (new_plane_state->color_pipeline) { + const struct drm_format_info *info = new_plane_state->fb->format; + + if (info->is_yuv) { + struct drm_colorop *colorop = new_plane_state->color_pipeline; + struct drm_colorop_state *colorop_state = NULL; + + if (!colorop || colorop->type != DRM_COLOROP_CSC) { + DRM_DEBUG_ATOMIC("YUV format requires CSC as first colorop\n"); + return -EINVAL; + } + + colorop_state = drm_atomic_get_new_colorop_state(state, colorop); + if (!colorop_state) { + DRM_DEBUG_ATOMIC("Failed to get CSC colorop state\n"); + return -EINVAL; + } + + if (colorop_state->bypass) { + DRM_DEBUG_ATOMIC("YUV format requires active CSC colorop (not bypassed)\n"); + return -EINVAL; + } + } + } + return 0; } -- 2.53.0
