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.
Unified · Split
| @@ -807,6 +807,12 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p, · 806 unmodified lines | |||
| 807 | case DRM_COLOROP_MULTIPLIER: | 807 | case DRM_COLOROP_MULTIPLIER: |
| 808 | drm_printf(p, "\tmultiplier=%llu\n", state->multiplier); | 808 | drm_printf(p, "\tmultiplier=%llu\n", state->multiplier); |
| 809 | break; | 809 | 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; | ||
| 810 | default: | 816 | default: |
| 811 | break; | 817 | break; |
| 812 | } | 818 | } |
| @@ -705,6 +705,10 @@ static int drm_atomic_color_set_data_property(struct drm_colorop *colorop, · 704 unmodified lines | |||
| 705 | case DRM_COLOROP_CTM_3X4: | 705 | case DRM_COLOROP_CTM_3X4: |
| 706 | size = sizeof(struct drm_color_ctm_3x4); | 706 | size = sizeof(struct drm_color_ctm_3x4); |
| 707 | break; | 707 | break; |
| 708 | case DRM_COLOROP_3D_LUT: | ||
| 709 | size = colorop->size * colorop->size * colorop->size * | ||
| 710 | sizeof(struct drm_color_lut32); | ||
| 711 | break; | ||
| 708 | default: | 712 | default: |
| 709 | /* should never get here */ | 713 | /* should never get here */ |
| 710 | return -EINVAL; | 714 | return -EINVAL; |
| @@ -732,6 +736,8 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, · 21 unmodified lines | |||
| 732 | state->curve_1d_type = val; | 736 | state->curve_1d_type = val; |
| 733 | } else if (property == colorop->multiplier_property) { | 737 | } else if (property == colorop->multiplier_property) { |
| 734 | state->multiplier = val; | 738 | state->multiplier = val; |
| 739 | } else if (property == colorop->lut3d_interpolation_property) { | ||
| 740 | colorop->lut3d_interpolation = val; | ||
| 735 | } else if (property == colorop->data_property) { | 741 | } else if (property == colorop->data_property) { |
| 736 | return drm_atomic_color_set_data_property(colorop, state, | 742 | return drm_atomic_color_set_data_property(colorop, state, |
| 737 | property, val); | 743 | property, val); |
| @@ -763,6 +769,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, · 25 unmodified lines | |||
| 763 | *val = state->multiplier; | 769 | *val = state->multiplier; |
| 764 | else if (property == colorop->size_property) | 770 | else if (property == colorop->size_property) |
| 765 | *val = colorop->size; | 771 | *val = colorop->size; |
| 772 | else if (property == colorop->lut3d_interpolation_property) | ||
| 773 | *val = colorop->lut3d_interpolation; | ||
| 766 | else if (property == colorop->data_property) | 774 | else if (property == colorop->data_property) |
| 767 | *val = (state->data) ? state->data->base.id : 0; | 775 | *val = (state->data) ? state->data->base.id : 0; |
| 768 | else | 776 | else |
| @@ -67,6 +67,7 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { · 66 unmodified lines | |||
| 67 | { DRM_COLOROP_1D_LUT, "1D LUT" }, | 67 | { DRM_COLOROP_1D_LUT, "1D LUT" }, |
| 68 | { DRM_COLOROP_CTM_3X4, "3x4 Matrix"}, | 68 | { DRM_COLOROP_CTM_3X4, "3x4 Matrix"}, |
| 69 | { DRM_COLOROP_MULTIPLIER, "Multiplier"}, | 69 | { DRM_COLOROP_MULTIPLIER, "Multiplier"}, |
| 70 | { DRM_COLOROP_3D_LUT, "3D LUT"}, | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | static const char * const colorop_curve_1d_type_names[] = { | 73 | 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 | |||
| 82 | { DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, "Linear" }, | 83 | { DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, "Linear" }, |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| 86 | |||
| 87 | static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] = { | ||
| 88 | { DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, "Tetrahedral" }, | ||
| 89 | }; | ||
| 90 | |||
| 85 | /* Init Helpers */ | 91 | /* Init Helpers */ |
| 86 | 92 | ||
| 87 | static int drm_plane_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, | 93 | 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 | |||
| 381 | } | 387 | } |
| 382 | EXPORT_SYMBOL(drm_plane_colorop_mult_init); | 388 | EXPORT_SYMBOL(drm_plane_colorop_mult_init); |
| 383 | 389 | ||
| 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 | |||
| 384 | static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop, | 435 | static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop, |
| 385 | struct drm_colorop_state *state) | 436 | struct drm_colorop_state *state) |
| 386 | { | 437 | { |
| @@ -472,7 +523,13 @@ static const char * const colorop_type_name[] = { · 85 unmodified lines | |||
| 472 | [DRM_COLOROP_1D_LUT] = "1D LUT", | 523 | [DRM_COLOROP_1D_LUT] = "1D LUT", |
| 473 | [DRM_COLOROP_CTM_3X4] = "3x4 Matrix", | 524 | [DRM_COLOROP_CTM_3X4] = "3x4 Matrix", |
| 474 | [DRM_COLOROP_MULTIPLIER] = "Multiplier", | 525 | [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", | ||
| 475 | }; | 531 | }; |
| 532 | |||
| 476 | static const char * const colorop_lut1d_interpolation_name[] = { | 533 | static const char * const colorop_lut1d_interpolation_name[] = { |
| 477 | [DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR] = "Linear", | 534 | [DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR] = "Linear", |
| 478 | }; | 535 | }; |
| @@ -508,6 +565,21 @@ const char *drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_inte · 29 unmodified lines | |||
| 508 | return colorop_lut1d_interpolation_name[type]; | 565 | return colorop_lut1d_interpolation_name[type]; |
| 509 | } | 566 | } |
| 510 | 567 | ||
| 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 | |||
| 511 | /** | 583 | /** |
| 512 | * drm_colorop_set_next_property - sets the next pointer | 584 | * drm_colorop_set_next_property - sets the next pointer |
| 513 | * @colorop: drm colorop | 585 | * @colorop: drm colorop |
| @@ -283,6 +283,14 @@ struct drm_colorop { · 282 unmodified lines | |||
| 283 | */ | 283 | */ |
| 284 | enum drm_colorop_lut1d_interpolation_type lut1d_interpolation; | 284 | enum drm_colorop_lut1d_interpolation_type lut1d_interpolation; |
| 285 | 285 | ||
| 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 | |||
| 286 | /** | 294 | /** |
| 287 | * @lut1d_interpolation_property: | 295 | * @lut1d_interpolation_property: |
| 288 | * | 296 | * |
| @@ -311,6 +319,13 @@ struct drm_colorop { · 22 unmodified lines | |||
| 311 | */ | 319 | */ |
| 312 | struct drm_property *size_property; | 320 | struct drm_property *size_property; |
| 313 | 321 | ||
| 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 | |||
| 314 | /** | 329 | /** |
| 315 | * @data_property: | 330 | * @data_property: |
| 316 | * | 331 | * |
| @@ -366,6 +381,11 @@ int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *c · 49 unmodified lines | |||
| 366 | struct drm_plane *plane, uint32_t flags); | 381 | struct drm_plane *plane, uint32_t flags); |
| 367 | int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop, | 382 | int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop, |
| 368 | struct drm_plane *plane, uint32_t flags); | 383 | 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); | ||
| 369 | 389 | ||
| 370 | struct drm_colorop_state * | 390 | struct drm_colorop_state * |
| 371 | drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop); | 391 | 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 | |||
| 418 | const char * | 438 | const char * |
| 419 | drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type); | 439 | drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type); |
| 420 | 440 | ||
| 441 | const char * | ||
| 442 | drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type); | ||
| 443 | |||
| 421 | void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); | 444 | void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); |
| 422 | 445 | ||
| 423 | #endif /* __DRM_COLOROP_H__ */ | 446 | #endif /* __DRM_COLOROP_H__ */ |
| @@ -942,6 +942,40 @@ enum drm_colorop_type { · 941 unmodified lines | |||
| 942 | * property. | 942 | * property. |
| 943 | */ | 943 | */ |
| 944 | DRM_COLOROP_MULTIPLIER, | 944 | 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, | ||
| 945 | }; | 979 | }; |
| 946 | 980 | ||
| 947 | /** | 981 | /** |