diff options
| author | Harry Wentland <harry.wentland@amd.com> | 2025-11-14 17:02:08 -0700 |
|---|---|---|
| committer | Simon Ser <contact@emersion.fr> | 2025-11-26 23:09:14 +0100 |
| commit | 7fa3ee8c0a79b7a8b5fae422ca29da2fde6821ba (patch) | |
| tree | c033aecdd105434b342dcbc7e5a86d9bba58c217 | |
| parent | 68186c7375ace5597383115cd3781ac8465dac99 (diff) | |
drm/colorop: Define LUT_1D interpolation
We want to make sure userspace is aware of the 1D LUT
interpolation. While linear interpolation is common it
might not be supported on all HW. Give driver implementers
a way to specify their interpolation.
Reviewed-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Sebastian Wick <sebastian.wick@redhat.com>
Signed-off-by: Simon Ser <contact@emersion.fr>
Link: https://patch.msgid.link/20251115000237.3561250-44-alex.hung@amd.com
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_atomic_uapi.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_colorop.c | 37 | ||||
| -rw-r--r-- | include/drm/drm_colorop.h | 21 | ||||
| -rw-r--r-- | include/uapi/drm/drm_mode.h | 13 |
6 files changed, 79 insertions, 4 deletions
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 33907cc8e1b3..e9363814d666 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 @@ -126,7 +126,8 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr goto cleanup; } - ret = drm_plane_colorop_curve_1d_lut_init(dev, ops[i], plane, MAX_COLOR_LUT_ENTRIES); + ret = drm_plane_colorop_curve_1d_lut_init(dev, ops[i], plane, MAX_COLOR_LUT_ENTRIES, + DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR); if (ret) goto cleanup; @@ -156,7 +157,8 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr goto cleanup; } - ret = drm_plane_colorop_curve_1d_lut_init(dev, ops[i], plane, MAX_COLOR_LUT_ENTRIES); + ret = drm_plane_colorop_curve_1d_lut_init(dev, ops[i], plane, MAX_COLOR_LUT_ENTRIES, + DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR); if (ret) goto cleanup; diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 45243d05a7fd..e49d2442fa12 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -796,6 +796,8 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p, break; case DRM_COLOROP_1D_LUT: drm_printf(p, "\tsize=%d\n", colorop->size); + drm_printf(p, "\tinterpolation=%s\n", + drm_get_colorop_lut1d_interpolation_name(colorop->lut1d_interpolation)); drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0); break; case DRM_COLOROP_CTM_3X4: diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 874dcf8dd14f..64e49338e284 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -726,6 +726,8 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, { if (property == colorop->bypass_property) { state->bypass = val; + } else if (property == colorop->lut1d_interpolation_property) { + colorop->lut1d_interpolation = val; } else if (property == colorop->curve_1d_type_property) { state->curve_1d_type = val; } else if (property == colorop->multiplier_property) { @@ -753,6 +755,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, *val = colorop->type; else if (property == colorop->bypass_property) *val = state->bypass; + else if (property == colorop->lut1d_interpolation_property) + *val = colorop->lut1d_interpolation; else if (property == colorop->curve_1d_type_property) *val = state->curve_1d_type; else if (property == colorop->multiplier_property) diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index be99af98fd6c..f9717d809829 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -78,6 +78,10 @@ static const char * const colorop_curve_1d_type_names[] = { [DRM_COLOROP_1D_CURVE_BT2020_OETF] = "BT.2020 OETF", }; +static const struct drm_prop_enum_list drm_colorop_lut1d_interpolation_list[] = { + { DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, "Linear" }, +}; + /* Init Helpers */ static int drm_plane_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, @@ -273,10 +277,12 @@ static int drm_colorop_create_data_prop(struct drm_device *dev, struct drm_color * @colorop: The drm_colorop object to initialize * @plane: The associated drm_plane * @lut_size: LUT size supported by driver + * @interpolation: 1D LUT interpolation type * @return zero on success, -E value on failure */ int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop, - struct drm_plane *plane, uint32_t lut_size) + struct drm_plane *plane, uint32_t lut_size, + enum drm_colorop_lut1d_interpolation_type interpolation) { struct drm_property *prop; int ret; @@ -296,6 +302,17 @@ int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_color drm_object_attach_property(&colorop->base, colorop->size_property, lut_size); colorop->size = lut_size; + /* interpolation */ + prop = drm_property_create_enum(dev, 0, "LUT1D_INTERPOLATION", + drm_colorop_lut1d_interpolation_list, + ARRAY_SIZE(drm_colorop_lut1d_interpolation_list)); + if (!prop) + return -ENOMEM; + + colorop->lut1d_interpolation_property = prop; + drm_object_attach_property(&colorop->base, prop, interpolation); + colorop->lut1d_interpolation = interpolation; + /* data */ ret = drm_colorop_create_data_prop(dev, colorop); if (ret) @@ -449,6 +466,9 @@ static const char * const colorop_type_name[] = { [DRM_COLOROP_CTM_3X4] = "3x4 Matrix", [DRM_COLOROP_MULTIPLIER] = "Multiplier", }; +static const char * const colorop_lut1d_interpolation_name[] = { + [DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR] = "Linear", +}; const char *drm_get_colorop_type_name(enum drm_colorop_type type) { @@ -467,6 +487,21 @@ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type ty } /** + * drm_get_colorop_lut1d_interpolation_name: return a string for interpolation type + * @type: interpolation 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_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type) +{ + if (WARN_ON(type >= ARRAY_SIZE(colorop_lut1d_interpolation_name))) + return "unknown"; + + return colorop_lut1d_interpolation_name[type]; +} + +/** * drm_colorop_set_next_property - sets the next pointer * @colorop: drm colorop * @next: next colorop diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index a4f6a22fa1f9..0e1a5e9d26f3 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -272,6 +272,21 @@ struct drm_colorop { uint32_t size; /** + * @lut1d_interpolation: + * + * Read-only + * Interpolation for DRM_COLOROP_1D_LUT + */ + enum drm_colorop_lut1d_interpolation_type lut1d_interpolation; + + /** + * @lut1d_interpolation_property: + * + * Read-only property for DRM_COLOROP_1D_LUT interpolation + */ + struct drm_property *lut1d_interpolation_property; + + /** * @curve_1d_type_property: * * Sub-type for DRM_COLOROP_1D_CURVE type. @@ -340,7 +355,8 @@ void drm_colorop_cleanup(struct drm_colorop *colorop); int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane, u64 supported_tfs); int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop, - struct drm_plane *plane, uint32_t lut_size); + struct drm_plane *plane, uint32_t lut_size, + enum drm_colorop_lut1d_interpolation_type interpolation); int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane); int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop, @@ -394,6 +410,9 @@ const char *drm_get_colorop_type_name(enum drm_colorop_type type); */ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type); +const char * +drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type); + void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); #endif /* __DRM_COLOROP_H__ */ diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index cac25c0ca37b..4b38da880fc7 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -945,6 +945,19 @@ enum drm_colorop_type { }; /** + * enum drm_colorop_lut1d_interpolation_type - type of interpolation for 1D LUTs + */ +enum drm_colorop_lut1d_interpolation_type { + /** + * @DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR: + * + * Linear interpolation. Values between points of the LUT will be + * linearly interpolated. + */ + DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, +}; + +/** * struct drm_plane_size_hint - Plane size hints * @width: The width of the plane in pixel * @height: The height of the plane in pixel |