History

drm/colorop: Add 3D LUT support to color pipeline

It is to be used to enable HDR by allowing userpace to create and pass 3D LUTs to kernel and hardware. new drm_colorop_type: DRM_COLOROP_3D_LUT.

Alex Hung committed 12 months ago

Commit db971851 parent 24689635 files · +143 −0Browse files

Unified · Split

5 files
  1. drivers/gpu/drm/drm_atomic.c +6 −0
  2. drivers/gpu/drm/drm_atomic_uapi.c +8 −0
  3. drivers/gpu/drm/drm_colorop.c +72 −0
  4. include/drm/drm_colorop.h +23 −0
  5. include/uapi/drm/drm_mode.h +34 −0
drivers/gpu/drm/drm_atomic.c+6−0
@@ -807,6 +807,12 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p, · 806 unmodified lines
807807 case DRM_COLOROP_MULTIPLIER:
808808 drm_printf(p, "\tmultiplier=%llu\n", state->multiplier);
809809 break;
810+ case DRM_COLOROP_3D_LUT:
811+ drm_printf(p, "\tsize=%d\n", colorop->size);
812+ drm_printf(p, "\tinterpolation=%s\n",
813+ drm_get_colorop_lut3d_interpolation_name(colorop->lut3d_interpolation));
814+ drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
815+ break;
810816 default:
811817 break;
812818 }
drivers/gpu/drm/drm_atomic_uapi.c+8−0
@@ -705,6 +705,10 @@ static int drm_atomic_color_set_data_property(struct drm_colorop *colorop, · 704 unmodified lines
705705 case DRM_COLOROP_CTM_3X4:
706706 size = sizeof(struct drm_color_ctm_3x4);
707707 break;
708+ case DRM_COLOROP_3D_LUT:
709+ size = colorop->size * colorop->size * colorop->size *
710+ sizeof(struct drm_color_lut32);
711+ break;
708712 default:
709713 /* should never get here */
710714 return -EINVAL;
@@ -732,6 +736,8 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, · 21 unmodified lines
732736 state->curve_1d_type = val;
733737 } else if (property == colorop->multiplier_property) {
734738 state->multiplier = val;
739+ } else if (property == colorop->lut3d_interpolation_property) {
740+ colorop->lut3d_interpolation = val;
735741 } else if (property == colorop->data_property) {
736742 return drm_atomic_color_set_data_property(colorop, state,
737743 property, val);
@@ -763,6 +769,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, · 25 unmodified lines
763769 *val = state->multiplier;
764770 else if (property == colorop->size_property)
765771 *val = colorop->size;
772+ else if (property == colorop->lut3d_interpolation_property)
773+ *val = colorop->lut3d_interpolation;
766774 else if (property == colorop->data_property)
767775 *val = (state->data) ? state->data->base.id : 0;
768776 else
drivers/gpu/drm/drm_colorop.c+72−0
@@ -67,6 +67,7 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { · 66 unmodified lines
6767 { DRM_COLOROP_1D_LUT, "1D LUT" },
6868 { DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
6969 { DRM_COLOROP_MULTIPLIER, "Multiplier"},
70+ { DRM_COLOROP_3D_LUT, "3D LUT"},
7071 };
7172
7273 static const char * const colorop_curve_1d_type_names[] = {
@@ -82,6 +83,11 @@ static const struct drm_prop_enum_list drm_colorop_lut1d_interpolation_list[] = · 9 unmodified lines
8283 { DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, "Linear" },
8384 };
8485
86+
87+static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] = {
88+ { DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, "Tetrahedral" },
89+};
90+
8591 /* Init Helpers */
8692
8793 static int drm_plane_colorop_init(struct drm_device *dev, struct drm_colorop *colorop,
@@ -381,6 +387,51 @@ int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colo · 293 unmodified lines
381387 }
382388 EXPORT_SYMBOL(drm_plane_colorop_mult_init);
383389
390+int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *colorop,
391+ struct drm_plane *plane,
392+ uint32_t lut_size,
393+ enum drm_colorop_lut3d_interpolation_type interpolation,
394+ uint32_t flags)
395+{
396+ struct drm_property *prop;
397+ int ret;
398+
399+ ret = drm_plane_colorop_init(dev, colorop, plane, DRM_COLOROP_3D_LUT, flags);
400+ if (ret)
401+ return ret;
402+
403+ /* LUT size */
404+ prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_ATOMIC,
405+ "SIZE", 0, UINT_MAX);
406+ if (!prop)
407+ return -ENOMEM;
408+
409+ colorop->size_property = prop;
410+ drm_object_attach_property(&colorop->base, colorop->size_property, lut_size);
411+ colorop->size = lut_size;
412+
413+ /* interpolation */
414+ prop = drm_property_create_enum(dev, 0, "LUT3D_INTERPOLATION",
415+ drm_colorop_lut3d_interpolation_list,
416+ ARRAY_SIZE(drm_colorop_lut3d_interpolation_list));
417+ if (!prop)
418+ return -ENOMEM;
419+
420+ colorop->lut3d_interpolation_property = prop;
421+ drm_object_attach_property(&colorop->base, prop, interpolation);
422+ colorop->lut3d_interpolation = interpolation;
423+
424+ /* data */
425+ ret = drm_colorop_create_data_prop(dev, colorop);
426+ if (ret)
427+ return ret;
428+
429+ drm_colorop_reset(colorop);
430+
431+ return 0;
432+}
433+EXPORT_SYMBOL(drm_plane_colorop_3dlut_init);
434+
384435 static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop,
385436 struct drm_colorop_state *state)
386437 {
@@ -472,7 +523,13 @@ static const char * const colorop_type_name[] = { · 85 unmodified lines
472523 [DRM_COLOROP_1D_LUT] = "1D LUT",
473524 [DRM_COLOROP_CTM_3X4] = "3x4 Matrix",
474525 [DRM_COLOROP_MULTIPLIER] = "Multiplier",
526+ [DRM_COLOROP_3D_LUT] = "3D LUT",
527+};
528+
529+static const char * const colorop_lu3d_interpolation_name[] = {
530+ [DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL] = "Tetrahedral",
475531 };
532+
476533 static const char * const colorop_lut1d_interpolation_name[] = {
477534 [DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR] = "Linear",
478535 };
@@ -508,6 +565,21 @@ const char *drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_inte · 29 unmodified lines
508565 return colorop_lut1d_interpolation_name[type];
509566 }
510567
568+/**
569+ * drm_get_colorop_lut3d_interpolation_name - return a string for interpolation type
570+ * @type: interpolation type to compute name of
571+ *
572+ * In contrast to the other drm_get_*_name functions this one here returns a
573+ * const pointer and hence is threadsafe.
574+ */
575+const char *drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type)
576+{
577+ if (WARN_ON(type >= ARRAY_SIZE(colorop_lu3d_interpolation_name)))
578+ return "unknown";
579+
580+ return colorop_lu3d_interpolation_name[type];
581+}
582+
511583 /**
512584 * drm_colorop_set_next_property - sets the next pointer
513585 * @colorop: drm colorop
include/drm/drm_colorop.h+23−0
@@ -283,6 +283,14 @@ struct drm_colorop { · 282 unmodified lines
283283 */
284284 enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
285285
286+ /**
287+ * @lut3d_interpolation:
288+ *
289+ * Read-only
290+ * Interpolation for DRM_COLOROP_3D_LUT
291+ */
292+ enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
293+
286294 /**
287295 * @lut1d_interpolation_property:
288296 *
@@ -311,6 +319,13 @@ struct drm_colorop { · 22 unmodified lines
311319 */
312320 struct drm_property *size_property;
313321
322+ /**
323+ * @lut3d_interpolation_property:
324+ *
325+ * Read-only property for DRM_COLOROP_3D_LUT interpolation
326+ */
327+ struct drm_property *lut3d_interpolation_property;
328+
314329 /**
315330 * @data_property:
316331 *
@@ -366,6 +381,11 @@ int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *c · 49 unmodified lines
366381 struct drm_plane *plane, uint32_t flags);
367382 int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop,
368383 struct drm_plane *plane, uint32_t flags);
384+int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *colorop,
385+ struct drm_plane *plane,
386+ uint32_t lut_size,
387+ enum drm_colorop_lut3d_interpolation_type interpolation,
388+ uint32_t flags);
369389
370390 struct drm_colorop_state *
371391 drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
@@ -418,6 +438,9 @@ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type ty · 46 unmodified lines
418438 const char *
419439 drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type);
420440
441+const char *
442+drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type);
443+
421444 void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next);
422445
423446 #endif /* __DRM_COLOROP_H__ */
include/uapi/drm/drm_mode.h+34−0
@@ -942,6 +942,40 @@ enum drm_colorop_type { · 941 unmodified lines
942942 * property.
943943 */
944944 DRM_COLOROP_MULTIPLIER,
945+
946+ /**
947+ * @DRM_COLOROP_3D_LUT:
948+ *
949+ * enum string "3D LUT"
950+ *
951+ * A 3D LUT of &drm_color_lut32 entries,
952+ * packed into a blob via the DATA property. The driver's expected
953+ * LUT size is advertised via the SIZE property, i.e., a 3D LUT with
954+ * 17x17x17 entries will have SIZE set to 17.
955+ *
956+ * The DATA blob is a 3D array of struct drm_color_lut32 with dimension
957+ * length of "size".
958+ * The LUT elements are traversed like so:
959+ *
960+ * for B in range 0..n
961+ * for G in range 0..n
962+ * for R in range 0..n
963+ * index = R + n * (G + n * B)
964+ * color = lut3d[index]
965+ */
966+ DRM_COLOROP_3D_LUT,
967+};
968+
969+/**
970+ * enum drm_colorop_lut3d_interpolation_type - type of 3DLUT interpolation
971+ */
972+enum drm_colorop_lut3d_interpolation_type {
973+ /**
974+ * @DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL:
975+ *
976+ * Tetrahedral 3DLUT interpolation
977+ */
978+ DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL,
945979 };
946980
947981 /**