Hi,
On 23.06.26 18:48, Harry Wentland wrote:
Insert a fixed matrix colorop as the first operation in the
VKMS color pipeline, before the existing 1D curve. This allows
userspace to select YUV-to-RGB conversion via the color pipeline
for YCbCr framebuffers.
The CSC Fixed Matrix colorop advertises support for all six
YUV-to-RGB conversion presets:
- YUV601/709/2020 full-range to RGB
- YUV601/709/2020 limited-range to RGB
Bump MAX_COLOR_PIPELINE_OPS from 4 to 5 to accommodate the new op.
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Harry Wentland <[email protected]>
Reviewed-by: Alex Hung <[email protected]>
---
drivers/gpu/drm/vkms/vkms_colorop.c | 66 ++++++++++++++++++++---------
1 file changed, 46 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c
b/drivers/gpu/drm/vkms/vkms_colorop.c
index 071f3a8d2e7c..9424b1994239 100644
--- a/drivers/gpu/drm/vkms/vkms_colorop.c
+++ b/drivers/gpu/drm/vkms/vkms_colorop.c
@@ -12,11 +12,19 @@ static const u64 supported_tfs =
BIT(DRM_COLOROP_1D_CURVE_SRGB_EOTF) |
BIT(DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF);
+static const u64 supported_fm =
+ BIT(DRM_COLOROP_FM_YCBCR601_FULL_RGB) |
+ BIT(DRM_COLOROP_FM_YCBCR601_LIMITED_RGB) |
+ BIT(DRM_COLOROP_FM_YCBCR709_FULL_RGB) |
+ BIT(DRM_COLOROP_FM_YCBCR709_LIMITED_RGB) |
+ BIT(DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB) |
+ BIT(DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB);
+
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 +35,25 @@ static int vkms_initialize_color_pipeline(struct drm_plane
*plane, struct drm_pr
memset(ops, 0, sizeof(ops));
- /* 1st op: 1d curve */
+ /* 1st op: Fixed Matrix (YUV to RGB) */
+ 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_fixed_matrix_init(dev, ops[i], plane,
&vkms_colorop_funcs,
+ supported_fm,
+
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 +67,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 +88,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");
LGTM.
Reviewed-by: Robert Mader <[email protected]>
--
Robert Mader
Consultant Software Developer
Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718