All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS
@ 2026-06-23 16:48 Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Harry Wentland
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx
  Cc: Harry Wentland, Alex Hung, Daniel Stone, Chaitanya Kumar Borah,
	Uma Shankar, Louis Chauvet, Melissa Wen, Simon Ser, Robert Mader

When we merged the drm_plane color pipeline API the major gap
that existed was the lack of a YUV to RGB conversion colorop.
We deprecated any legacy drm_plane color properties, which
means that the COLOR_RANGE and COLOR_ENCODING properties can't
be used with the COLOR_PIPELINE property on a drm_plane. In
practice this means that we can't use a COLOR_PIPELINE on
YCbCr encoded framebuffers.

This patchset expands on the Fixed Matrix colorop proposed by Chaitanya
and adds limited range variants of the YCbCr to RGB conversions.

His full patchset can be found at
https://patchwork.freedesktop.org/patch/709860

This code has been tested with IGT and an experimental KWin branch.

IGT branch:
https://gitlab.freedesktop.org/hwentland/igt-gpu-tools/-/tree/yuv-fm-colorop

KWin branch used for testing:
https://invent.kde.org/hwentlan/kwin/-/tree/yuv-fm-colorop

The kernel branch containing these changes, based on drm-misc-next
can be found at:
https://gitlab.freedesktop.org/hwentland/linux/-/tree/yuv-fm-colorop

Further background on this work can be found at:
https://hwentland.github.io/2026/03/10/plane-color-pipeline-csc-3d-lut-kwin.html

v3:
- base on Chaitanya's updated patch and rename code accordingly
  to Fixed_Matrix instead of CSC Fixed-Function

v2:
- use Chaitanya's CSC_FF block for named matrices

Cc: Alex Hung <alex.hung@amd.com>
Cc: Daniel Stone <daniels@collabora.com>
Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Louis Chauvet <louis.chauvet@bootlin.com>
Cc: Melissa Wen <mwen@igalia.com>
Cc: Simon Ser <contact@emersion.fr>
Cc: Robert Mader <robert.mader@collabora.com>

Chaitanya Kumar Borah (1):
  drm/colorop: Add DRM_COLOROP_FIXED_MATRIX

Harry Wentland (10):
  drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values
  drm/vkms: Add fixed matrix colorop to color pipeline
  drm/vkms: Add atomic check and matrix handling for fixed matrix
    colorop
  drm/amd/display: Add fixed matrix colorop to color pipeline
  drm/amd/display: Implement fixed matrix colorop color space mapping
  drm/amd/display: Use GAMCOR for first TF if YUV conversion is needed
  drm/amd/display: Check actual state during commit_tail
  drm/amd/display: Set color_space to plane_infos
  drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is
    bypassed
  drm/amd/display: Force GAMCOR for subsampled surfaces with
    PQ/Gamma22/HLG

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  14 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   |  91 +++++++++++++-
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c |  27 ++++-
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.h |   1 +
 .../amd/display/modules/color/color_gamma.c   |   3 +-
 drivers/gpu/drm/drm_atomic.c                  |   4 +
 drivers/gpu/drm/drm_atomic_uapi.c             |   4 +
 drivers/gpu/drm/drm_colorop.c                 | 109 +++++++++++++++++
 drivers/gpu/drm/vkms/vkms_colorop.c           |  66 +++++++---
 drivers/gpu/drm/vkms/vkms_composer.c          |   6 +
 drivers/gpu/drm/vkms/vkms_plane.c             |  68 ++++++++++-
 include/drm/drm_colorop.h                     | 114 ++++++++++++++++++
 include/uapi/drm/drm_mode.h                   |  12 ++
 13 files changed, 487 insertions(+), 32 deletions(-)

--
2.54.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-07-03 10:15   ` Robert Mader
  2026-07-03 10:52   ` Pekka Paalanen
  2026-06-23 16:48 ` [PATCH v3 02/11] drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values Harry Wentland
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Chaitanya Kumar Borah, Melissa Wen, Harry Wentland

From: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>

Introduce DRM_COLOROP_FIXED_MATRIX, a new colorop type representing a
hardware that performs a fixed matrix operation.

Unlike CTM-based colorops, this block does not expose programmable
coefficients. Instead, userspace selects one of the predefined
hardware modes via a new FIXED_MATRIX_TYPE enum property. Supported modes
include common YCbCr->RGB and RGB709->RGB2020 conversions.

v2:
 - Naming changes (Pekka)

v3:
 - Fix NC matrix enum name and string (Melissa)
 - Rebase

Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
---
 drivers/gpu/drm/drm_atomic.c      |   4 ++
 drivers/gpu/drm/drm_atomic_uapi.c |   4 ++
 drivers/gpu/drm/drm_colorop.c     | 106 ++++++++++++++++++++++++++++++
 include/drm/drm_colorop.h         |  84 +++++++++++++++++++++++
 include/uapi/drm/drm_mode.h       |  12 ++++
 5 files changed, 210 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3af1b9cc9a06..ced591c4a0bd 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -925,6 +925,10 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
 				  drm_get_colorop_lut3d_interpolation_name(colorop->lut3d_interpolation));
 		drm_printf_indent(p, 1, "data blob id=%d\n", state->data ? state->data->base.id : 0);
 		break;
+	case DRM_COLOROP_FIXED_MATRIX:
+		drm_printf_indent(p, 1, "fixed_matrix_type=%s\n",
+				  drm_get_colorop_fixed_matrix_type_name(state->fixed_matrix_type));
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index c7f80d90794c..cee4550ffdbd 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -761,6 +761,8 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
 	} else if (property == colorop->data_property) {
 		return drm_atomic_color_set_data_property(colorop, state,
 							  property, val);
+	} else if (property == colorop->fixed_matrix_type_property) {
+		state->fixed_matrix_type = val;
 	} else {
 		drm_dbg_atomic(colorop->dev,
 			       "[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
@@ -793,6 +795,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
 		*val = colorop->lut3d_interpolation;
 	else if (property == colorop->data_property)
 		*val = (state->data) ? state->data->base.id : 0;
+	else if (property == colorop->fixed_matrix_type_property)
+		*val = state->fixed_matrix_type;
 	else
 		return -EINVAL;
 
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index c0eecde8c176..c11c3012fcc5 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -68,6 +68,7 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = {
 	{ DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
 	{ DRM_COLOROP_MULTIPLIER, "Multiplier"},
 	{ DRM_COLOROP_3D_LUT, "3D LUT"},
+	{ DRM_COLOROP_FIXED_MATRIX, "Fixed Matrix"},
 };
 
 static const char * const colorop_curve_1d_type_names[] = {
@@ -90,6 +91,14 @@ static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] =
 	{ DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, "Tetrahedral" },
 };
 
+static const char * const colorop_fixed_matrix_type_names[] = {
+	[DRM_COLOROP_FM_YCBCR601_FULL_RGB] = "YCbCr 601 Full to RGB",
+	[DRM_COLOROP_FM_YCBCR709_FULL_RGB] = "YCbCr 709 Full to RGB",
+	[DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB] = "YCbCr 2020 NC Full to RGB",
+	[DRM_COLOROP_FM_YCBCR_LIMITED_FULL] = "YCbCr limited to full",
+	[DRM_COLOROP_FM_RGB709_RGB2020] = "RGB709 to RGB2020",
+};
+
 /* Init Helpers */
 
 static int drm_plane_colorop_init(struct drm_device *dev, struct drm_colorop *colorop,
@@ -455,6 +464,80 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
 }
 EXPORT_SYMBOL(drm_plane_colorop_3dlut_init);
 
+/**
+ * drm_plane_colorop_fixed_matrix_init - Initialize a DRM_COLOROP_FIXED_MATRIX
+ *
+ * @dev: DRM device
+ * @colorop: The drm_colorop object to initialize
+ * @plane: The associated drm_plane
+ * @funcs: control functions for the new colorop
+ * @supported_fm: A bitfield of supported drm_colorop_fixed_matrix_type enum values,
+ *               created using BIT(fixed_matrix_type) and combined with the OR '|'
+ *               operator.
+ * @flags: bitmask of misc, see DRM_COLOROP_FLAG_* defines.
+ * @return zero on success, -E value on failure
+ */
+int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
+					struct drm_plane *plane,
+					const struct drm_colorop_funcs *funcs,
+					u64 supported_fm, uint32_t flags)
+{
+	struct drm_prop_enum_list enum_list[DRM_COLOROP_FM_COUNT];
+	int i, len;
+	struct drm_property *prop;
+	int ret;
+
+	if (!supported_fm) {
+		drm_err(dev,
+			"No supported FM type op for new Fixed Matrix colorop on [PLANE:%d:%s]\n",
+			plane->base.id, plane->name);
+		return -EINVAL;
+	}
+
+	if ((supported_fm & -BIT(DRM_COLOROP_FM_COUNT)) != 0) {
+		drm_err(dev, "Unknown Fixed Matrix provided on [PLANE:%d:%s]\n",
+			plane->base.id, plane->name);
+		return -EINVAL;
+	}
+
+	ret = drm_plane_colorop_init(dev, colorop, plane, funcs, DRM_COLOROP_FIXED_MATRIX, flags);
+	if (ret)
+		return ret;
+
+	len = 0;
+	for (i = 0; i < DRM_COLOROP_FM_COUNT; i++) {
+		if ((supported_fm & BIT(i)) == 0)
+			continue;
+
+		enum_list[len].type = i;
+		enum_list[len].name = colorop_fixed_matrix_type_names[i];
+		len++;
+	}
+
+	if (WARN_ON(len <= 0))
+		return -EINVAL;
+
+	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "FIXED_MATRIX_TYPE",
+					enum_list, len);
+
+	if (!prop)
+		return -ENOMEM;
+
+	colorop->fixed_matrix_type_property = prop;
+	/*
+	 * Default to the first supported CSC mode as provided by the driver.
+	 * Intuitively this should be something that keeps the colorop in pixel bypass
+	 * mode but that is already handled via the standard colorop bypass
+	 * property.
+	 */
+	drm_object_attach_property(&colorop->base, colorop->fixed_matrix_type_property,
+				   enum_list[0].type);
+	drm_colorop_reset(colorop);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_plane_colorop_fixed_matrix_init);
+
 static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop,
 							struct drm_colorop_state *state)
 {
@@ -521,6 +604,13 @@ static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
 							   &val))
 			colorop_state->curve_1d_type = val;
 	}
+
+	if (colorop->fixed_matrix_type_property) {
+		if (!drm_object_property_get_default_value(&colorop->base,
+							   colorop->fixed_matrix_type_property,
+							   &val))
+			colorop_state->fixed_matrix_type = val;
+	}
 }
 
 /**
@@ -584,6 +674,7 @@ static const char * const colorop_type_name[] = {
 	[DRM_COLOROP_CTM_3X4] = "3x4 Matrix",
 	[DRM_COLOROP_MULTIPLIER] = "Multiplier",
 	[DRM_COLOROP_3D_LUT] = "3D LUT",
+	[DRM_COLOROP_FIXED_MATRIX] = "Fixed Matrix",
 };
 
 static const char * const colorop_lu3d_interpolation_name[] = {
@@ -640,6 +731,21 @@ const char *drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_inte
 	return colorop_lu3d_interpolation_name[type];
 }
 
+/**
+ * drm_get_colorop_fixed_matrix_type_name: return a string for fixed matrix type
+ * @type: fixed matrix type to compute name of
+ *
+ * In contrast to the other drm_get_*_name functions this one here returns a
+ * const pointer and hence is threadsafe.
+ */
+const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type)
+{
+	if (WARN_ON(type >= ARRAY_SIZE(colorop_fixed_matrix_type_names)))
+		return "unknown";
+
+	return colorop_fixed_matrix_type_names[type];
+}
+
 /**
  * drm_colorop_set_next_property - sets the next pointer
  * @colorop: drm colorop
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index b4b9e4f558ab..88933d5b4d8b 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -134,6 +134,71 @@ enum drm_colorop_curve_1d_type {
 	DRM_COLOROP_1D_CURVE_COUNT
 };
 
+/**
+ * enum drm_colorop_fixed_matrix_type - type of Fixed Matrix
+ *
+ * Describes a Fixed Matrix operation to be applied by the DRM_COLOROP_FIXED_MATRIX
+ */
+enum drm_colorop_fixed_matrix_type {
+	/**
+	 * @DRM_COLOROP_FM_YCBCR601_FULL_RGB:
+	 *
+	 * enum string "YCbCr 601 Full to RGB"
+	 *
+	 * This selects the matrix that converts full range YCbCr into RGB
+	 * according to the BT.601 coefficients.
+	 */
+	DRM_COLOROP_FM_YCBCR601_FULL_RGB,
+
+	/**
+	 * @DRM_COLOROP_FM_YCBCR709_FULL_RGB:
+	 *
+	 * enum string "YCbCr 709 Full to RGB"
+	 *
+	 * This selects the matrix that converts full range YCbCr into RGB
+	 * according to the BT.709 coefficients.
+	 */
+	DRM_COLOROP_FM_YCBCR709_FULL_RGB,
+
+	/**
+	 * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
+	 *
+	 * enum string "YCbCr 2020 NC Full to RGB"
+	 *
+	 * This selects the matrix that converts full range YCbCr into RGB
+	 * according to the BT.2020 non-constant luminance coefficients.
+	 */
+	DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB,
+
+	/**
+	 * @DRM_COLOROP_FM_YCBCR_LIMITED_FULL:
+	 *
+	 * enum string "YCbCr limited to full"
+	 *
+	 * This selects the matrix that converts limited range YCbCr into
+	 * full range YCbCr. Though not strictly a matrix operation but
+	 * can be represented as one.
+	 */
+	DRM_COLOROP_FM_YCBCR_LIMITED_FULL,
+
+	/**
+	 * @DRM_COLOROP_FM_RGB709_RGB2020:
+	 *
+	 * enum string "RGB709 to RGB2020"
+	 *
+	 * Selects the fixed-function CSC preset that converts RGB
+	 * (BT.709) colorimetry to RGB (BT.2020).
+	 */
+	DRM_COLOROP_FM_RGB709_RGB2020,
+
+	/**
+	 * @DRM_COLOROP_FM_COUNT:
+	 *
+	 * enum value denoting the size of the enum
+	 */
+	DRM_COLOROP_FM_COUNT
+};
+
 /**
  * struct drm_colorop_state - mutable colorop state
  */
@@ -183,6 +248,13 @@ struct drm_colorop_state {
 	 */
 	struct drm_property_blob *data;
 
+	/**
+	 * @fixed_matrix_type:
+	 *
+	 * Type of Fixed Matrix operation.
+	 */
+	enum drm_colorop_fixed_matrix_type fixed_matrix_type;
+
 	/** @state: backpointer to global drm_atomic_commit */
 	struct drm_atomic_commit *state;
 };
@@ -368,6 +440,13 @@ struct drm_colorop {
 	 */
 	struct drm_property *data_property;
 
+	/**
+	 * @fixed_matrix_type_property:
+	 *
+	 * Sub-type for DRM_COLOROP_FIXED_MATRIX type.
+	 */
+	struct drm_property *fixed_matrix_type_property;
+
 	/**
 	 * @next_property:
 	 *
@@ -424,6 +503,10 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
 				 uint32_t lut_size,
 				 enum drm_colorop_lut3d_interpolation_type interpolation,
 				 uint32_t flags);
+int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
+					struct drm_plane *plane,
+					const struct drm_colorop_funcs *funcs,
+					u64 supported_fm, uint32_t flags);
 
 struct drm_colorop_state *
 drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop);
@@ -482,6 +565,7 @@ drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_ty
 
 const char *
 drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type);
+const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type);
 
 void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next);
 
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 381a3e857d4e..bff6dba08d50 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -954,6 +954,18 @@ enum drm_colorop_type {
 	 *         color = lut3d[index]
 	 */
 	DRM_COLOROP_3D_LUT,
+
+	/**
+	 * @DRM_COLOROP_FIXED_MATRIX:
+	 *
+	 * enum string "Fixed Matrix"
+	 *
+	 * A Colorop block that performs a pre-defined matrix operation selected
+	 * via the FIXED_MATRIX_TYPE enum property. The driver advertises the supported
+	 * operations through this property.
+	 */
+	DRM_COLOROP_FIXED_MATRIX,
+
 };
 
 /**
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 02/11] drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-07-03 10:17   ` Robert Mader
  2026-06-23 16:48 ` [PATCH v3 03/11] drm/vkms: Add fixed matrix colorop to color pipeline Harry Wentland
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, Alex Hung

Add three new limited-range YUV-to-RGB conversion presets to the
Fixed Matrix colorop enum:

  - DRM_COLOROP_FM_YCBCR601_LIMITED_RGB
  - DRM_COLOROP_FM_YCBCR709_LIMITED_RGB
  - DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB

Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/drm_colorop.c |  3 +++
 include/drm/drm_colorop.h     | 30 ++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index c11c3012fcc5..9cf89153b365 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -93,8 +93,11 @@ static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] =
 
 static const char * const colorop_fixed_matrix_type_names[] = {
 	[DRM_COLOROP_FM_YCBCR601_FULL_RGB] = "YCbCr 601 Full to RGB",
+	[DRM_COLOROP_FM_YCBCR601_LIMITED_RGB] = "YCbCr 601 Limited to RGB",
 	[DRM_COLOROP_FM_YCBCR709_FULL_RGB] = "YCbCr 709 Full to RGB",
+	[DRM_COLOROP_FM_YCBCR709_LIMITED_RGB] = "YCbCr 709 Limited to RGB",
 	[DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB] = "YCbCr 2020 NC Full to RGB",
+	[DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB] = "YCbCr 2020 NC Limited to RGB",
 	[DRM_COLOROP_FM_YCBCR_LIMITED_FULL] = "YCbCr limited to full",
 	[DRM_COLOROP_FM_RGB709_RGB2020] = "RGB709 to RGB2020",
 };
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index 88933d5b4d8b..5c542c264a36 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -150,6 +150,16 @@ enum drm_colorop_fixed_matrix_type {
 	 */
 	DRM_COLOROP_FM_YCBCR601_FULL_RGB,
 
+	/**
+	 * @DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
+	 *
+	 * enum string "YCbCr 601 Limited to RGB"
+	 *
+	 * This selects the matrix that converts limited range YCbCr into RGB
+	 * according to the BT.601 coefficients.
+	 */
+	DRM_COLOROP_FM_YCBCR601_LIMITED_RGB,
+
 	/**
 	 * @DRM_COLOROP_FM_YCBCR709_FULL_RGB:
 	 *
@@ -160,6 +170,16 @@ enum drm_colorop_fixed_matrix_type {
 	 */
 	DRM_COLOROP_FM_YCBCR709_FULL_RGB,
 
+	/**
+	 * @DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
+	 *
+	 * enum string "YCbCr 709 Limited to RGB"
+	 *
+	 * This selects the matrix that converts limited range YCbCr into RGB
+	 * according to the BT.709 coefficients.
+	 */
+	DRM_COLOROP_FM_YCBCR709_LIMITED_RGB,
+
 	/**
 	 * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
 	 *
@@ -170,6 +190,16 @@ enum drm_colorop_fixed_matrix_type {
 	 */
 	DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB,
 
+	/**
+	 * @DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
+	 *
+	 * enum string "YCbCr 2020 NC Limited to RGB"
+	 *
+	 * This selects the matrix that converts limited range YCbCr into RGB
+	 * according to the BT.2020 non-constant luminance coefficients.
+	 */
+	DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB,
+
 	/**
 	 * @DRM_COLOROP_FM_YCBCR_LIMITED_FULL:
 	 *
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 03/11] drm/vkms: Add fixed matrix colorop to color pipeline
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 02/11] drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-07-03 10:24   ` Robert Mader
  2026-06-23 16:48 ` [PATCH v3 04/11] drm/vkms: Add atomic check and matrix handling for fixed matrix colorop Harry Wentland
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, Alex Hung

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 <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
---
 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");
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 04/11] drm/vkms: Add atomic check and matrix handling for fixed matrix colorop
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (2 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 03/11] drm/vkms: Add fixed matrix colorop to color pipeline Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-07-03 10:32   ` Robert Mader
  2026-06-23 16:48 ` [PATCH v3 05/11] drm/amd/display: Add fixed matrix colorop to color pipeline Harry Wentland
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, Alex Hung

In vkms_plane_atomic_check(), validate that when a color pipeline
is active and the framebuffer format is YUV:
  - The first colorop must be DRM_COLOROP_FIXED_MATRIX
  - The fixed matrix colorop must not be bypassed

In vkms_plane_atomic_update(), when a color pipeline is active,
read the fixed_matrix_type from the first colorop state and map
it to the appropriate (color_encoding, color_range) pair for the
existing get_conversion_matrix_to_argb_u16() function.

In apply_colorop(), add a no-op case for DRM_COLOROP_FIXED_MATRIX
since the actual YUV-to-RGB conversion is already performed at
format read time via the conversion matrix.

Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c |  6 +++
 drivers/gpu/drm/vkms/vkms_plane.c    | 68 +++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 83d217085ad0..899120cd07ac 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -187,6 +187,12 @@ 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_FIXED_MATRIX) {
+		/*
+		 * Fixed Matrix is a no-op here. YUV-to-RGB conversion
+		 * is handled at format read time via the
+		 * conversion_matrix set in vkms_plane_atomic_update().
+		 */
 	}
 }
 
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 68cb2a3335e6..4ef4cebe718b 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -6,6 +6,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_blend.h>
+#include <drm/drm_colorop.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
@@ -148,8 +149,56 @@ 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) {
+		struct drm_colorop *colorop = new_state->color_pipeline;
+		struct drm_colorop_state *colorop_state;
+
+		colorop_state = drm_atomic_get_new_colorop_state(state, colorop);
+
+		if (colorop_state && !colorop_state->bypass) {
+			enum drm_color_encoding encoding;
+			enum drm_color_range range;
+
+			switch (colorop_state->fixed_matrix_type) {
+			case DRM_COLOROP_FM_YCBCR601_FULL_RGB:
+				encoding = DRM_COLOR_YCBCR_BT601;
+				range = DRM_COLOR_YCBCR_FULL_RANGE;
+				break;
+			case DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
+				encoding = DRM_COLOR_YCBCR_BT601;
+				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
+				break;
+			case DRM_COLOROP_FM_YCBCR709_FULL_RGB:
+				encoding = DRM_COLOR_YCBCR_BT709;
+				range = DRM_COLOR_YCBCR_FULL_RANGE;
+				break;
+			case DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
+				encoding = DRM_COLOR_YCBCR_BT709;
+				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
+				break;
+			case DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
+				encoding = DRM_COLOR_YCBCR_BT2020;
+				range = DRM_COLOR_YCBCR_FULL_RANGE;
+				break;
+			case DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
+				encoding = DRM_COLOR_YCBCR_BT2020;
+				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
+				break;
+			default:
+				encoding = DRM_COLOR_YCBCR_BT709;
+				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
+				break;
+			}
+
+			get_conversion_matrix_to_argb_u16(fmt, encoding, range,
+							  &vkms_plane_state->conversion_matrix);
+		}
+	} else {
+		get_conversion_matrix_to_argb_u16(fmt, new_state->color_encoding,
+						  new_state->color_range,
+						  &vkms_plane_state->conversion_matrix);
+	}
 }
 
 static int vkms_plane_atomic_check(struct drm_plane *plane,
@@ -175,6 +224,21 @@ static int vkms_plane_atomic_check(struct drm_plane *plane,
 	if (ret != 0)
 		return ret;
 
+	if (new_plane_state->color_pipeline && new_plane_state->fb->format->is_yuv) {
+		struct drm_colorop *colorop = new_plane_state->color_pipeline;
+		struct drm_colorop_state *colorop_state;
+		if (colorop->type != DRM_COLOROP_FIXED_MATRIX)
+
+			return -EINVAL;
+
+		colorop_state = drm_atomic_get_new_colorop_state(state, colorop);
+		if (!colorop_state)
+			return -EINVAL;
+
+		if (colorop_state->bypass)
+			return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 05/11] drm/amd/display: Add fixed matrix colorop to color pipeline
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (3 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 04/11] drm/vkms: Add atomic check and matrix handling for fixed matrix colorop Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 06/11] drm/amd/display: Implement fixed matrix colorop color space mapping Harry Wentland
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, Alex Hung

Insert a fixed matrix colorop as the first operation in the
amdgpu color pipeline, before the existing DEGAM 1D curve. This
allows userspace to select YUV-to-RGB conversion via the color
pipeline for YCbCr framebuffers.

The 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

Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 27 ++++++++++++++++++-
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.h |  1 +
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
index 7ee051cb3c05..972fa96b4b9c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
@@ -51,6 +51,14 @@ const u64 amdgpu_dm_supported_blnd_tfs =
 	BIT(DRM_COLOROP_1D_CURVE_BT2020_INV_OETF) |
 	BIT(DRM_COLOROP_1D_CURVE_GAMMA22);
 
+const u64 amdgpu_dm_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);
+
 #define MAX_COLOR_PIPELINE_OPS 10
 
 #define LUT3D_SIZE		17
@@ -70,6 +78,23 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr
 
 	memset(ops, 0, sizeof(ops));
 
+	/* Fixed Matrix (YUV to RGB) */
+	ops[i] = kzalloc_obj(*ops[0]);
+	if (!ops[i]) {
+		ret = -ENOMEM;
+		goto cleanup;
+	}
+
+	ret = drm_plane_colorop_fixed_matrix_init(dev, ops[i], plane, &dm_colorop_funcs,
+						  amdgpu_dm_supported_fm,
+						  DRM_COLOROP_FLAG_ALLOW_BYPASS);
+	if (ret)
+		goto cleanup;
+
+	list->type = ops[i]->base.id;
+
+	i++;
+
 	/* 1D curve - DEGAM TF */
 	ops[i] = kzalloc_obj(*ops[0]);
 	if (!ops[i]) {
@@ -83,7 +108,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr
 	if (ret)
 		goto cleanup;
 
-	list->type = ops[i]->base.id;
+	drm_colorop_set_next_property(ops[i - 1], ops[i]);
 
 	i++;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h
index 2e1617ffc8ee..7b71d3144391 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h
@@ -30,6 +30,7 @@
 extern const u64 amdgpu_dm_supported_degam_tfs;
 extern const u64 amdgpu_dm_supported_shaper_tfs;
 extern const u64 amdgpu_dm_supported_blnd_tfs;
+extern const u64 amdgpu_dm_supported_fm;
 
 int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list);
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 06/11] drm/amd/display: Implement fixed matrix colorop color space mapping
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (4 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 05/11] drm/amd/display: Add fixed matrix colorop to color pipeline Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 07/11] drm/amd/display: Use GAMCOR for first TF if YUV conversion is needed Harry Wentland
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, Alex Hung

Add __set_dm_plane_colorop_fixed_matrix() which maps the fixed matrix
type enum to the appropriate dc_color_space for DC programming:

  YCBCR601_FULL_RGB     -> COLOR_SPACE_YCBCR601
  YCBCR601_LIMITED_RGB  -> COLOR_SPACE_YCBCR601_LIMITED
  YCBCR709_FULL_RGB     -> COLOR_SPACE_YCBCR709
  YCBCR709_LIMITED_RGB  -> COLOR_SPACE_YCBCR709_LIMITED
  YCBCR2020_FULL_RGB_NC -> COLOR_SPACE_2020_YCBCR_FULL
  YCBCR2020_LIMITED_RGB_NC -> COLOR_SPACE_2020_YCBCR_LIMITED

When the fixed matrix is bypassed, color_space is set to
COLOR_SPACE_UNKNOWN.

Update amdgpu_dm_plane_set_colorop_properties() to process the
fixed matrix colorop first (before DEGAM), matching the new pipeline
order.

Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 68 ++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index fa6883ae4dfb..c54ca5188f68 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -1492,6 +1492,61 @@ __set_colorop_in_tf_1d_curve(struct dc_plane_state *dc_plane_state,
 	return 0;
 }
 
+static int
+__set_dm_plane_colorop_fixed_matrix(struct drm_plane_state *plane_state,
+				    struct dc_plane_state *dc_plane_state,
+				    struct drm_colorop *colorop)
+{
+	struct drm_colorop *old_colorop;
+	struct drm_colorop_state *colorop_state = NULL, *new_colorop_state;
+	struct drm_atomic_commit *state = plane_state->state;
+	int i = 0;
+
+	old_colorop = colorop;
+
+	for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) {
+		if (new_colorop_state->colorop == old_colorop) {
+			colorop_state = new_colorop_state;
+			break;
+		}
+	}
+
+	if (!colorop_state)
+		return -EINVAL;
+
+	if (colorop_state->bypass) {
+		dc_plane_state->color_space = COLOR_SPACE_UNKNOWN;
+		return 0;
+	}
+
+	switch (colorop_state->fixed_matrix_type) {
+	case DRM_COLOROP_FM_YCBCR601_FULL_RGB:
+		dc_plane_state->color_space = COLOR_SPACE_YCBCR601;
+		break;
+	case DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
+		dc_plane_state->color_space = COLOR_SPACE_YCBCR601_LIMITED;
+		break;
+	case DRM_COLOROP_FM_YCBCR709_FULL_RGB:
+		dc_plane_state->color_space = COLOR_SPACE_YCBCR709;
+		break;
+	case DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
+		dc_plane_state->color_space = COLOR_SPACE_YCBCR709_LIMITED;
+		break;
+	case DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
+		dc_plane_state->color_space = COLOR_SPACE_2020_YCBCR_FULL;
+		break;
+	case DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
+		dc_plane_state->color_space = COLOR_SPACE_2020_YCBCR_LIMITED;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	dc_plane_state->update_flags.bits.full_update = 1;
+
+	return 0;
+}
+
 static int
 __set_dm_plane_colorop_degamma(struct drm_plane_state *plane_state,
 			       struct dc_plane_state *dc_plane_state,
@@ -1879,10 +1934,21 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state,
 	bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
 	int ret;
 
-	/* 1D Curve - DEGAM TF */
+	/* Fixed Matrix (YUV to RGB) */
 	if (!colorop)
 		return -EINVAL;
 
+	ret = __set_dm_plane_colorop_fixed_matrix(plane_state, dc_plane_state, colorop);
+	if (ret)
+		return ret;
+
+	/* 1D Curve - DEGAM TF */
+	colorop = colorop->next;
+	if (!colorop) {
+		drm_dbg(dev, "no degamma colorop found\n");
+		return -EINVAL;
+	}
+
 	ret = __set_dm_plane_colorop_degamma(plane_state, dc_plane_state, colorop);
 	if (ret)
 		return ret;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 07/11] drm/amd/display: Use GAMCOR for first TF if YUV conversion is needed
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (5 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 06/11] drm/amd/display: Implement fixed matrix colorop color space mapping Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 08/11] drm/amd/display: Check actual state during commit_tail Harry Wentland
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland

For subsampled formats we need to use GAMCOR instead of
the DEGAM block. The color module can create a LUT for
that if we set map_user_ramp to true. So do that when
we have subsampled formats.

Assisted-by: Claude:claude-sonnet-4.5
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 23 +++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index c54ca5188f68..561ee9a2e749 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -1454,11 +1454,15 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 		if (ret)
 			return ret;
        } else {
+		bool is_subsampled =
+			dc_plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN &&
+			dc_plane_state->format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END;
+
 		dc_plane_state->in_transfer_func.type =
 			TF_TYPE_PREDEFINED;
 
 		if (!mod_color_calculate_degamma_params(color_caps,
-		    &dc_plane_state->in_transfer_func, NULL, false))
+		    &dc_plane_state->in_transfer_func, NULL, is_subsampled))
 			return -ENOMEM;
 	}
 	return 0;
@@ -1471,6 +1475,8 @@ __set_colorop_in_tf_1d_curve(struct dc_plane_state *dc_plane_state,
 	struct dc_transfer_func *tf = &dc_plane_state->in_transfer_func;
 	struct drm_colorop *colorop = colorop_state->colorop;
 	struct drm_device *drm = colorop->dev;
+	struct dc_color_caps *color_caps = NULL;
+	bool is_subsampled_format;
 
 	if (colorop->type != DRM_COLOROP_1D_CURVE)
 		return -EINVAL;
@@ -1485,10 +1491,23 @@ __set_colorop_in_tf_1d_curve(struct dc_plane_state *dc_plane_state,
 	}
 
 	drm_dbg(drm, "Degamma colorop with ID: %d\n", colorop->base.id);
-
 	tf->type = TF_TYPE_PREDEFINED;
+
+	/* Check if format requires post-scale color processing (subsampled formats) */
+	is_subsampled_format = (dc_plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN &&
+				dc_plane_state->format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END);
+
 	tf->tf = amdgpu_colorop_tf_to_dc_tf(colorop_state->curve_1d_type);
 
+	if (dc_plane_state->ctx && dc_plane_state->ctx->dc)
+		color_caps = &dc_plane_state->ctx->dc->caps.color;
+
+	if (!mod_color_calculate_degamma_params(color_caps, tf, NULL,
+						is_subsampled_format)) {
+		drm_err(drm, "Failed to calculate degamma params\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 08/11] drm/amd/display: Check actual state during commit_tail
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (6 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 07/11] drm/amd/display: Use GAMCOR for first TF if YUV conversion is needed Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 09/11] drm/amd/display: Set color_space to plane_infos Harry Wentland
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, Alex Hung

Previously we checked the plane_state->state's plane_color_pipeline
client config when determining whether fill_plane_color_attributes
should run, i.e., whether we had a plane color pipeline and should
use that code for handling fixed matrix properties, or whether we
should look at legacy plane encoding and range.

The problem is that we also call this during commit_tail, during
which plane_state doesn't have the state backpointer. This meant
that during commit_tail we'd look at the legacy plane COLOR_RANGE
and COLOR_ENCODING values and overwrite what we pulled from the
fixed matrix colorop in atomic_check previously.

Instead pass the drm_atomic_state in explicitly and check that.

Assisted-by:Claude:claude-sonnet-4.5
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ece581609cf7..6d0e3d699eb1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6270,7 +6270,8 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = {
 };
 
 static int
-fill_plane_color_attributes(const struct drm_plane_state *plane_state,
+fill_plane_color_attributes(struct drm_atomic_commit *state,
+			    const struct drm_plane_state *plane_state,
 			    const enum surface_pixel_format format,
 			    enum dc_color_space *color_space)
 {
@@ -6279,7 +6280,7 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state,
 	*color_space = COLOR_SPACE_SRGB;
 
 	/* Ignore properties when DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE is set */
-	if (plane_state->state && plane_state->state->plane_color_pipeline)
+	if (state && state->plane_color_pipeline)
 		return 0;
 
 	/* DRM color properties only affect non-RGB formats. */
@@ -6319,6 +6320,7 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state,
 
 static int
 fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
+			    struct drm_atomic_commit *state,
 			    const struct drm_plane_state *plane_state,
 			    const u64 tiling_flags,
 			    struct dc_plane_info *plane_info,
@@ -6412,7 +6414,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
 
 	plane_info->layer_index = plane_state->normalized_zpos;
 
-	ret = fill_plane_color_attributes(plane_state, plane_info->format,
+	ret = fill_plane_color_attributes(state, plane_state, plane_info->format,
 					  &plane_info->color_space);
 	if (ret)
 		return ret;
@@ -6453,7 +6455,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 	dc_plane_state->clip_rect = scaling_info.clip_rect;
 	dc_plane_state->scaling_quality = scaling_info.scaling_quality;
 
-	ret = fill_dc_plane_info_and_addr(adev, plane_state,
+	ret = fill_dc_plane_info_and_addr(adev, plane_state->state, plane_state,
 					  afb->tiling_flags,
 					  &plane_info,
 					  &dc_plane_state->address,
@@ -10306,7 +10308,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
 		}
 
 		fill_dc_plane_info_and_addr(
-			dm->adev, new_plane_state,
+			dm->adev, state, new_plane_state,
 			afb->tiling_flags,
 			&bundle->plane_infos[planes_count],
 			&bundle->flip_addrs[planes_count].address,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 09/11] drm/amd/display: Set color_space to plane_infos
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (7 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 08/11] drm/amd/display: Check actual state during commit_tail Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-06-23 16:48 ` [PATCH v3 10/11] drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is bypassed Harry Wentland
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, Alex Hung

DC looks at plane_info structs.

For legacy drm_plane COLOR_ENCODING and COLOR_RANGE this was
done in fill_dc_plane_info_and_addr's call to
fill_plane_color_attributes.

Assisted-by: Claude:claude-sonnet-4.5
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6d0e3d699eb1..50d65f2f34e2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10314,6 +10314,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
 			&bundle->flip_addrs[planes_count].address,
 			afb->tmz_surface);
 
+		bundle->plane_infos[planes_count].color_space = dc_plane->color_space;
+
 		drm_dbg_state(state->dev, "plane: id=%d dcc_en=%d\n",
 				 new_plane_state->plane->index,
 				 bundle->plane_infos[planes_count].dcc.enable);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 10/11] drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is bypassed
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (8 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 09/11] drm/amd/display: Set color_space to plane_infos Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-07-03 10:40   ` Robert Mader
  2026-06-23 16:48 ` [PATCH v3 11/11] drm/amd/display: Force GAMCOR for subsampled surfaces with PQ/Gamma22/HLG Harry Wentland
  2026-07-03  9:44 ` [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Robert Mader
  11 siblings, 1 reply; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, stable

When the fixed matrix colorop is bypassed, the color_space was set to
COLOR_SPACE_UNKNOWN (0). In DC's DPP setup (dpp1_cnv_setup), the logic
'input_color_space ? input_color_space : color_space' treats 0 as
'not provided', causing it to fall back to the format-based default of
COLOR_SPACE_YCBCR709 for YUV framebuffers. This results in an implicit
YUV-to-RGB conversion via ICSC even when a color pipeline is active and
the fixed matrix is bypassed.

Fix this by setting COLOR_SPACE_SRGB (1) instead. This is non-zero, so
it overrides the format default. The SRGB entry in dpp_input_csc_matrix
is an identity matrix, so ICSC performs no actual conversion, which is
the correct behavior when the fixed matrix colorop is bypassed.

Cc: stable@vger.kernel.org
Fixes: 93d922f4833b ("drm/amd/display: Implement fixed matrix colorop color space mapping")
Assisted-by: Copilot:claude-opus-4.6
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 561ee9a2e749..984bbfcf23f0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -1534,7 +1534,7 @@ __set_dm_plane_colorop_fixed_matrix(struct drm_plane_state *plane_state,
 		return -EINVAL;
 
 	if (colorop_state->bypass) {
-		dc_plane_state->color_space = COLOR_SPACE_UNKNOWN;
+		dc_plane_state->color_space = COLOR_SPACE_SRGB;
 		return 0;
 	}
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 11/11] drm/amd/display: Force GAMCOR for subsampled surfaces with PQ/Gamma22/HLG
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (9 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 10/11] drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is bypassed Harry Wentland
@ 2026-06-23 16:48 ` Harry Wentland
  2026-07-03  9:44 ` [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Robert Mader
  11 siblings, 0 replies; 19+ messages in thread
From: Harry Wentland @ 2026-06-23 16:48 UTC (permalink / raw)
  To: dri-devel, amd-gfx; +Cc: Harry Wentland, stable

The ROM early-return checks for PQ, Gamma 2.2, and HLG in
mod_color_calculate_degamma_params() do not consider the map_user_ramp
parameter. When map_user_ramp is true (indicating a subsampled surface
that requires post-scaler degamma via GAMCOR), the function still takes
the ROM path, programming PRE_DEGAM instead.

For subsampled formats the chroma channels must be upsampled by the
scaler before degamma is applied. PRE_DEGAM sits before the scaler in
the pipeline (CNVC domain), while GAMCOR sits after it (CM domain).
Using the ROM for subsampled surfaces means degamma is applied to
subsampled chroma before upsampling, producing incorrect results.

Fix by gating the dcn_arch ROM capability checks on !map_user_ramp,
forcing PQ/Gamma22/HLG through the GAMCOR LUT path when the surface
is subsampled.

Fixes: a8bf71649088 ("drm/amd/display: Internal refactoring to abstract color caps")
Cc: stable@vger.kernel.org
Assisted-by: Copilot:claude-opus-4.6
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
 drivers/gpu/drm/amd/display/modules/color/color_gamma.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index 03d88e78165d..5786ef5787ac 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -1696,7 +1696,8 @@ bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps,
 			return true;
 
 		if (dc_caps != NULL &&
-			dc_caps->dpp.dcn_arch == 1) {
+			dc_caps->dpp.dcn_arch == 1 &&
+			!map_user_ramp) {
 
 			if (input_tf->tf == TRANSFER_FUNCTION_PQ &&
 					dc_caps->dpp.dgam_rom_caps.pq == 1)
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS
  2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
                   ` (10 preceding siblings ...)
  2026-06-23 16:48 ` [PATCH v3 11/11] drm/amd/display: Force GAMCOR for subsampled surfaces with PQ/Gamma22/HLG Harry Wentland
@ 2026-07-03  9:44 ` Robert Mader
  11 siblings, 0 replies; 19+ messages in thread
From: Robert Mader @ 2026-07-03  9:44 UTC (permalink / raw)
  To: Harry Wentland, dri-devel, amd-gfx
  Cc: Alex Hung, Daniel Stone, Chaitanya Kumar Borah, Uma Shankar,
	Louis Chauvet, Melissa Wen, Simon Ser

Hi Harry,

I wrote a Weston draft implementation here: 
https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/2133

Weston had an existing test ("color-representation-drm") for the legacy 
properties, ensuring the VKMS output visually matches expectations for 
all six possible values. With the MR above, if VKMS is loaded with 
enable_plane_pipeline=1 the new colorop is used, confirming that the 
VKMS implementation works as expected and in general that the new 
colorop can be used as a drop-in replacement for the legacy properties. 
That means any driver/hardware/plane that currently supports 
COLOR_ENCODING and COLOR_RANGE could offer a pipeline with only the 
colorop added here and just map it to the existing underlying 
implementation.

The mentioned test runs on the CI and thus allow to easily check that 
things work as expected - quoting one example from KMS debug output in 
the the test log:

[atomic] applying output 0 (Virtual-1) state
     [CRTC:97] MODE_ID (24) -> 108 (0x6c)
     [CRTC:97] ACTIVE (23) -> 1 (0x1)
     [CRTC:97] GAMMA_LUT (29) -> 0 (0x0)
     [CRTC:97] VRR_ENABLED (25) -> 0 (0x0)
     [CRTC:97] BACKGROUND_COLOR (31) -> 18446462598732840960 
(0xffff000000000000)
     [CONN:105] CRTC_ID (21) -> 97 (0x61)
     [PLANE:35] FB_ID (18) -> 109 (0x6d)
     [PLANE:35] CRTC_ID (21) -> 97 (0x61)
     [PLANE:35] SRC_X (10) -> 0 (0x0)
     [PLANE:35] SRC_Y (11) -> 0 (0x0)
     [PLANE:35] SRC_W (12) -> 16777216 (0x1000000)
     [PLANE:35] SRC_H (13) -> 16777216 (0x1000000)
     [PLANE:35] CRTC_X (14) -> 384 (0x180)
     [PLANE:35] CRTC_Y (15) -> 256 (0x100)
     [PLANE:35] CRTC_W (16) -> 256 (0x100)
     [PLANE:35] CRTC_H (17) -> 256 (0x100)
     [COLOROP:40] BYPASS (42) -> 0 (0x0)
     [COLOROP:40] FIXED_MATRIX_TYPE (44) -> YCbCr 2020 NC Limited to RGB 
(0x5)
     [COLOROP:45] BYPASS (47) -> 1 (0x1)
     [COLOROP:50] BYPASS (52) -> 1 (0x1)
     [COLOROP:55] BYPASS (57) -> 1 (0x1)
     [COLOROP:60] BYPASS (62) -> 1 (0x1)
     [PLANE:35] COLOR_PIPELINE (65) -> 40 (0x28)
     [PLANE:35] FORMAT: NV12 MODIFIER: LINEAR (0x0)
     [PLANE:35] rotation (37) -> 1 (0x1)

I also tested the AMD implementation with the Weston MR and Gstreamer 
(>= 1.28) pipelines like this:

gst-launch-1.0 filesrc location=~/Alaska2160p30fps8bitAV1.webm ! 
parsebin ! vaav1dec ! waylandsink fullscreen=1

and confirmed that at least BT709-limited and BT2020-limited with NV12 
and P010 work as expected.

In these test cases all other colorops where set to bypass - however at 
the recent Display Next Hackfest we also tested more complex pipelines 
with a mostly identical patch-set.

Therefor the whole series is:

Tested-by: Robert Mader <robert.mader@collabora.com>

I'll now go over the individual commits to add additional R-Bs where I 
reasonably can.

Thanks and best regards!

Robert

On 23.06.26 18:48, Harry Wentland wrote:
> When we merged the drm_plane color pipeline API the major gap
> that existed was the lack of a YUV to RGB conversion colorop.
> We deprecated any legacy drm_plane color properties, which
> means that the COLOR_RANGE and COLOR_ENCODING properties can't
> be used with the COLOR_PIPELINE property on a drm_plane. In
> practice this means that we can't use a COLOR_PIPELINE on
> YCbCr encoded framebuffers.
>
> This patchset expands on the Fixed Matrix colorop proposed by Chaitanya
> and adds limited range variants of the YCbCr to RGB conversions.
>
> His full patchset can be found at
> https://patchwork.freedesktop.org/patch/709860
>
> This code has been tested with IGT and an experimental KWin branch.
>
> IGT branch:
> https://gitlab.freedesktop.org/hwentland/igt-gpu-tools/-/tree/yuv-fm-colorop
>
> KWin branch used for testing:
> https://invent.kde.org/hwentlan/kwin/-/tree/yuv-fm-colorop
>
> The kernel branch containing these changes, based on drm-misc-next
> can be found at:
> https://gitlab.freedesktop.org/hwentland/linux/-/tree/yuv-fm-colorop
>
> Further background on this work can be found at:
> https://hwentland.github.io/2026/03/10/plane-color-pipeline-csc-3d-lut-kwin.html
>
> v3:
> - base on Chaitanya's updated patch and rename code accordingly
>    to Fixed_Matrix instead of CSC Fixed-Function
>
> v2:
> - use Chaitanya's CSC_FF block for named matrices
>
> Cc: Alex Hung <alex.hung@amd.com>
> Cc: Daniel Stone <daniels@collabora.com>
> Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Cc: Louis Chauvet <louis.chauvet@bootlin.com>
> Cc: Melissa Wen <mwen@igalia.com>
> Cc: Simon Ser <contact@emersion.fr>
> Cc: Robert Mader <robert.mader@collabora.com>
>
> Chaitanya Kumar Borah (1):
>    drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
>
> Harry Wentland (10):
>    drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values
>    drm/vkms: Add fixed matrix colorop to color pipeline
>    drm/vkms: Add atomic check and matrix handling for fixed matrix
>      colorop
>    drm/amd/display: Add fixed matrix colorop to color pipeline
>    drm/amd/display: Implement fixed matrix colorop color space mapping
>    drm/amd/display: Use GAMCOR for first TF if YUV conversion is needed
>    drm/amd/display: Check actual state during commit_tail
>    drm/amd/display: Set color_space to plane_infos
>    drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is
>      bypassed
>    drm/amd/display: Force GAMCOR for subsampled surfaces with
>      PQ/Gamma22/HLG
>
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  14 ++-
>   .../amd/display/amdgpu_dm/amdgpu_dm_color.c   |  91 +++++++++++++-
>   .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c |  27 ++++-
>   .../amd/display/amdgpu_dm/amdgpu_dm_colorop.h |   1 +
>   .../amd/display/modules/color/color_gamma.c   |   3 +-
>   drivers/gpu/drm/drm_atomic.c                  |   4 +
>   drivers/gpu/drm/drm_atomic_uapi.c             |   4 +
>   drivers/gpu/drm/drm_colorop.c                 | 109 +++++++++++++++++
>   drivers/gpu/drm/vkms/vkms_colorop.c           |  66 +++++++---
>   drivers/gpu/drm/vkms/vkms_composer.c          |   6 +
>   drivers/gpu/drm/vkms/vkms_plane.c             |  68 ++++++++++-
>   include/drm/drm_colorop.h                     | 114 ++++++++++++++++++
>   include/uapi/drm/drm_mode.h                   |  12 ++
>   13 files changed, 487 insertions(+), 32 deletions(-)
>
> --
> 2.54.0
>
>
>  From mboxrd@z Thu Jan  1 00:00:00 1970
> Return-Path: <dri-devel-bounces@lists.freedesktop.org>
> X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
> 	aws-us-west-2-korg-lkml-1.web.codeaurora.org
> Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177])
> 	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
> 	(No client certificate requested)
> 	by smtp.lore.kernel.org (Postfix) with ESMTPS id B655BCDB479
> 	for <dri-devel@archiver.kernel.org>; Tue, 23 Jun 2026 16:48:27 +0000 (UTC)
> Received: from gabe.freedesktop.org (localhost [127.0.0.1])
> 	by gabe.freedesktop.org (Postfix) with ESMTP id 0E9B310EC02;
> 	Tue, 23 Jun 2026 16:48:27 +0000 (UTC)
> Authentication-Results: gabe.freedesktop.org;
> 	dkim=pass (1024-bit key; unprotected) header.d=amd.com header.i=@amd.com header.b="qZX10j76";
> 	dkim-atps=neutral
> Received: from CO1PR03CU002.outbound.protection.outlook.com
>   (mail-westus2azon11010047.outbound.protection.outlook.com [52.101.46.47])
>   by gabe.freedesktop.org (Postfix) with ESMTPS id 5F51010EC02;
>   Tue, 23 Jun 2026 16:48:26 +0000 (UTC)
> ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
>   b=VA0YLyQcoF/NwrbXIx3+VQ3BEuv4aT+SYHQefo57EnVYiNpi7RTRdV8VfAs3YI1HaBIgdfe0AkgUp2sC8Azh2r/XMeGOAqDdtj7rRvOHuvgjadls3iVdy5T/OCqvN+DcP5e0Ydi2hlorPceYBV4ks7zRX19kZmUhJfvowzMu+XwXMzrBa9xNAjbM+WxzxrXmrQH5lmz3Zg5xwSSInH2RR9E/Tt4TP/XK+pIaCYlJJpAYXMrInwgmzvdFXJZxaMdQ9JKTbSm0SgpYPSQNPx97d2RgSobhpvcU8W+dKFZisu+NPHwJZmigWmqY5aK94xMrUhQlA+IxH7Lt3oENs+ALcA==
> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;
>   s=arcselector10001;
>   h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;
>   bh=Va79LlpBVSYHVb5GCR4+MP8S3TZmpgDcdmsEEadaWcA=;
>   b=eoDmKJvvQs88tX+Vv3cmW09h27cbxGDBKt5MemE17ISSIfStPkjPR1Usp+BuJfNnGpTnlrmuYy0r6kE690Tnn9r9T1yFAYNZzZ6U8HOGw+zlTM8cXdLol+R37urgfqSWz21U08bYDNw7XnTf6wbE/g/x75DRwzWyrKN3z5Y6tWiX8+LK0yLYRmsjneexC8uAw5Z5kRaPPylBnJRY0Thse5NiffisMrri1OdAoOgEW9z1GL2Q7X8AInUvthDOGefsppr5QOZIr2Xr8zNqqKSpRCMyDIDOTUXlfO5SCdCaYc68yb7FOUWO+rbxqgWll7JcOmnMaZh4eJ1+eAgKTst9lA==
> ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is
>   165.204.84.17) smtp.rcpttodomain=lists.freedesktop.org smtp.mailfrom=amd.com;
>   dmarc=pass (p=quarantine sp=quarantine pct=100) action=none
>   header.from=amd.com; dkim=none (message not signed); arc=none (0)
> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1;
>   h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
>   bh=Va79LlpBVSYHVb5GCR4+MP8S3TZmpgDcdmsEEadaWcA=;
>   b=qZX10j76DTVxZmEdcDnUG3FjzS8o4p/w092+ZzCoDTdUvqRhy8BseSn6wGPgeWFEbkyS35p0+8lPhM6kx0YCDqeAvP6ya7APbwQxyiMLnhDAMu7cZffNOZGNmVMrJd0zsMMZgN8X2aWlj0ckB5JENTDjCjjYyKZfVWwJHQO3Isc=
> Received: from DS7PR05CA0037.namprd05.prod.outlook.com (2603:10b6:8:2f::24) by
>   SA3PR12MB9199.namprd12.prod.outlook.com (2603:10b6:806:398::19) with
>   Microsoft SMTP Server (version=TLS1_2,
>   cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.139.20; Tue, 23 Jun
>   2026 16:48:19 +0000
> Received: from DS1PEPF00017099.namprd05.prod.outlook.com (2603:10b6:8:2f::4)
>   by DS7PR05CA0037.outlook.office365.com (2603:10b6:8:2f::24) with Microsoft
>   SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.159.12
>   via Frontend Transport; Tue, 23 Jun 2026 16:48:18 +0000
> X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17)
>   smtp.mailfrom=amd.com; dkim=none (message not signed)
>   header.d=none;dmarc=pass action=none header.from=amd.com;
> Received-SPF: Pass (protection.outlook.com: domain of amd.com designates
>   165.204.84.17 as permitted sender) receiver=protection.outlook.com;
>   client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C
> Received: from satlexmb08.amd.com (165.204.84.17) by
>   DS1PEPF00017099.mail.protection.outlook.com (10.167.18.103) with Microsoft
>   SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
>   15.21.159.10 via Frontend Transport; Tue, 23 Jun 2026 16:48:18 +0000
> Received: from satlexmb10.amd.com (10.181.42.219) by satlexmb08.amd.com
>   (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2,
>   cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Tue, 23 Jun
>   2026 11:48:18 -0500
> Received: from satlexmb08.amd.com (10.181.42.217) by satlexmb10.amd.com
>   (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2,
>   cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Tue, 23 Jun
>   2026 11:48:18 -0500
> Received: from hwentlanryzen (10.180.168.240) by satlexmb08.amd.com
>   (10.181.42.217) with Microsoft SMTP Server id 15.2.2562.41 via Frontend
>   Transport; Tue, 23 Jun 2026 11:48:17 -0500
> From: Harry Wentland <harry.wentland@amd.com>
> To: <dri-devel@lists.freedesktop.org>, <amd-gfx@lists.freedesktop.org>
> CC: Harry Wentland <harry.wentland@amd.com>, Alex Hung <alex.hung@amd.com>
> Subject: [PATCH v3 03/11] drm/vkms: Add fixed matrix colorop to color pipeline
> Date: Tue, 23 Jun 2026 12:48:04 -0400
> Message-ID: <20260623164812.81110-4-harry.wentland@amd.com>
> X-Mailer: git-send-email 2.54.0
> In-Reply-To: <20260623164812.81110-1-harry.wentland@amd.com>
> References: <20260623164812.81110-1-harry.wentland@amd.com>
> MIME-Version: 1.0
> Content-Transfer-Encoding: 8bit
> Content-Type: text/plain
> X-EOPAttributedMessage: 0
> X-MS-PublicTrafficType: Email
> X-MS-TrafficTypeDiagnostic: DS1PEPF00017099:EE_|SA3PR12MB9199:EE_
> X-MS-Office365-Filtering-Correlation-Id: b8d5e9e1-ef4b-45b3-3dd2-08ded1473a84
> X-MS-Exchange-SenderADCheck: 1
> X-MS-Exchange-AntiSpam-Relay: 0
> X-Microsoft-Antispam: BCL:0;
>   ARA:13230040|376014|36860700016|82310400026|1800799024|23010399003|11063799006|56012099006|18002099003|22082099003;
> X-Microsoft-Antispam-Message-Info: HWkLA1p9dJhZyeyQ+wRPa13E7c3B1nHhhTTqJAch6jyxhBqK2bXCX4wi71GuXwKamvb0dDZO5W0bt+VmstYYLg/ai2JdaH9Ky5UZrjhvd6xZP0WpXuMaYcmPe3sy6CNsQ45zbDJH6G+w3ycZWBm9yXMQg3/U8q75th+zL2NV1PrP9CZ+xuTpWLmITvsb8s7QN75yKpxosdZ1hQheQ6SiWpe3JbfBU80b5FE03xBEQAjlO5Zr8ALlTgfDNNzSfbDmzK24bLPUxeE9gHq6uJTKbcv7mYXJsFdpDetHWjEN4gAaqXAUlyP62FksIJOdNSl1ZU4GPi9UEzqpiW/MJp2KH7p8LIVvyeN1TRtv0n8gch2slamirYUj3XZd5GGusjidQKjon7MMq1HVjkAne6f44NC1+E4WRBCWr9l3ij5HFz9+OfO6yGchONfrY/HzYApeFN8ylIghw5ZhL3FdtDmC4Ya0nC9e4zoWdcfSRa013xQC4W2ZR02YxAuoirWh9JgCbYPwcIe59geKASyGabDlJrwhmci/aFeaMzw8/cw+UvRGqnVS4dfjhyvYKKw8IDnZtHL775UavtadnBKftKlz3Punx/lsLNlEPgEInts1YSsrWWcSDwZjf9i3d+srM2YMEMtoaRjWP/ghtKFYio84JfqBTGz2zb1MductyyjOnbU/6fatAM4cf+PqmdSqyLZ9KL+xrK8hcaFxT4awOqeqvg==
> X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:;
>   IPV:NLI; SFV:NSPM; H:satlexmb08.amd.com; PTR:InfoDomainNonexistent; CAT:NONE;
>   SFS:(13230040)(376014)(36860700016)(82310400026)(1800799024)(23010399003)(11063799006)(56012099006)(18002099003)(22082099003);
>   DIR:OUT; SFP:1101;
> X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1
> X-MS-Exchange-AntiSpam-MessageData-0: y1eQ/S3waZfjEZXFahjKn+8wWNk7thWlCT5NINZNyFhy6gsLTrvn2uHkXQjwTIZHM0dKCFbNTMTl/+rtqNe7HsAuG7uDsfbZBlLQQE4BY4QDUYh4W8IvQa+vMgtH/lDUe8dUAeXDCDm6JXk6hkomFO8h3vM8ey/NZYyctZZlxUKS/ocYoL4t24N28DABkUVt+82m7QrOo6BUWwftaj2rATOo3F/wdisUHeLnUyucdGsOWYxnlD1G2Z/ZpbNChk8m5EnAMkti2xmQgHLAIroV9KC+bHBURnmn5BoK0Bub2tXFMqdFnE7SIrD4BE5GeGCWjs3icEwQgr8B1/dqwIMr1Pccuk1QebbrFUiqZEfj9rzwNcF/cYq6gqvCsM30BhcObGAob2T4aGbJam2qmxG0q53+aVy00VxSqQvLGYLDkr8VaGsbt6MOEEZ5oyYrwxTd
> X-OriginatorOrg: amd.com
> X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jun 2026 16:48:18.7091 (UTC)
> X-MS-Exchange-CrossTenant-Network-Message-Id: b8d5e9e1-ef4b-45b3-3dd2-08ded1473a84
> X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d
> X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17];
>   Helo=[satlexmb08.amd.com]
> X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF00017099.namprd05.prod.outlook.com
> X-MS-Exchange-CrossTenant-AuthAs: Anonymous
> X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem
> X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR12MB9199
> X-BeenThere: dri-devel@lists.freedesktop.org
> X-Mailman-Version: 2.1.29
> Precedence: list
> List-Id: Direct Rendering Infrastructure - Development
>   <dri-devel.lists.freedesktop.org>
> List-Unsubscribe: <https://lists.freedesktop.org/mailman/options/dri-devel>,
>   <mailto:dri-devel-request@lists.freedesktop.org?subject=unsubscribe>
> List-Archive: <https://lists.freedesktop.org/archives/dri-devel>
> List-Post: <mailto:dri-devel@lists.freedesktop.org>
> List-Help: <mailto:dri-devel-request@lists.freedesktop.org?subject=help>
> List-Subscribe: <https://lists.freedesktop.org/mailman/listinfo/dri-devel>,
>   <mailto:dri-devel-request@lists.freedesktop.org?subject=subscribe>
> Errors-To: dri-devel-bounces@lists.freedesktop.org
> Sender: "dri-devel" <dri-devel-bounces@lists.freedesktop.org>
>
> 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 <harry.wentland@amd.com>
> Reviewed-by: Alex Hung <alex.hung@amd.com>
> ---
>   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");

-- 
Robert Mader
Consultant Software Developer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
  2026-06-23 16:48 ` [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Harry Wentland
@ 2026-07-03 10:15   ` Robert Mader
  2026-07-03 10:52   ` Pekka Paalanen
  1 sibling, 0 replies; 19+ messages in thread
From: Robert Mader @ 2026-07-03 10:15 UTC (permalink / raw)
  To: Harry Wentland, dri-devel, amd-gfx; +Cc: Chaitanya Kumar Borah, Melissa Wen

Hi Harry,

On 23.06.26 18:48, Harry Wentland wrote:
> From: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
>
> Introduce DRM_COLOROP_FIXED_MATRIX, a new colorop type representing a
> hardware that performs a fixed matrix operation.
>
> Unlike CTM-based colorops, this block does not expose programmable
> coefficients. Instead, userspace selects one of the predefined
> hardware modes via a new FIXED_MATRIX_TYPE enum property. Supported modes
> include common YCbCr->RGB and RGB709->RGB2020 conversions.
>
> v2:
>   - Naming changes (Pekka)
>
> v3:
>   - Fix NC matrix enum name and string (Melissa)
>   - Rebase
>
> Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
> Reviewed-by: Melissa Wen <mwen@igalia.com>
> Reviewed-by: Harry Wentland <harry.wentland@amd.com>
> ---
>   drivers/gpu/drm/drm_atomic.c      |   4 ++
>   drivers/gpu/drm/drm_atomic_uapi.c |   4 ++
>   drivers/gpu/drm/drm_colorop.c     | 106 ++++++++++++++++++++++++++++++
>   include/drm/drm_colorop.h         |  84 +++++++++++++++++++++++
>   include/uapi/drm/drm_mode.h       |  12 ++++
>   5 files changed, 210 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 3af1b9cc9a06..ced591c4a0bd 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -925,6 +925,10 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
>   				  drm_get_colorop_lut3d_interpolation_name(colorop->lut3d_interpolation));
>   		drm_printf_indent(p, 1, "data blob id=%d\n", state->data ? state->data->base.id : 0);
>   		break;
> +	case DRM_COLOROP_FIXED_MATRIX:
> +		drm_printf_indent(p, 1, "fixed_matrix_type=%s\n",
> +				  drm_get_colorop_fixed_matrix_type_name(state->fixed_matrix_type));
> +		break;
>   	default:
>   		break;
>   	}
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index c7f80d90794c..cee4550ffdbd 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -761,6 +761,8 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
>   	} else if (property == colorop->data_property) {
>   		return drm_atomic_color_set_data_property(colorop, state,
>   							  property, val);
> +	} else if (property == colorop->fixed_matrix_type_property) {
> +		state->fixed_matrix_type = val;
>   	} else {
>   		drm_dbg_atomic(colorop->dev,
>   			       "[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
> @@ -793,6 +795,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
>   		*val = colorop->lut3d_interpolation;
>   	else if (property == colorop->data_property)
>   		*val = (state->data) ? state->data->base.id : 0;
> +	else if (property == colorop->fixed_matrix_type_property)
> +		*val = state->fixed_matrix_type;
>   	else
>   		return -EINVAL;
>   
> diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
> index c0eecde8c176..c11c3012fcc5 100644
> --- a/drivers/gpu/drm/drm_colorop.c
> +++ b/drivers/gpu/drm/drm_colorop.c
> @@ -68,6 +68,7 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = {
>   	{ DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
>   	{ DRM_COLOROP_MULTIPLIER, "Multiplier"},
>   	{ DRM_COLOROP_3D_LUT, "3D LUT"},
> +	{ DRM_COLOROP_FIXED_MATRIX, "Fixed Matrix"},
>   };
>   
>   static const char * const colorop_curve_1d_type_names[] = {
> @@ -90,6 +91,14 @@ static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] =
>   	{ DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, "Tetrahedral" },
>   };
>   
> +static const char * const colorop_fixed_matrix_type_names[] = {
> +	[DRM_COLOROP_FM_YCBCR601_FULL_RGB] = "YCbCr 601 Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR709_FULL_RGB] = "YCbCr 709 Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB] = "YCbCr 2020 NC Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR_LIMITED_FULL] = "YCbCr limited to full",
> +	[DRM_COLOROP_FM_RGB709_RGB2020] = "RGB709 to RGB2020",

The last two ops do not get implemented in the series, even though they 
were the original ones mentioned in the commit message. I'd suggest to 
drop them - they can get re-added once there's a testable 
implementation. Instead I'd include the limited-range ones from the 
following commit, making the series cleaner.

Just suggestions, though. So either way:

Reviewed-by: Robert Mader <robert.mader@collabora.com>

-- 
Robert Mader
Consultant Software Developer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 02/11] drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values
  2026-06-23 16:48 ` [PATCH v3 02/11] drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values Harry Wentland
@ 2026-07-03 10:17   ` Robert Mader
  0 siblings, 0 replies; 19+ messages in thread
From: Robert Mader @ 2026-07-03 10:17 UTC (permalink / raw)
  To: Harry Wentland, dri-devel, amd-gfx; +Cc: Alex Hung

Hi,

On 23.06.26 18:48, Harry Wentland wrote:
> Add three new limited-range YUV-to-RGB conversion presets to the
> Fixed Matrix colorop enum:
>
>    - DRM_COLOROP_FM_YCBCR601_LIMITED_RGB
>    - DRM_COLOROP_FM_YCBCR709_LIMITED_RGB
>    - DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB
>
> Assisted-by: Claude:claude-opus-4.6
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Reviewed-by: Alex Hung <alex.hung@amd.com>
> ---
>   drivers/gpu/drm/drm_colorop.c |  3 +++
>   include/drm/drm_colorop.h     | 30 ++++++++++++++++++++++++++++++
>   2 files changed, 33 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
> index c11c3012fcc5..9cf89153b365 100644
> --- a/drivers/gpu/drm/drm_colorop.c
> +++ b/drivers/gpu/drm/drm_colorop.c
> @@ -93,8 +93,11 @@ static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] =
>   
>   static const char * const colorop_fixed_matrix_type_names[] = {
>   	[DRM_COLOROP_FM_YCBCR601_FULL_RGB] = "YCbCr 601 Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR601_LIMITED_RGB] = "YCbCr 601 Limited to RGB",
>   	[DRM_COLOROP_FM_YCBCR709_FULL_RGB] = "YCbCr 709 Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR709_LIMITED_RGB] = "YCbCr 709 Limited to RGB",
>   	[DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB] = "YCbCr 2020 NC Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB] = "YCbCr 2020 NC Limited to RGB",
>   	[DRM_COLOROP_FM_YCBCR_LIMITED_FULL] = "YCbCr limited to full",
>   	[DRM_COLOROP_FM_RGB709_RGB2020] = "RGB709 to RGB2020",
>   };
> diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
> index 88933d5b4d8b..5c542c264a36 100644
> --- a/include/drm/drm_colorop.h
> +++ b/include/drm/drm_colorop.h
> @@ -150,6 +150,16 @@ enum drm_colorop_fixed_matrix_type {
>   	 */
>   	DRM_COLOROP_FM_YCBCR601_FULL_RGB,
>   
> +	/**
> +	 * @DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
> +	 *
> +	 * enum string "YCbCr 601 Limited to RGB"
> +	 *
> +	 * This selects the matrix that converts limited range YCbCr into RGB
> +	 * according to the BT.601 coefficients.
> +	 */
> +	DRM_COLOROP_FM_YCBCR601_LIMITED_RGB,
> +
>   	/**
>   	 * @DRM_COLOROP_FM_YCBCR709_FULL_RGB:
>   	 *
> @@ -160,6 +170,16 @@ enum drm_colorop_fixed_matrix_type {
>   	 */
>   	DRM_COLOROP_FM_YCBCR709_FULL_RGB,
>   
> +	/**
> +	 * @DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
> +	 *
> +	 * enum string "YCbCr 709 Limited to RGB"
> +	 *
> +	 * This selects the matrix that converts limited range YCbCr into RGB
> +	 * according to the BT.709 coefficients.
> +	 */
> +	DRM_COLOROP_FM_YCBCR709_LIMITED_RGB,
> +
>   	/**
>   	 * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
>   	 *
> @@ -170,6 +190,16 @@ enum drm_colorop_fixed_matrix_type {
>   	 */
>   	DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB,
>   
> +	/**
> +	 * @DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
> +	 *
> +	 * enum string "YCbCr 2020 NC Limited to RGB"
> +	 *
> +	 * This selects the matrix that converts limited range YCbCr into RGB
> +	 * according to the BT.2020 non-constant luminance coefficients.
> +	 */
> +	DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB,
> +
>   	/**
>   	 * @DRM_COLOROP_FM_YCBCR_LIMITED_FULL:
>   	 *

I'd prefer the commit to get squashed into the previous one - but either 
way:

Reviewed-by: Robert Mader <robert.mader@collabora.com>

-- 
Robert Mader
Consultant Software Developer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 03/11] drm/vkms: Add fixed matrix colorop to color pipeline
  2026-06-23 16:48 ` [PATCH v3 03/11] drm/vkms: Add fixed matrix colorop to color pipeline Harry Wentland
@ 2026-07-03 10:24   ` Robert Mader
  0 siblings, 0 replies; 19+ messages in thread
From: Robert Mader @ 2026-07-03 10:24 UTC (permalink / raw)
  To: Harry Wentland, dri-devel, amd-gfx; +Cc: Alex Hung

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 <harry.wentland@amd.com>
> Reviewed-by: Alex Hung <alex.hung@amd.com>
> ---
>   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 <robert.mader@collabora.com>

-- 
Robert Mader
Consultant Software Developer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 04/11] drm/vkms: Add atomic check and matrix handling for fixed matrix colorop
  2026-06-23 16:48 ` [PATCH v3 04/11] drm/vkms: Add atomic check and matrix handling for fixed matrix colorop Harry Wentland
@ 2026-07-03 10:32   ` Robert Mader
  0 siblings, 0 replies; 19+ messages in thread
From: Robert Mader @ 2026-07-03 10:32 UTC (permalink / raw)
  To: Harry Wentland, dri-devel, amd-gfx; +Cc: Alex Hung

Hi,

On 23.06.26 18:48, Harry Wentland wrote:
> In vkms_plane_atomic_check(), validate that when a color pipeline
> is active and the framebuffer format is YUV:
>    - The first colorop must be DRM_COLOROP_FIXED_MATRIX
>    - The fixed matrix colorop must not be bypassed
>
> In vkms_plane_atomic_update(), when a color pipeline is active,
> read the fixed_matrix_type from the first colorop state and map
> it to the appropriate (color_encoding, color_range) pair for the
> existing get_conversion_matrix_to_argb_u16() function.
>
> In apply_colorop(), add a no-op case for DRM_COLOROP_FIXED_MATRIX
> since the actual YUV-to-RGB conversion is already performed at
> format read time via the conversion matrix.
>
> Assisted-by: Claude:claude-opus-4.6
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Reviewed-by: Alex Hung <alex.hung@amd.com>
> ---
>   drivers/gpu/drm/vkms/vkms_composer.c |  6 +++
>   drivers/gpu/drm/vkms/vkms_plane.c    | 68 +++++++++++++++++++++++++++-
>   2 files changed, 72 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
> index 83d217085ad0..899120cd07ac 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -187,6 +187,12 @@ 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_FIXED_MATRIX) {
> +		/*
> +		 * Fixed Matrix is a no-op here. YUV-to-RGB conversion
> +		 * is handled at format read time via the
> +		 * conversion_matrix set in vkms_plane_atomic_update().
> +		 */
>   	}
>   }
>   
> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> index 68cb2a3335e6..4ef4cebe718b 100644
> --- a/drivers/gpu/drm/vkms/vkms_plane.c
> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> @@ -6,6 +6,7 @@
>   #include <drm/drm_atomic.h>
>   #include <drm/drm_atomic_helper.h>
>   #include <drm/drm_blend.h>
> +#include <drm/drm_colorop.h>
>   #include <drm/drm_fourcc.h>
>   #include <drm/drm_gem_atomic_helper.h>
>   #include <drm/drm_gem_framebuffer_helper.h>
> @@ -148,8 +149,56 @@ 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) {
> +		struct drm_colorop *colorop = new_state->color_pipeline;
> +		struct drm_colorop_state *colorop_state;
> +
> +		colorop_state = drm_atomic_get_new_colorop_state(state, colorop);
> +
> +		if (colorop_state && !colorop_state->bypass) {
> +			enum drm_color_encoding encoding;
> +			enum drm_color_range range;
> +
> +			switch (colorop_state->fixed_matrix_type) {
> +			case DRM_COLOROP_FM_YCBCR601_FULL_RGB:
> +				encoding = DRM_COLOR_YCBCR_BT601;
> +				range = DRM_COLOR_YCBCR_FULL_RANGE;
> +				break;
> +			case DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
> +				encoding = DRM_COLOR_YCBCR_BT601;
> +				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
> +				break;
> +			case DRM_COLOROP_FM_YCBCR709_FULL_RGB:
> +				encoding = DRM_COLOR_YCBCR_BT709;
> +				range = DRM_COLOR_YCBCR_FULL_RANGE;
> +				break;
> +			case DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
> +				encoding = DRM_COLOR_YCBCR_BT709;
> +				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
> +				break;
> +			case DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
> +				encoding = DRM_COLOR_YCBCR_BT2020;
> +				range = DRM_COLOR_YCBCR_FULL_RANGE;
> +				break;
> +			case DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
> +				encoding = DRM_COLOR_YCBCR_BT2020;
> +				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
> +				break;
> +			default:
> +				encoding = DRM_COLOR_YCBCR_BT709;
> +				range = DRM_COLOR_YCBCR_LIMITED_RANGE;
> +				break;
> +			}
> +
> +			get_conversion_matrix_to_argb_u16(fmt, encoding, range,
> +							  &vkms_plane_state->conversion_matrix);
> +		}
> +	} else {
> +		get_conversion_matrix_to_argb_u16(fmt, new_state->color_encoding,
> +						  new_state->color_range,
> +						  &vkms_plane_state->conversion_matrix);
> +	}
>   }
>   
>   static int vkms_plane_atomic_check(struct drm_plane *plane,
> @@ -175,6 +224,21 @@ static int vkms_plane_atomic_check(struct drm_plane *plane,
>   	if (ret != 0)
>   		return ret;
>   
> +	if (new_plane_state->color_pipeline && new_plane_state->fb->format->is_yuv) {
> +		struct drm_colorop *colorop = new_plane_state->color_pipeline;
> +		struct drm_colorop_state *colorop_state;
> +		if (colorop->type != DRM_COLOROP_FIXED_MATRIX)
> +
> +			return -EINVAL;
> +
> +		colorop_state = drm_atomic_get_new_colorop_state(state, colorop);
> +		if (!colorop_state)
> +			return -EINVAL;
> +
> +		if (colorop_state->bypass)
> +			return -EINVAL;
> +	}
> +
>   	return 0;
>   }
>   

This simple implementation makes sense to me and looks correct.

Reviewed-by: Robert Mader <robert.mader@collabora.com>

-- 
Robert Mader
Consultant Software Developer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 10/11] drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is bypassed
  2026-06-23 16:48 ` [PATCH v3 10/11] drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is bypassed Harry Wentland
@ 2026-07-03 10:40   ` Robert Mader
  0 siblings, 0 replies; 19+ messages in thread
From: Robert Mader @ 2026-07-03 10:40 UTC (permalink / raw)
  To: Harry Wentland, dri-devel, amd-gfx; +Cc: stable

Hi,

On 23.06.26 18:48, Harry Wentland wrote:
> When the fixed matrix colorop is bypassed, the color_space was set to
> COLOR_SPACE_UNKNOWN (0). In DC's DPP setup (dpp1_cnv_setup), the logic
> 'input_color_space ? input_color_space : color_space' treats 0 as
> 'not provided', causing it to fall back to the format-based default of
> COLOR_SPACE_YCBCR709 for YUV framebuffers. This results in an implicit
> YUV-to-RGB conversion via ICSC even when a color pipeline is active and
> the fixed matrix is bypassed.

shouldn't a commit with YUV framebuffer and fixed matrix set to bypass 
always fail, like it does in the VKMS implementation?

If this commit is only needed for RGB formats, somehow getting a 
YUV-to-RGB conversion applied to them otherwise, then I think the commit 
message should be clarified accordingly, no?

>
> Fix this by setting COLOR_SPACE_SRGB (1) instead. This is non-zero, so
> it overrides the format default. The SRGB entry in dpp_input_csc_matrix
> is an identity matrix, so ICSC performs no actual conversion, which is
> the correct behavior when the fixed matrix colorop is bypassed.
>
> Cc: stable@vger.kernel.org
> Fixes: 93d922f4833b ("drm/amd/display: Implement fixed matrix colorop color space mapping")
> Assisted-by: Copilot:claude-opus-4.6
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> ---
>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> index 561ee9a2e749..984bbfcf23f0 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> @@ -1534,7 +1534,7 @@ __set_dm_plane_colorop_fixed_matrix(struct drm_plane_state *plane_state,
>   		return -EINVAL;
>   
>   	if (colorop_state->bypass) {
> -		dc_plane_state->color_space = COLOR_SPACE_UNKNOWN;
> +		dc_plane_state->color_space = COLOR_SPACE_SRGB;
>   		return 0;
>   	}
>   

-- 
Robert Mader
Consultant Software Developer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
  2026-06-23 16:48 ` [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Harry Wentland
  2026-07-03 10:15   ` Robert Mader
@ 2026-07-03 10:52   ` Pekka Paalanen
  1 sibling, 0 replies; 19+ messages in thread
From: Pekka Paalanen @ 2026-07-03 10:52 UTC (permalink / raw)
  To: Harry Wentland; +Cc: dri-devel, amd-gfx, Chaitanya Kumar Borah, Melissa Wen

[-- Attachment #1: Type: text/plain, Size: 14313 bytes --]

On Tue, 23 Jun 2026 12:48:02 -0400
Harry Wentland <harry.wentland@amd.com> wrote:

> From: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
> 
> Introduce DRM_COLOROP_FIXED_MATRIX, a new colorop type representing a
> hardware that performs a fixed matrix operation.
> 
> Unlike CTM-based colorops, this block does not expose programmable
> coefficients. Instead, userspace selects one of the predefined
> hardware modes via a new FIXED_MATRIX_TYPE enum property. Supported modes
> include common YCbCr->RGB and RGB709->RGB2020 conversions.
> 
> v2:
>  - Naming changes (Pekka)
> 
> v3:
>  - Fix NC matrix enum name and string (Melissa)
>  - Rebase
> 
> Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
> Reviewed-by: Melissa Wen <mwen@igalia.com>
> Reviewed-by: Harry Wentland <harry.wentland@amd.com>
> ---
>  drivers/gpu/drm/drm_atomic.c      |   4 ++
>  drivers/gpu/drm/drm_atomic_uapi.c |   4 ++
>  drivers/gpu/drm/drm_colorop.c     | 106 ++++++++++++++++++++++++++++++
>  include/drm/drm_colorop.h         |  84 +++++++++++++++++++++++
>  include/uapi/drm/drm_mode.h       |  12 ++++
>  5 files changed, 210 insertions(+)
> 

Hi,

the UAPI looks good.

Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>

It's a little bit unfortunate that the colorop UAPI documentation is
embedded into kernel-private enum types' documentation.

Is RGB always full-range? The documentation could be more explicit
about that. Maybe the documentation should spell out the matrix
contents just to be clear? There are more than one form of limited
range IIRC (HDMI, JPEG, SDI). Or maybe JPEG was a different type of
full-range?

> +	 * enum string "RGB709 to RGB2020"
> +	 *
> +	 * Selects the fixed-function CSC preset that converts RGB
> +	 * (BT.709) colorimetry to RGB (BT.2020).

Why is this called a "CSC preset" rather than a matrix? This confuses
me.

Was there a conclusion from discussions around compatible pixel formats
for a specific choice of a fixed matrix? How will userspace discover
that, or will it be based on documentation and enforced as a common
requirement over all drivers?

ISTR some hardware requiring an YUV pixel format to be able to use the
YCbCr conversion matrices, or vice versa. Otherwise there is no reason
to have that limitation.


Thanks,
pq


> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 3af1b9cc9a06..ced591c4a0bd 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -925,6 +925,10 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
>  				  drm_get_colorop_lut3d_interpolation_name(colorop->lut3d_interpolation));
>  		drm_printf_indent(p, 1, "data blob id=%d\n", state->data ? state->data->base.id : 0);
>  		break;
> +	case DRM_COLOROP_FIXED_MATRIX:
> +		drm_printf_indent(p, 1, "fixed_matrix_type=%s\n",
> +				  drm_get_colorop_fixed_matrix_type_name(state->fixed_matrix_type));
> +		break;
>  	default:
>  		break;
>  	}
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index c7f80d90794c..cee4550ffdbd 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -761,6 +761,8 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
>  	} else if (property == colorop->data_property) {
>  		return drm_atomic_color_set_data_property(colorop, state,
>  							  property, val);
> +	} else if (property == colorop->fixed_matrix_type_property) {
> +		state->fixed_matrix_type = val;
>  	} else {
>  		drm_dbg_atomic(colorop->dev,
>  			       "[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
> @@ -793,6 +795,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
>  		*val = colorop->lut3d_interpolation;
>  	else if (property == colorop->data_property)
>  		*val = (state->data) ? state->data->base.id : 0;
> +	else if (property == colorop->fixed_matrix_type_property)
> +		*val = state->fixed_matrix_type;
>  	else
>  		return -EINVAL;
>  
> diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
> index c0eecde8c176..c11c3012fcc5 100644
> --- a/drivers/gpu/drm/drm_colorop.c
> +++ b/drivers/gpu/drm/drm_colorop.c
> @@ -68,6 +68,7 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = {
>  	{ DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
>  	{ DRM_COLOROP_MULTIPLIER, "Multiplier"},
>  	{ DRM_COLOROP_3D_LUT, "3D LUT"},
> +	{ DRM_COLOROP_FIXED_MATRIX, "Fixed Matrix"},
>  };
>  
>  static const char * const colorop_curve_1d_type_names[] = {
> @@ -90,6 +91,14 @@ static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] =
>  	{ DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, "Tetrahedral" },
>  };
>  
> +static const char * const colorop_fixed_matrix_type_names[] = {
> +	[DRM_COLOROP_FM_YCBCR601_FULL_RGB] = "YCbCr 601 Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR709_FULL_RGB] = "YCbCr 709 Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB] = "YCbCr 2020 NC Full to RGB",
> +	[DRM_COLOROP_FM_YCBCR_LIMITED_FULL] = "YCbCr limited to full",
> +	[DRM_COLOROP_FM_RGB709_RGB2020] = "RGB709 to RGB2020",
> +};
> +
>  /* Init Helpers */
>  
>  static int drm_plane_colorop_init(struct drm_device *dev, struct drm_colorop *colorop,
> @@ -455,6 +464,80 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
>  }
>  EXPORT_SYMBOL(drm_plane_colorop_3dlut_init);
>  
> +/**
> + * drm_plane_colorop_fixed_matrix_init - Initialize a DRM_COLOROP_FIXED_MATRIX
> + *
> + * @dev: DRM device
> + * @colorop: The drm_colorop object to initialize
> + * @plane: The associated drm_plane
> + * @funcs: control functions for the new colorop
> + * @supported_fm: A bitfield of supported drm_colorop_fixed_matrix_type enum values,
> + *               created using BIT(fixed_matrix_type) and combined with the OR '|'
> + *               operator.
> + * @flags: bitmask of misc, see DRM_COLOROP_FLAG_* defines.
> + * @return zero on success, -E value on failure
> + */
> +int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
> +					struct drm_plane *plane,
> +					const struct drm_colorop_funcs *funcs,
> +					u64 supported_fm, uint32_t flags)
> +{
> +	struct drm_prop_enum_list enum_list[DRM_COLOROP_FM_COUNT];
> +	int i, len;
> +	struct drm_property *prop;
> +	int ret;
> +
> +	if (!supported_fm) {
> +		drm_err(dev,
> +			"No supported FM type op for new Fixed Matrix colorop on [PLANE:%d:%s]\n",
> +			plane->base.id, plane->name);
> +		return -EINVAL;
> +	}
> +
> +	if ((supported_fm & -BIT(DRM_COLOROP_FM_COUNT)) != 0) {
> +		drm_err(dev, "Unknown Fixed Matrix provided on [PLANE:%d:%s]\n",
> +			plane->base.id, plane->name);
> +		return -EINVAL;
> +	}
> +
> +	ret = drm_plane_colorop_init(dev, colorop, plane, funcs, DRM_COLOROP_FIXED_MATRIX, flags);
> +	if (ret)
> +		return ret;
> +
> +	len = 0;
> +	for (i = 0; i < DRM_COLOROP_FM_COUNT; i++) {
> +		if ((supported_fm & BIT(i)) == 0)
> +			continue;
> +
> +		enum_list[len].type = i;
> +		enum_list[len].name = colorop_fixed_matrix_type_names[i];
> +		len++;
> +	}
> +
> +	if (WARN_ON(len <= 0))
> +		return -EINVAL;
> +
> +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "FIXED_MATRIX_TYPE",
> +					enum_list, len);
> +
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	colorop->fixed_matrix_type_property = prop;
> +	/*
> +	 * Default to the first supported CSC mode as provided by the driver.
> +	 * Intuitively this should be something that keeps the colorop in pixel bypass
> +	 * mode but that is already handled via the standard colorop bypass
> +	 * property.
> +	 */
> +	drm_object_attach_property(&colorop->base, colorop->fixed_matrix_type_property,
> +				   enum_list[0].type);
> +	drm_colorop_reset(colorop);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_colorop_fixed_matrix_init);
> +
>  static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop,
>  							struct drm_colorop_state *state)
>  {
> @@ -521,6 +604,13 @@ static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
>  							   &val))
>  			colorop_state->curve_1d_type = val;
>  	}
> +
> +	if (colorop->fixed_matrix_type_property) {
> +		if (!drm_object_property_get_default_value(&colorop->base,
> +							   colorop->fixed_matrix_type_property,
> +							   &val))
> +			colorop_state->fixed_matrix_type = val;
> +	}
>  }
>  
>  /**
> @@ -584,6 +674,7 @@ static const char * const colorop_type_name[] = {
>  	[DRM_COLOROP_CTM_3X4] = "3x4 Matrix",
>  	[DRM_COLOROP_MULTIPLIER] = "Multiplier",
>  	[DRM_COLOROP_3D_LUT] = "3D LUT",
> +	[DRM_COLOROP_FIXED_MATRIX] = "Fixed Matrix",
>  };
>  
>  static const char * const colorop_lu3d_interpolation_name[] = {
> @@ -640,6 +731,21 @@ const char *drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_inte
>  	return colorop_lu3d_interpolation_name[type];
>  }
>  
> +/**
> + * drm_get_colorop_fixed_matrix_type_name: return a string for fixed matrix type
> + * @type: fixed matrix type to compute name of
> + *
> + * In contrast to the other drm_get_*_name functions this one here returns a
> + * const pointer and hence is threadsafe.
> + */
> +const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type)
> +{
> +	if (WARN_ON(type >= ARRAY_SIZE(colorop_fixed_matrix_type_names)))
> +		return "unknown";
> +
> +	return colorop_fixed_matrix_type_names[type];
> +}
> +
>  /**
>   * drm_colorop_set_next_property - sets the next pointer
>   * @colorop: drm colorop
> diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
> index b4b9e4f558ab..88933d5b4d8b 100644
> --- a/include/drm/drm_colorop.h
> +++ b/include/drm/drm_colorop.h
> @@ -134,6 +134,71 @@ enum drm_colorop_curve_1d_type {
>  	DRM_COLOROP_1D_CURVE_COUNT
>  };
>  
> +/**
> + * enum drm_colorop_fixed_matrix_type - type of Fixed Matrix
> + *
> + * Describes a Fixed Matrix operation to be applied by the DRM_COLOROP_FIXED_MATRIX
> + */
> +enum drm_colorop_fixed_matrix_type {
> +	/**
> +	 * @DRM_COLOROP_FM_YCBCR601_FULL_RGB:
> +	 *
> +	 * enum string "YCbCr 601 Full to RGB"
> +	 *
> +	 * This selects the matrix that converts full range YCbCr into RGB
> +	 * according to the BT.601 coefficients.
> +	 */
> +	DRM_COLOROP_FM_YCBCR601_FULL_RGB,
> +
> +	/**
> +	 * @DRM_COLOROP_FM_YCBCR709_FULL_RGB:
> +	 *
> +	 * enum string "YCbCr 709 Full to RGB"
> +	 *
> +	 * This selects the matrix that converts full range YCbCr into RGB
> +	 * according to the BT.709 coefficients.
> +	 */
> +	DRM_COLOROP_FM_YCBCR709_FULL_RGB,
> +
> +	/**
> +	 * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
> +	 *
> +	 * enum string "YCbCr 2020 NC Full to RGB"
> +	 *
> +	 * This selects the matrix that converts full range YCbCr into RGB
> +	 * according to the BT.2020 non-constant luminance coefficients.
> +	 */
> +	DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB,
> +
> +	/**
> +	 * @DRM_COLOROP_FM_YCBCR_LIMITED_FULL:
> +	 *
> +	 * enum string "YCbCr limited to full"
> +	 *
> +	 * This selects the matrix that converts limited range YCbCr into
> +	 * full range YCbCr. Though not strictly a matrix operation but
> +	 * can be represented as one.
> +	 */
> +	DRM_COLOROP_FM_YCBCR_LIMITED_FULL,
> +
> +	/**
> +	 * @DRM_COLOROP_FM_RGB709_RGB2020:
> +	 *
> +	 * enum string "RGB709 to RGB2020"
> +	 *
> +	 * Selects the fixed-function CSC preset that converts RGB
> +	 * (BT.709) colorimetry to RGB (BT.2020).
> +	 */
> +	DRM_COLOROP_FM_RGB709_RGB2020,
> +
> +	/**
> +	 * @DRM_COLOROP_FM_COUNT:
> +	 *
> +	 * enum value denoting the size of the enum
> +	 */
> +	DRM_COLOROP_FM_COUNT
> +};
> +
>  /**
>   * struct drm_colorop_state - mutable colorop state
>   */
> @@ -183,6 +248,13 @@ struct drm_colorop_state {
>  	 */
>  	struct drm_property_blob *data;
>  
> +	/**
> +	 * @fixed_matrix_type:
> +	 *
> +	 * Type of Fixed Matrix operation.
> +	 */
> +	enum drm_colorop_fixed_matrix_type fixed_matrix_type;
> +
>  	/** @state: backpointer to global drm_atomic_commit */
>  	struct drm_atomic_commit *state;
>  };
> @@ -368,6 +440,13 @@ struct drm_colorop {
>  	 */
>  	struct drm_property *data_property;
>  
> +	/**
> +	 * @fixed_matrix_type_property:
> +	 *
> +	 * Sub-type for DRM_COLOROP_FIXED_MATRIX type.
> +	 */
> +	struct drm_property *fixed_matrix_type_property;
> +
>  	/**
>  	 * @next_property:
>  	 *
> @@ -424,6 +503,10 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
>  				 uint32_t lut_size,
>  				 enum drm_colorop_lut3d_interpolation_type interpolation,
>  				 uint32_t flags);
> +int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
> +					struct drm_plane *plane,
> +					const struct drm_colorop_funcs *funcs,
> +					u64 supported_fm, uint32_t flags);
>  
>  struct drm_colorop_state *
>  drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop);
> @@ -482,6 +565,7 @@ drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_ty
>  
>  const char *
>  drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type);
> +const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type);
>  
>  void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next);
>  
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 381a3e857d4e..bff6dba08d50 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -954,6 +954,18 @@ enum drm_colorop_type {
>  	 *         color = lut3d[index]
>  	 */
>  	DRM_COLOROP_3D_LUT,
> +
> +	/**
> +	 * @DRM_COLOROP_FIXED_MATRIX:
> +	 *
> +	 * enum string "Fixed Matrix"
> +	 *
> +	 * A Colorop block that performs a pre-defined matrix operation selected
> +	 * via the FIXED_MATRIX_TYPE enum property. The driver advertises the supported
> +	 * operations through this property.
> +	 */
> +	DRM_COLOROP_FIXED_MATRIX,
> +
>  };
>  
>  /**


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2026-07-03 10:52 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-23 16:48 [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Harry Wentland
2026-06-23 16:48 ` [PATCH v3 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Harry Wentland
2026-07-03 10:15   ` Robert Mader
2026-07-03 10:52   ` Pekka Paalanen
2026-06-23 16:48 ` [PATCH v3 02/11] drm/colorop: Add limited-range YUV-to-RGB fixed matrix enum values Harry Wentland
2026-07-03 10:17   ` Robert Mader
2026-06-23 16:48 ` [PATCH v3 03/11] drm/vkms: Add fixed matrix colorop to color pipeline Harry Wentland
2026-07-03 10:24   ` Robert Mader
2026-06-23 16:48 ` [PATCH v3 04/11] drm/vkms: Add atomic check and matrix handling for fixed matrix colorop Harry Wentland
2026-07-03 10:32   ` Robert Mader
2026-06-23 16:48 ` [PATCH v3 05/11] drm/amd/display: Add fixed matrix colorop to color pipeline Harry Wentland
2026-06-23 16:48 ` [PATCH v3 06/11] drm/amd/display: Implement fixed matrix colorop color space mapping Harry Wentland
2026-06-23 16:48 ` [PATCH v3 07/11] drm/amd/display: Use GAMCOR for first TF if YUV conversion is needed Harry Wentland
2026-06-23 16:48 ` [PATCH v3 08/11] drm/amd/display: Check actual state during commit_tail Harry Wentland
2026-06-23 16:48 ` [PATCH v3 09/11] drm/amd/display: Set color_space to plane_infos Harry Wentland
2026-06-23 16:48 ` [PATCH v3 10/11] drm/amd/display: Set COLOR_SPACE_SRGB when fixed matrix colorop is bypassed Harry Wentland
2026-07-03 10:40   ` Robert Mader
2026-06-23 16:48 ` [PATCH v3 11/11] drm/amd/display: Force GAMCOR for subsampled surfaces with PQ/Gamma22/HLG Harry Wentland
2026-07-03  9:44 ` [PATCH v3 00/11] YUV conversion colorop with amdgpu and VKMS Robert Mader

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.