Add CSC (Color Space Conversion) colorop as the first operation in the VKMS color pipeline. This colorop handles YUV-to-RGB conversion with support for BT.601, BT.709, and BT.2020 encoding standards and both limited and full range.
The CSC colorop supports bypass mode for RGB-only workflows. The actual YUV conversion is performed by the existing conversion_matrix path in the format reading functions, so the CSC colorop in the compositor is a no-op that just validates the configuration. Increase MAX_COLOR_PIPELINE_OPS from 4 to 5 to accommodate the new CSC colorop at the front of the pipeline. Co-developed by Claude Sonnet 4.5. Signed-off-by: Harry Wentland <[email protected]> --- drivers/gpu/drm/vkms/vkms_colorop.c | 64 +++++++++++++++++++--------- drivers/gpu/drm/vkms/vkms_composer.c | 5 +++ 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c b/drivers/gpu/drm/vkms/vkms_colorop.c index 071f3a8d2e7c..429491581008 100644 --- a/drivers/gpu/drm/vkms/vkms_colorop.c +++ b/drivers/gpu/drm/vkms/vkms_colorop.c @@ -16,7 +16,7 @@ static const struct drm_colorop_funcs vkms_colorop_funcs = { .destroy = drm_colorop_destroy, }; -#define MAX_COLOR_PIPELINE_OPS 4 +#define MAX_COLOR_PIPELINE_OPS 5 static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list) { @@ -27,7 +27,31 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr memset(ops, 0, sizeof(ops)); - /* 1st op: 1d curve */ + /* 1st op: CSC (YUV to RGB conversion) */ + ops[i] = kzalloc_obj(*ops[i]); + if (!ops[i]) { + drm_err(dev, "KMS: Failed to allocate colorop\n"); + ret = -ENOMEM; + goto cleanup; + } + + ret = drm_plane_colorop_csc_init(dev, ops[i], plane, &vkms_colorop_funcs, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709) | + BIT(DRM_COLOR_YCBCR_BT2020), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), + DRM_COLOR_YCBCR_BT709, + DRM_COLOR_YCBCR_LIMITED_RANGE, + DRM_COLOROP_FLAG_ALLOW_BYPASS); + if (ret) + goto cleanup; + + list->type = ops[i]->base.id; + + i++; + + /* 2nd op: 1d curve */ ops[i] = kzalloc_obj(*ops[i]); if (!ops[i]) { drm_err(dev, "KMS: Failed to allocate colorop\n"); @@ -41,23 +65,6 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr if (ret) goto cleanup; - list->type = ops[i]->base.id; - - i++; - - /* 2nd op: 3x4 matrix */ - ops[i] = kzalloc_obj(*ops[i]); - if (!ops[i]) { - drm_err(dev, "KMS: Failed to allocate colorop\n"); - ret = -ENOMEM; - goto cleanup; - } - - ret = drm_plane_colorop_ctm_3x4_init(dev, ops[i], plane, &vkms_colorop_funcs, - DRM_COLOROP_FLAG_ALLOW_BYPASS); - if (ret) - goto cleanup; - drm_colorop_set_next_property(ops[i - 1], ops[i]); i++; @@ -79,7 +86,24 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr i++; - /* 4th op: 1d curve */ + /* 4th op: 3x4 matrix */ + ops[i] = kzalloc_obj(*ops[i]); + if (!ops[i]) { + drm_err(dev, "KMS: Failed to allocate colorop\n"); + ret = -ENOMEM; + goto cleanup; + } + + ret = drm_plane_colorop_ctm_3x4_init(dev, ops[i], plane, &vkms_colorop_funcs, + DRM_COLOROP_FLAG_ALLOW_BYPASS); + if (ret) + goto cleanup; + + drm_colorop_set_next_property(ops[i - 1], ops[i]); + + i++; + + /* 5th op: 1d curve */ ops[i] = kzalloc_obj(*ops[i]); if (!ops[i]) { drm_err(dev, "KMS: Failed to allocate colorop\n"); diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index cd85de4ffd03..1c7dba35dc3f 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -15,6 +15,7 @@ #include <kunit/visibility.h> #include "vkms_composer.h" +#include "vkms_formats.h" #include "vkms_luts.h" static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha) @@ -187,6 +188,10 @@ static void apply_colorop(struct pixel_argb_s32 *pixel, struct drm_colorop *colo if (colorop_state->data) apply_3x4_matrix(pixel, (struct drm_color_ctm_3x4 *)colorop_state->data->data); + } else if (colorop->type == DRM_COLOROP_CSC) { + /* CSC conversion already handled by YUV read functions via conversion_matrix. + * By the time we reach this colorop, pixels are already in RGB. + */ } } -- 2.53.0
