Re: [PATCH v4 01/11] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
"Borah, Chaitanya Kumar" <[email protected]> Fri, 31 Jul 2026 10:04:53 +0530
| Newsgroups | org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <[email protected]> |
On 7/31/2026 1:57 AM, Harry Wentland wrote: > > > 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. > Sure Harry, makes sense. We will try to get one user mode implementation soon. > 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. > Ack, sorry for missing Pekka's comment the first time. I will take them into account when I create a patch for the colorops that Intel needs. == Chaitnaya > 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 >