> -----Original Message----- > From: dri-devel <[email protected]> On Behalf Of Uma > Shankar > Sent: Wednesday, July 2, 2025 2:50 PM > To: [email protected]; [email protected]; dri- > [email protected] > Cc: Borah, Chaitanya Kumar <[email protected]>; > [email protected]; [email protected]; > [email protected]; [email protected]; [email protected]; > [email protected]; [email protected]; > [email protected]; Sharma, Swati2 <[email protected]>; > [email protected]; Shankar, Uma <[email protected]> > Subject: [v5 23/24] drm/i915/color: Create color pipeline with > multisegmented LUT > > From: Chaitanya Kumar Borah <[email protected]> > > Add a color pipeline with three colorops in the sequence > > 1D LUT MULTSEG - CTM - 1D LUT MULTSEG > > This pipeline can be used to do any color space conversion or HDR tone > mapping > > Signed-off-by: Uma Shankar <[email protected]> > Signed-off-by: Chaitanya Kumar Borah <[email protected]> > --- > drivers/gpu/drm/i915/display/intel_color.c | 185 +++++++++++++++++++++ > drivers/gpu/drm/i915/display/intel_color.h | 1 + > 2 files changed, 186 insertions(+) > > diff --git a/drivers/gpu/drm/i915/display/intel_color.c > b/drivers/gpu/drm/i915/display/intel_color.c > index 689bc4f4ce25..cf2e1e3653b2 100644 > --- a/drivers/gpu/drm/i915/display/intel_color.c > +++ b/drivers/gpu/drm/i915/display/intel_color.c > @@ -4311,6 +4311,139 @@ static const struct intel_color_funcs > ilk_color_funcs = { > .get_config = ilk_get_config, > }; > > +static const struct drm_color_lut_range xelpd_degamma_hdr[] = { > + /* segment 1 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 128, > + .start = 0, .end = (1 << 24) - 1, > + .norm_factor = (1 << 24), > + .precision = { > + .intp = 0, > + .fracp = 24, > + }, > + }, > + /* segment 2 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 1, > + .start = (1 << 24), .end = (1 << 24), > + .norm_factor = (1 << 24), > + .precision = { > + .intp = 3, > + .fracp = 24, > + }, > + }, > + /* Segment 3 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 1, > + .start = 3 * (1 << 24), .end = 3 * (1 << 24), > + .norm_factor = (1 << 24), > + .precision = { > + .intp = 3, > + .fracp = 24, > + }, > + }, > + /* Segment 4 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 1, > + .start = 7 * (1 << 24), .end = 7 * (1 << 24), > + .norm_factor = (1 << 24), > + .precision = { > + .intp = 3, > + .fracp = 24, > + }, > + } > +}; > + > +/* FIXME input bpc? */ > +static const struct drm_color_lut_range xelpd_gamma_hdr[] = { > + /* segment 1 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 9, > + .start = 0, .end = 8, > + .norm_factor = 8 * 32, > + .precision = { > + .intp = 0, > + .fracp = 24, > + }, > + }, > + /* segment 2 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 30, > + .start = 8 * 2, .end = 8 * (32 - 1), > + .norm_factor = 8 * 32, > + .precision = { > + .intp = 0, > + .fracp = 24, > + }, > + }, > + /* segment 3 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 1, > + .start = 8 * 32, .end = 8 * 32, > + .norm_factor = 8 * 32, > + .precision = { > + .intp = 3, > + .fracp = 24, > + }, > + }, > + /* segment 4 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 1, > + .start = 3 * 8 * 32, .end = 3 * 8 * 32, > + .norm_factor = 8 * 32, > + .precision = { > + .intp = 3, > + .fracp = 24, > + }, > + }, > + /* segment 5 */ > + { > + .flags = > (DRM_COLOROP_1D_LUT_MULTSEG_REFLECT_NEGATIVE | > + DRM_COLOROP_1D_LUT_MULTSEG_INTERPOLATE > | > + > DRM_COLOROP_1D_LUT_MULTSEG_SINGLE_CHANNEL | > + > DRM_COLOROP_1D_LUT_MULTSEG_NON_DECREASING), > + .count = 1, > + .start = 7 * 8 * 32, .end = 7 * 8 * 32, > + .norm_factor = 8 * 32, > + .precision = { > + .intp = 3, > + .fracp = 24, > + }, > + }, > +}; > + > /* TODO: Move to another file */ > static void > intel_color_load_plane_csc_matrix(struct intel_dsb *dsb, @@ -4424,6 > +4557,52 @@ int intel_plane_tf_pipeline_init(struct drm_plane *plane, struct > drm_prop_enum_l > return 0; > } > > +int intel_plane_tf_multseg_pipeline_init(struct drm_plane *plane, > +struct drm_prop_enum_list *list) { Need to rethink the name Regards, Suraj Kandpal > + struct intel_plane_colorop *colorop; > + struct drm_device *dev = plane->dev; > + int ret; > + struct drm_colorop *prev_op; > + > + colorop = intel_plane_colorop_create(CB_PLANE_PRE_CSC_LUT); > + > + ret = drm_plane_colorop_curve_1d_lut_multseg_init(dev, &colorop- > >base, > + plane, > xelpd_degamma_hdr, > + > sizeof(xelpd_degamma_hdr), > + > DRM_COLOROP_FLAG_ALLOW_BYPASS); > + if (ret) > + return ret; > + > + list->type = colorop->base.base.id; > + list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", > +colorop->base.base.id); > + > + /* TODO: handle failures and clean up*/ > + prev_op = &colorop->base; > + > + colorop = intel_plane_colorop_create(CB_PLANE_CSC); > + > + ret = drm_plane_colorop_ctm_3x4_init(dev, &colorop->base, plane, > + > DRM_COLOROP_FLAG_ALLOW_BYPASS); > + if (ret) > + return ret; > + > + drm_colorop_set_next_property(prev_op, &colorop->base); > + > + prev_op = &colorop->base; > + > + colorop = intel_plane_colorop_create(CB_PLANE_POST_CSC_LUT); > + ret = drm_plane_colorop_curve_1d_lut_multseg_init(dev, &colorop- > >base, > + plane, > xelpd_gamma_hdr, > + > sizeof(xelpd_gamma_hdr), > + > DRM_COLOROP_FLAG_ALLOW_BYPASS); > + if (ret) > + return ret; > + > + drm_colorop_set_next_property(prev_op, &colorop->base); > + > + return 0; > +} > + > int intel_plane_color_init(struct drm_plane *plane) { > struct drm_device *dev = plane->dev; > @@ -4448,6 +4627,12 @@ int intel_plane_color_init(struct drm_plane > *plane) > return ret; > len++; > > + /* Create Pipeline with Multi-segmented LUT */ > + ret = intel_plane_tf_multseg_pipeline_init(plane, &pipelines[len]); > + if (ret) > + return ret; > + len++; > + > /* Create COLOR_PIPELINE property and attach */ > prop = drm_property_create_enum(dev, > DRM_MODE_PROP_ATOMIC, > "COLOR_PIPELINE", > diff --git a/drivers/gpu/drm/i915/display/intel_color.h > b/drivers/gpu/drm/i915/display/intel_color.h > index 420d596dbbae..1808b64a6903 100644 > --- a/drivers/gpu/drm/i915/display/intel_color.h > +++ b/drivers/gpu/drm/i915/display/intel_color.h > @@ -52,4 +52,5 @@ int intel_plane_tf_pipeline_init(struct drm_plane > *plane, struct drm_prop_enum_l int intel_plane_color_init(struct drm_plane > *plane); void intel_color_plane_program_pipeline(struct intel_dsb *dsb, > const struct intel_plane_state > *plane_state); > +int intel_plane_tf_multseg_pipeline_init(struct drm_plane *plane, > +struct drm_prop_enum_list *list); > #endif /* __INTEL_COLOR_H__ */ > -- > 2.42.0
