]> Gentwo Git Trees - linux/.git/commitdiff
drm/colorop: Define LUT_1D interpolation
authorHarry Wentland <harry.wentland@amd.com>
Sat, 15 Nov 2025 00:02:08 +0000 (17:02 -0700)
committerSimon Ser <contact@emersion.fr>
Wed, 26 Nov 2025 22:09:14 +0000 (23:09 +0100)
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
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_atomic_uapi.c
drivers/gpu/drm/drm_colorop.c
include/drm/drm_colorop.h
include/uapi/drm/drm_mode.h

index 33907cc8e1b3e36eafa13ee2e5e1f92c097faf75..e9363814d6667477a9e12fff958003cfa28343ba 100644 (file)
@@ -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;
 
index 45243d05a7fd1390f98514c3528437c5671a5f61..e49d2442fa12bad397f2eec7a9c7e804c9a70c3b 100644 (file)
@@ -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:
index 874dcf8dd14fa0a549aa5b46bb838ca7b4b0de66..64e49338e284d3e11b828e489c1687451f4b6ed3 100644 (file)
@@ -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)
index be99af98fd6c50c416515870a454f8597da58040..f9717d80982906bf9ee5a6696c536e5021def54f 100644 (file)
@@ -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)
 {
@@ -466,6 +486,21 @@ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type ty
        return colorop_curve_1d_type_names[type];
 }
 
+/**
+ * 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
index a4f6a22fa1f9d749667f753af746a6080e231de8..0e1a5e9d26f3e999d1d2c52d626b355d30735f0e 100644 (file)
@@ -271,6 +271,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:
         *
@@ -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__ */
index cac25c0ca37bb3031a92cf9c257e7bca80ea9a01..4b38da880fc7692079f3905a69d9007275d7470e 100644 (file)
@@ -944,6 +944,19 @@ enum drm_colorop_type {
        DRM_COLOROP_MULTIPLIER,
 };
 
+/**
+ * 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