Skip to content

Implement generic KMS color pipeline support#2218

Draft
k2naveen wants to merge 18 commits into
ValveSoftware:masterfrom
k2naveen:kms_color_v2_extended
Draft

Implement generic KMS color pipeline support#2218
k2naveen wants to merge 18 commits into
ValveSoftware:masterfrom
k2naveen:kms_color_v2_extended

Conversation

@k2naveen

@k2naveen k2naveen commented Jun 15, 2026

Copy link
Copy Markdown

This MR is on top of Melissa's effort migrate color mgmt from AMD driver specific properties to new KMS color API and replaces AMD-specific vendor enum matching with a generic colorop chain walker using FindByType(type, index), matching the pattern used by KWin and Weston. Any unhandled op is bypassed, keeping hardware state clean.

Two paths are supported:

  • 3D LUT path (e.g. AMD): shaper curve + shaper LUT + 3D LUT + blend curve, unchanged in behavior.
  • 1D fallback path (e.g. Intel): 1D_LUT degamma → CTM_3X4 gamut mapping → CRTC GAMMA_LUT for OETF (pipe gamma applied after blending, matching the "offload-blend-to-output" design in Weston).

LUT blobs are sized to the hardware's SIZE/GAMMA_LUT_SIZE property rather than hardcoded entry counts, so any driver advertising a COLOR_PIPELINE with 1D or 3D LUT colorops is handled correctly.

Tested on Intel Arc (Xe2) with HDR and SDR output.

emersion and others added 15 commits June 15, 2026 09:05
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Store the value of the color pipeline enum for a given plane that fits
color pipeline needs. So that we can set plane COLOR_PIPELINE property
with this value.

Signed-off-by: Melissa Wen <mwen@igalia.com>
Check if there is any color pipeline with the properties needed for
plane color mgmt.

Signed-off-by: Melissa Wen <mwen@igalia.com>
Add CURVE_1D_TYPE property to colorop, helper for degamma curve using
DRM_COLOROP_* predefined curve instead of AMD_TRANSFER_FUNCTIONs, add
set degamma 1D curve accordingly

Signed-off-by: Melissa Wen <mwen@igalia.com>
Create helper to use DRM_COLOROP curves instead of
AMD_TRANSFER_FUNCTIONs and set properties accordingly

Signed-off-by: Melissa Wen <mwen@igalia.com>
Create a helper to translate output tf of AMD_TRANSFER_FUNCTION enum
type to DRM_COLOROP type

Signed-off-by: Melissa Wen <mwen@igalia.com>
Gamescope already use 3x4 matrix, so doesn't needed additional helper.

Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Instead of struct drm_color_lut, shaper and 3D LUTs follow struct
drm_color_lut32, which means 32-bit for each channel, not 16-bit
anymore. Create a helper to make possible reuse LUTs already created for
AMD driver-specific color properties.

Assisted-by: Claude Code <Sonnet 4.6>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Match the existing behavior of the legacy AMD plane properties, which
reset layers to DEFAULT without color management applied to them.

Otherwise, stale color pipeline state from the previous scanout frame
persists during composition, resulting in double color management and an
overly-saturated output image.

Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
@k2naveen k2naveen changed the title Implement generic KMS color pipeline support (Intel + AMD) Implement generic KMS color pipeline support Jun 15, 2026
k2naveen added 3 commits June 16, 2026 11:36
…yout

The previous code validated that the COLOR_PIPELINE colorop chain is
exactly 8 ops with AMD-specific types in a fixed order.  Any other
shape silently returned {} causing COLOR_PIPELINE=Bypass for any
non-AMD hardware that advertises the property.

Replace the hard shape check with a type-based field assignment: walk
the colorop chain and assign each named CDRMColorPipeline field to the
first colorop whose DRM TYPE matches.  Fields with no matching op in
the chain are left nullptr.

Add null-checks before every named field access in the pipeline
programming code so that hardware with fewer ops (e.g. Intel's
1D_LUT → CTM_3X4 → 1D_LUT) is handled gracefully: present ops are
programmed, absent ops are silently skipped.

bUseShaperAnd3DLUT now requires both shaperLut and lut3D to be
non-null so the AMD 3D LUT path cannot be accidentally enabled on
pipelines that don't have a 3D LUT.

Assisted-by: Claude:claude-sonnet-4.6
Signed-off-by: Naveen Kumar <naveen1.kumar@intel.com>
Replace the CDRMColorPipeline named fields (degamma, HDRMult, CTM, …)
with a generic ops vector and a FindByType(type, index) lookup method.

This mirrors the search-by-type approach used in KWin and Weston:
callers locate the nth op of a given DRM type by walking the chain,
then bypass every op not explicitly handled via a catch-all loop at
the end of the programming block.

No behaviour change for AMD hardware — the same ops are programmed in
the same way.  The approach is now vendor-agnostic: any pipeline that
exposes the required DRM types in its chain will be handled correctly
regardless of chain length or ordering.

bUseShaperAnd3DLUT is additionally gated on the shaperlut and lut3d
colorop blobs being populated so that it can only fire when the full
colour-management LUT chain has been computed.

Assisted-by: Claude:claude-sonnet-4.6
Signed-off-by: Naveen Kumar <naveen1.kumar@intel.com>
For hardware that exposes a color pipeline without a 3D LUT (e.g. Intel
Arc: 1D_LUT → CTM_3X4 → 1D_LUT), add a fallback path that provides
correct HDR and SDR color output:

 - Plane 1D_LUT (1st, degamma):  EOTF decode (sRGB→linear or PQ→linear)
 - Plane CTM_3X4 (gamut):        BT.709→BT.2020 when HDR output and
                                 BT.709 source content; bypassed otherwise
 - Plane 1D_LUT (2nd, POST_CSC): always bypassed
 - CRTC GAMMA_LUT (pipe gamma):  OETF encode (linear→PQ for HDR,
                                 linear→sRGB for SDR) applied after all
                                 planes are composited

The OETF is applied at the CRTC level rather than per-plane so that it
fires once after blending — matching the offload-blend-to-output design
in Weston.  On AMD the CRTC GAMMA_LUT is left at 0 (AMD uses
AMD_CRTC_REGAMMA_TF instead).

The auto-gamut CTM (BT.709→BT.2020) is gated on pLut3DOp == nullptr so
it is never injected on AMD where the 3D LUT already encodes the full
gamut+OETF transform.

Implementation details:
 - CDRMColorOp gains a SIZE property so that 1D LUT blobs are generated
   at the exact entry count the driver expects (Intel: 128 degamma,
   1024 GAMMA_LUT) rather than a hardcoded AMD count.
 - CDRMCRTC gains a GAMMA_LUT_SIZE property read at RefreshState time.
 - drm_state_t gains gamut_ctm_colorop_id (cached BT.709→BT.2020 blob)
   and pipe_gamma_id (CRTC GAMMA_LUT blob); pipegamma_colorop_id is
   removed.
 - make_pipe_gamma_blob() generates drm_color_lut (U0.16) blobs for
   the CRTC GAMMA_LUT, distinct from the U0.32 colorop blobs.
 - CRTC GAMMA_LUT is set after drm_prepare_liftoff() returns, once
   pipe_gamma_id is known.

Assisted-by: Claude:claude-sonnet-4.6
Signed-off-by: Naveen Kumar <naveen1.kumar@intel.com>
@k2naveen k2naveen force-pushed the kms_color_v2_extended branch from 93ea4f6 to d8abde7 Compare June 16, 2026 11:55
@matte-schwartz

Copy link
Copy Markdown

Thanks for this, I'll test this on Lunar Lake next time I have a chance. I should hopefully be getting access to a Panther Lake platform soon as well.

@matte-schwartz

Copy link
Copy Markdown

This resolves the crash, but it looks like something is messed up with the composition pipeline that results in an extremely overexposed output image.

Scanout Composition (gamescopectl composite_force 1)
IMG_0846 IMG_0847

@k2naveen

k2naveen commented Jun 30, 2026

Copy link
Copy Markdown
Author

This resolves the crash, but it looks like something is messed up with the composition pipeline that results in an extremely overexposed output image.

thanks, I will check and send the fix soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants