Re: [PATCH v4 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
Harry Wentland <[email protected]> Thu, 30 Jul 2026 16:27:27 -0400
| Newsgroups | org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <[email protected]> |
On 2026-07-30 06:59, Pekka Paalanen wrote: > On Wed, 22 Jul 2026 09:45:57 -0400 > Harry Wentland <[email protected]> wrote: > >> From: Chaitanya Kumar Borah <[email protected]> >> >> 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. >> >> v4: >> - Add limited-range YCbCr-RGB conversion matrix enums (Robert) >> - Document matrix values (Pekka) >> - Clarify RGB709 to RGB2020 is a full-range matrix (Pekka) >> - Fix confusing "CSC preset" doc (Pekka) >> >> v2: >> - Naming changes (Pekka) >> >> v3: >> - Fix NC matrix enum name and string (Melissa) >> - Rebase >> >> Co-developed-by: Harry Wentland <[email protected]> >> Signed-off-by: Chaitanya Kumar Borah <[email protected]> >> Signed-off-by: Harry Wentland <[email protected]> >> Reviewed-by: Melissa Wen <[email protected]> >> Reviewed-by: Harry Wentland <[email protected]> >> Reviewed-by: Robert Mader <[email protected]> >> --- >> drivers/gpu/drm/drm_atomic.c | 4 + >> drivers/gpu/drm/drm_atomic_uapi.c | 7 ++ >> drivers/gpu/drm/drm_colorop.c | 109 ++++++++++++++++++++ >> include/drm/drm_colorop.h | 159 ++++++++++++++++++++++++++++++ >> include/uapi/drm/drm_mode.h | 12 +++ >> 5 files changed, 291 insertions(+) > >> diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c >> index 682fcc651525..e7ccf7d053b8 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,17 @@ 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_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 224fae40ed2b..92eb6463c39f 100644 >> --- a/include/drm/drm_colorop.h >> +++ b/include/drm/drm_colorop.h >> @@ -134,6 +134,146 @@ 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" >> + * >> + * Converts full-range YCbCr into full-range RGB using the BT.601 >> + * coefficients. Y is normalized to [0, 1] and Cb, Cr are centered >> + * at 0 (the nominal 0.5 offset removed) before the matrix:: >> + * >> + * | R | | 1.0 0.000000 1.402000 | | Y | >> + * | G | = | 1.0 -0.344136 -0.714136 | x | Cb | >> + * | B | | 1.0 1.772000 0.000000 | | Cr | >> + */ >> + DRM_COLOROP_FM_YCBCR601_FULL_RGB, >> + >> + /** >> + * @DRM_COLOROP_FM_YCBCR601_LIMITED_RGB: >> + * >> + * enum string "YCbCr 601 Limited to RGB" >> + * >> + * Converts limited- (narrow-) range YCbCr into full-range RGB using >> + * the BT.601 coefficients. Before the matrix Y is offset by 16/255 >> + * and Cb, Cr are centered at 0, following the studio-range >> + * convention of ITU-R BT.601:: >> + * >> + * | R | | 1.164384 0.000000 1.596027 | | Y - 16/255 | >> + * | G | = | 1.164384 -0.391762 -0.812968 | x | Cb | >> + * | B | | 1.164384 2.017232 0.000000 | | Cr | >> + */ >> + DRM_COLOROP_FM_YCBCR601_LIMITED_RGB, >> + >> + /** >> + * @DRM_COLOROP_FM_YCBCR709_FULL_RGB: >> + * >> + * enum string "YCbCr 709 Full to RGB" >> + * >> + * Converts full-range YCbCr into full-range RGB using the BT.709 >> + * coefficients. Y is normalized to [0, 1] and Cb, Cr are centered >> + * at 0 (the nominal 0.5 offset removed) before the matrix:: >> + * >> + * | R | | 1.0 0.000000 1.574800 | | Y | >> + * | G | = | 1.0 -0.187324 -0.468124 | x | Cb | >> + * | B | | 1.0 1.855600 0.000000 | | Cr | >> + */ >> + DRM_COLOROP_FM_YCBCR709_FULL_RGB, >> + >> + /** >> + * @DRM_COLOROP_FM_YCBCR709_LIMITED_RGB: >> + * >> + * enum string "YCbCr 709 Limited to RGB" >> + * >> + * Converts limited- (narrow-) range YCbCr into full-range RGB using >> + * the BT.709 coefficients. Before the matrix Y is offset by 16/255 >> + * and Cb, Cr are centered at 0, following the studio-range >> + * convention of ITU-R BT.709:: >> + * >> + * | R | | 1.164384 0.000000 1.792741 | | Y - 16/255 | >> + * | G | = | 1.164384 -0.213249 -0.532909 | x | Cb | >> + * | B | | 1.164384 2.112402 0.000000 | | Cr | >> + */ >> + DRM_COLOROP_FM_YCBCR709_LIMITED_RGB, >> + >> + /** >> + * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB: >> + * >> + * enum string "YCbCr 2020 NC Full to RGB" >> + * >> + * Converts full-range YCbCr into full-range RGB using the BT.2020 >> + * non-constant luminance coefficients. Y is normalized to [0, 1] >> + * and Cb, Cr are centered at 0 (the nominal 0.5 offset removed) >> + * before the matrix:: >> + * >> + * | R | | 1.0 0.000000 1.474600 | | Y | >> + * | G | = | 1.0 -0.164553 -0.571353 | x | Cb | >> + * | B | | 1.0 1.881400 0.000000 | | Cr | >> + */ >> + DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB, >> + >> + /** >> + * @DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB: >> + * >> + * enum string "YCbCr 2020 NC Limited to RGB" >> + * >> + * Converts limited- (narrow-) range YCbCr into full-range RGB using >> + * the BT.2020 non-constant luminance coefficients. Before the matrix >> + * Y is offset by 16/255 and Cb, Cr are centered at 0, following the >> + * studio-range convention of ITU-R BT.2020:: >> + * >> + * | R | | 1.164384 0.000000 1.678674 | | Y - 16/255 | >> + * | G | = | 1.164384 -0.187326 -0.650424 | x | Cb | >> + * | B | | 1.164384 2.141772 0.000000 | | Cr | >> + */ >> + DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB, >> + >> + /** >> + * @DRM_COLOROP_FM_YCBCR_LIMITED_FULL: >> + * >> + * enum string "YCbCr limited to full" >> + * >> + * Converts limited- (narrow-) range YCbCr into full-range YCbCr. >> + * Though not strictly a matrix operation it can be represented as >> + * one. Luma is expanded by 255/219 and chroma by 255/224, keeping >> + * the black level (16/255) and chroma neutral point (0.5) fixed:: >> + * >> + * | Y' | | 1.164384 0.000000 0.000000 | | Y - 16/255 | >> + * | Cb'-0.5 | = | 0.000000 1.138393 0.000000 | x | Cb - 0.5 | >> + * | Cr'-0.5 | | 0.000000 0.000000 1.138393 | | Cr - 0.5 | >> + */ > > Hi Harry, > > the prime notation (Y') is often used to signify an electrical domain > while in the same context stimulus variables without prime signify an > optical domain. Using both forms here might cause some confusion. > Instead of an equals sign, maybe you could use an arrow to avoid having > to rename all YCbCr variables? (e.g. x ← x + 1) > > About the chroma offset for both ranges on all coefficients; it depends > on the number of bits per channel B such that > > N = 1 << B > offset = (N / 2) / (N - 1) > > I assume the drivers and hardware get this right, but I feel a little > uncomfortable letting this approximation into the documentation since, > strictly speaking, it's incorrect. > I'm dropping DRM_COLOROP_FM_YCBCR_LIMITED_FULL and DRM_COLOROP_FM_RGB709_RGB2020 from v5 because we don't have any good non-IGT usermode testing these currently, to my knowledge. Chaitanya, I expect you'll re-add them for your Intel series. Make sure to take Pekka's comments into account then. Would like to see how these fit into any compositor implementation. Harry > >> + DRM_COLOROP_FM_YCBCR_LIMITED_FULL, >> + >> + /** >> + * @DRM_COLOROP_FM_RGB709_RGB2020: >> + * >> + * enum string "RGB709 to RGB2020" >> + * >> + * Selects the matrix that converts full-range RGB with BT.709 >> + * primaries to full-range RGB with BT.2020 primaries. The >> + * coefficients match the RGB-to-RGB conversion defined in >> + * ITU-R BT.2087:: >> + * >> + * | R2020 | | 0.6274 0.3293 0.0433 | | R709 | >> + * | G2020 | = | 0.0691 0.9195 0.0114 | x | G709 | >> + * | B2020 | | 0.0164 0.0880 0.8956 | | B709 | >> + */ >> + DRM_COLOROP_FM_RGB709_RGB2020, >> + >> + /** >> + * @DRM_COLOROP_FM_COUNT: >> + * >> + * enum value denoting the size of the enum >> + */ >> + DRM_COLOROP_FM_COUNT >> +}; > > I have verified all the matrices listed above. > > I would prefer to see the notational issues addressed, but with or > without: > > Reviewed-by: Pekka Paalanen <[email protected]> > > > Thanks, > pq