From: Ville Syrjälä ville.syrjala@linux.intel.com
Here's a refresh of Jyri's COLOR_ENCODING and COLOR_RANGE properties, and the i915 implementation I did on top. I tossed in a few core updates as well: plane state dump, and the BT.2020 constant luminance variant.
Apparently nouveau is already exposing a "iturbt_709" bool property which allows one to choose between BT.601 and BT.709 encodings, but given that we want at least BT.2020 in addition I don't think that property is good enough. Trying to implement it, and somehow extend it beyond BT.601 vs. BT.709 seems like wasted effort. Hence I think we should just ignore it and move on.
My userspace implementation in the form of intel ddx XV_COLORSPACE attribute: https://patchwork.freedesktop.org/patch/204696/
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com
Jyri Sarha (1): drm: Add optional COLOR_ENCODING and COLOR_RANGE properties to drm_plane
Ville Syrjälä (7): drm: Add BT.2020 constant luminance enum value for the COLOR_ENCODING property drm/atomic: Include color encoding/range in plane state dump drm/i915: Correctly handle limited range YCbCr data on VLV/CHV drm/i915: Fix plane YCbCr->RGB conversion for GLK drm/i915: Add support for the YCbCr COLOR_ENCODING property drm/i915: Change the COLOR_ENCODING prop default value to BT.709 drm/i915: Add support for the YCbCr COLOR_RANGE property
drivers/gpu/drm/drm_atomic.c | 12 ++++ drivers/gpu/drm/drm_color_mgmt.c | 108 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 24 ++++++- drivers/gpu/drm/i915/intel_display.c | 25 +++++++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_sprite.c | 134 ++++++++++++++++++++++++++++------- include/drm/drm_color_mgmt.h | 20 ++++++ include/drm/drm_plane.h | 8 +++ 9 files changed, 309 insertions(+), 26 deletions(-)
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com --- drivers/gpu/drm/drm_atomic.c | 8 ++++ drivers/gpu/drm/drm_color_mgmt.c | 91 ++++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 +++++++++ include/drm/drm_plane.h | 8 ++++ 4 files changed, 126 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val; + } else if (property == plane->color_encoding_property) { + state->color_encoding = val; + } else if (property == plane->color_range_property) { + state->color_range = val; } else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val); @@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos; + } else if (property == plane->color_encoding_property) { + *val = state->color_encoding; + } else if (property == plane->color_range_property) { + *val = state->color_range; } else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else { diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..a84fc861e406 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,19 @@ * drm_mode_crtc_set_gamma_size(). Drivers which support both should use * drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the * "GAMMA_LUT" property above. + * + * Support for different non RGB color encodings is controlled through + * &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties: + * + * "COLOR_ENCODING" + * Optional plane enum property to support different non RGB + * color encodings. The driver can provide a subset of standard + * enum values supported by the DRM plane. + * + * "COLOR_RANGE" + * Optional plane enum property to support different non RGB + * color parameter ranges. The driver can provide a subset of + * standard enum values supported by the DRM plane. */
/** @@ -339,3 +352,81 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; } + +static const char * const color_encoding_name[] = { + [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr", + [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr", + [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr", +}; + +static const char * const color_range_name[] = { + [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range", + [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range", +}; + +/** + * drm_plane_create_color_properties - color encoding related plane properties + * @supported_encodings: bitfield indicating supported color encodings + * @supported_ranges: bitfileld indicating supported color ranges + * @default_encoding: default color encoding + * @default_range: default color range + * + * Create and attach plane specific COLOR_ENCODING and COLOR_RANGE + * properties to to the drm_plane object. The supported encodings and + * ranges should be provided in supported_encodings and + * supported_ranges bitmasks. Each bit set in the bitmask indicates + * the its number as enum value being supported. + */ +int drm_plane_create_color_properties(struct drm_plane *plane, + u32 supported_encodings, + u32 supported_ranges, + enum drm_color_encoding default_encoding, + enum drm_color_range default_range) +{ + struct drm_device *dev = plane->dev; + struct drm_property *prop; + struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX, + DRM_COLOR_RANGE_MAX)]; + int i, len; + + len = 0; + for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) { + if ((supported_encodings & BIT(i)) == 0) + continue; + + enum_list[len].type = i; + enum_list[len].name = color_encoding_name[i]; + len++; + } + + prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING", + enum_list, len); + if (!prop) + return -ENOMEM; + plane->color_encoding_property = prop; + drm_object_attach_property(&plane->base, prop, default_encoding); + if (plane->state) + plane->state->color_encoding = default_encoding; + + len = 0; + for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) { + if ((supported_ranges & BIT(i)) == 0) + continue; + + enum_list[len].type = i; + enum_list[len].name = color_range_name[i]; + len++; + } + + prop = drm_property_create_enum(dev, 0, "COLOR_RANGE", + enum_list, len); + if (!prop) + return -ENOMEM; + plane->color_range_property = prop; + drm_object_attach_property(&plane->base, prop, default_range); + if (plane->state) + plane->state->color_range = default_range; + + return 0; +} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding { + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, + DRM_COLOR_YCBCR_BT2020, + DRM_COLOR_ENCODING_MAX, +}; + +enum drm_color_range { + DRM_COLOR_YCBCR_LIMITED_RANGE, + DRM_COLOR_YCBCR_FULL_RANGE, + DRM_COLOR_RANGE_MAX, +}; + +int drm_plane_create_color_properties(struct drm_plane *plane, + u32 supported_encodings, + u32 supported_ranges, + enum drm_color_encoding default_encoding, + enum drm_color_range default_range); #endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..c0a242dcda44 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,10 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
+ /* Color encoding for non RGB formats */ + enum drm_color_encoding color_encoding; + enum drm_color_range color_range; + /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +563,9 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property; + + struct drm_property *color_encoding_property; + struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
On Wed, Feb 14, 2018 at 09:23:20PM +0200, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com
drivers/gpu/drm/drm_atomic.c | 8 ++++ drivers/gpu/drm/drm_color_mgmt.c | 91 ++++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 +++++++++ include/drm/drm_plane.h | 8 ++++ 4 files changed, 126 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..a84fc861e406 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,19 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties:
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
Please also mention the function to setup/register them, like we try to do with the other optional properties.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
*/
- standard enum values supported by the DRM plane.
/** @@ -339,3 +352,81 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to to the drm_plane object. The supported encodings and
- ranges should be provided in supported_encodings and
- supported_ranges bitmasks. Each bit set in the bitmask indicates
- the its number as enum value being supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
Is 0 in the above two supported_ masks a valid value? If yes, should we still register the prop in that case? If no, please add a WARN_ON early exit case to catch this.
Similar, if there's only 1 possible value I guess we should make the prop immutable?
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range);
#endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..c0a242dcda44 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,10 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /* Color encoding for non RGB formats */
- enum drm_color_encoding color_encoding;
- enum drm_color_range color_range;
Needs kerneldoc.
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +563,9 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
- struct drm_property *color_encoding_property;
- struct drm_property *color_range_property;
Dito.
};
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
2.13.6
On Mon, Feb 19, 2018 at 04:04:42PM +0100, Daniel Vetter wrote:
On Wed, Feb 14, 2018 at 09:23:20PM +0200, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com
drivers/gpu/drm/drm_atomic.c | 8 ++++ drivers/gpu/drm/drm_color_mgmt.c | 91 ++++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 +++++++++ include/drm/drm_plane.h | 8 ++++ 4 files changed, 126 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..a84fc861e406 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,19 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties:
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
Please also mention the function to setup/register them, like we try to do with the other optional properties.
ack
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
*/
- standard enum values supported by the DRM plane.
/** @@ -339,3 +352,81 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to to the drm_plane object. The supported encodings and
- ranges should be provided in supported_encodings and
- supported_ranges bitmasks. Each bit set in the bitmask indicates
- the its number as enum value being supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
Is 0 in the above two supported_ masks a valid value? If yes, should we still register the prop in that case? If no, please add a WARN_ON early exit case to catch this.
I guess if we go for that we should also check that the supported bitmasks don't contain undefined enum values, and that the default enum values are included in the bitmasks.
Jyri said he's not looked at this in a while, so I'll just go ahead and respin this myself.
Similar, if there's only 1 possible value I guess we should make the prop immutable?
I wonder if we should put that logic into drm_property_create_enum() & co. actually?
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range);
#endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..c0a242dcda44 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,10 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /* Color encoding for non RGB formats */
- enum drm_color_encoding color_encoding;
- enum drm_color_range color_range;
Needs kerneldoc.
ack
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +563,9 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
- struct drm_property *color_encoding_property;
- struct drm_property *color_range_property;
Dito.
ack
};
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
2.13.6
-- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
On 19/02/18 22:19, Ville Syrjälä wrote:
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
Is 0 in the above two supported_ masks a valid value? If yes, should we still register the prop in that case? If no, please add a WARN_ON early exit case to catch this.
I guess if we go for that we should also check that the supported bitmasks don't contain undefined enum values, and that the default enum values are included in the bitmasks.
Agreed. I wonder if there should still be check in drm_property_create_enum() for empty enum list. I can not imagine any good reason for having an enum property without valid options. It is almost a contradiction in terms.
Jyri said he's not looked at this in a while, so I'll just go ahead and respin this myself.
Thanks, please do.
Similar, if there's only 1 possible value I guess we should make the prop immutable?
I wonder if we should put that logic into drm_property_create_enum() & co. actually?
On Mon, Feb 19, 2018 at 10:38:46PM +0200, Jyri Sarha wrote:
On 19/02/18 22:19, Ville Syrjälä wrote:
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
Is 0 in the above two supported_ masks a valid value? If yes, should we still register the prop in that case? If no, please add a WARN_ON early exit case to catch this.
I guess if we go for that we should also check that the supported bitmasks don't contain undefined enum values, and that the default enum values are included in the bitmasks.
Agreed. I wonder if there should still be check in drm_property_create_enum() for empty enum list. I can not imagine any good reason for having an enum property without valid options. It is almost a contradiction in terms.
Yeah checking for that in the the core function sounds best.
Jyri said he's not looked at this in a while, so I'll just go ahead and respin this myself.
Thanks, please do.
Similar, if there's only 1 possible value I guess we should make the prop immutable?
I wonder if we should put that logic into drm_property_create_enum() & co. actually?
I could imagine that we end up with a property that generic userspace wants to set, but a driver somehow only wants to expose a single value (because there's one platform where random constraints result in that). Not quite a sure we should check for that too in the core, but I guess we can try and see what happens. -Daniel
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val; + } else if (property == plane->color_encoding_property) { + state->color_encoding = val; + } else if (property == plane->color_range_property) { + state->color_range = val; } else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val); @@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos; + } else if (property == plane->color_encoding_property) { + *val = state->color_encoding; + } else if (property == plane->color_range_property) { + *val = state->color_range; } else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else { diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@ * drm_mode_crtc_set_gamma_size(). Drivers which support both should use * drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the * "GAMMA_LUT" property above. + * + * Support for different non RGB color encodings is controlled through + * &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They + * are set up by calling drm_plane_create_color_properties(). + * + * "COLOR_ENCODING" + * Optional plane enum property to support different non RGB + * color encodings. The driver can provide a subset of standard + * enum values supported by the DRM plane. + * + * "COLOR_RANGE" + * Optional plane enum property to support different non RGB + * color parameter ranges. The driver can provide a subset of + * standard enum values supported by the DRM plane. */
/** @@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; } + +static const char * const color_encoding_name[] = { + [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr", + [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr", + [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr", +}; + +static const char * const color_range_name[] = { + [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range", + [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range", +}; + +/** + * drm_plane_create_color_properties - color encoding related plane properties + * @plane: plane object + * @supported_encodings: bitfield indicating supported color encodings + * @supported_ranges: bitfileld indicating supported color ranges + * @default_encoding: default color encoding + * @default_range: default color range + * + * Create and attach plane specific COLOR_ENCODING and COLOR_RANGE + * properties to @plane. The supported encodings and ranges should + * be provided in supported_encodings and supported_ranges bitmasks. + * Each bit set in the bitmask indicates that its number as enum + * value is supported. + */ +int drm_plane_create_color_properties(struct drm_plane *plane, + u32 supported_encodings, + u32 supported_ranges, + enum drm_color_encoding default_encoding, + enum drm_color_range default_range) +{ + struct drm_device *dev = plane->dev; + struct drm_property *prop; + struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX, + DRM_COLOR_RANGE_MAX)]; + int i, len; + + if (WARN_ON(supported_encodings == 0 || + (supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 || + (supported_encodings & BIT(default_encoding)) == 0)) + return -EINVAL; + + if (WARN_ON(supported_ranges == 0 || + (supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 || + (supported_ranges & BIT(default_range)) == 0)) + return -EINVAL; + + len = 0; + for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) { + if ((supported_encodings & BIT(i)) == 0) + continue; + + enum_list[len].type = i; + enum_list[len].name = color_encoding_name[i]; + len++; + } + + prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING", + enum_list, len); + if (!prop) + return -ENOMEM; + plane->color_encoding_property = prop; + drm_object_attach_property(&plane->base, prop, default_encoding); + if (plane->state) + plane->state->color_encoding = default_encoding; + + len = 0; + for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) { + if ((supported_ranges & BIT(i)) == 0) + continue; + + enum_list[len].type = i; + enum_list[len].name = color_range_name[i]; + len++; + } + + prop = drm_property_create_enum(dev, 0, "COLOR_RANGE", + enum_list, len); + if (!prop) + return -ENOMEM; + plane->color_range_property = prop; + drm_object_attach_property(&plane->base, prop, default_range); + if (plane->state) + plane->state->color_range = default_range; + + return 0; +} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding { + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, + DRM_COLOR_YCBCR_BT2020, + DRM_COLOR_ENCODING_MAX, +}; + +enum drm_color_range { + DRM_COLOR_YCBCR_LIMITED_RANGE, + DRM_COLOR_YCBCR_FULL_RANGE, + DRM_COLOR_RANGE_MAX, +}; + +int drm_plane_create_color_properties(struct drm_plane *plane, + u32 supported_encodings, + u32 supported_ranges, + enum drm_color_encoding default_encoding, + enum drm_color_range default_range); #endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
+ /** + * @color_encoding: + * + * Color encoding for non RGB formats + */ + enum drm_color_encoding color_encoding; + + /** + * @color_range: + * + * Color range for non RGB formats + */ + enum drm_color_range color_range; + /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property; + + /** + * @color_encoding_property: + * + * Optional "COLOR_ENCODING" enum property for specifying + * color encoding for non RGB formats. + * See drm_plane_create_color_properties(). + */ + struct drm_property *color_encoding_property; + /** + * @color_range_property: + * + * Optional "COLOR_RANGE" enum property for specifying + * color range for non RGB formats. + * See drm_plane_create_color_properties(). + */ + struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
On Mon, Feb 19, 2018 at 10:28:23PM +0200, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
- are set up by calling drm_plane_create_color_properties().
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
*/
- standard enum values supported by the DRM plane.
/** @@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to @plane. The supported encodings and ranges should
- be provided in supported_encodings and supported_ranges bitmasks.
- Each bit set in the bitmask indicates that its number as enum
- value is supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- if (WARN_ON(supported_encodings == 0 ||
(supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
(supported_encodings & BIT(default_encoding)) == 0))
return -EINVAL;
- if (WARN_ON(supported_ranges == 0 ||
(supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range);
#endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /**
* @color_encoding:
*
* Color encoding for non RGB formats
*/
- enum drm_color_encoding color_encoding;
- /**
* @color_range:
*
* Color range for non RGB formats
*/
- enum drm_color_range color_range;
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
- /**
* @color_encoding_property:
*
* Optional "COLOR_ENCODING" enum property for specifying
* color encoding for non RGB formats.
* See drm_plane_create_color_properties().
*/
- struct drm_property *color_encoding_property;
- /**
* @color_range_property:
*
* Optional "COLOR_RANGE" enum property for specifying
* color range for non RGB formats.
* See drm_plane_create_color_properties().
*/
- struct drm_property *color_range_property;
};
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
2.13.6
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
Regards, Chris
On 02/19/2018 09:28 PM, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
- are set up by calling drm_plane_create_color_properties().
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
- standard enum values supported by the DRM plane.
*/
/**
@@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to @plane. The supported encodings and ranges should
- be provided in supported_encodings and supported_ranges bitmasks.
- Each bit set in the bitmask indicates that its number as enum
- value is supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- if (WARN_ON(supported_encodings == 0 ||
(supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
(supported_encodings & BIT(default_encoding)) == 0))
return -EINVAL;
- if (WARN_ON(supported_ranges == 0 ||
(supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
#endifenum drm_color_range default_range);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /**
* @color_encoding:
*
* Color encoding for non RGB formats
*/
- enum drm_color_encoding color_encoding;
- /**
* @color_range:
*
* Color range for non RGB formats
*/
- enum drm_color_range color_range;
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
/**
* @color_encoding_property:
*
* Optional "COLOR_ENCODING" enum property for specifying
* color encoding for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_encoding_property;
/**
* @color_range_property:
*
* Optional "COLOR_RANGE" enum property for specifying
* color range for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
Regards, Chris
On 02/19/2018 09:28 PM, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
- are set up by calling drm_plane_create_color_properties().
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
- standard enum values supported by the DRM plane.
*/
/**
@@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to @plane. The supported encodings and ranges should
- be provided in supported_encodings and supported_ranges bitmasks.
- Each bit set in the bitmask indicates that its number as enum
- value is supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- if (WARN_ON(supported_encodings == 0 ||
(supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
(supported_encodings & BIT(default_encoding)) == 0))
return -EINVAL;
- if (WARN_ON(supported_ranges == 0 ||
(supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
#endifenum drm_color_range default_range);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /**
* @color_encoding:
*
* Color encoding for non RGB formats
*/
- enum drm_color_encoding color_encoding;
- /**
* @color_range:
*
* Color range for non RGB formats
*/
- enum drm_color_range color_range;
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
/**
* @color_encoding_property:
*
* Optional "COLOR_ENCODING" enum property for specifying
* color encoding for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_encoding_property;
/**
* @color_range_property:
*
* Optional "COLOR_RANGE" enum property for specifying
* color range for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
1. What color encoding and range drm should expect on its input RGB buffers by default?
2. How userspace should inform drm that given buffer has specified non-default color encoding and range?
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
B. Reuse current enums, but remove format information from them: DRM_COLOR_YCBCR_BT601 => DRM_COLOR_BT601.
Regards
Andrzej
Regards, Chris
On 02/19/2018 09:28 PM, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
- are set up by calling drm_plane_create_color_properties().
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
- standard enum values supported by the DRM plane.
*/
/**
@@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to @plane. The supported encodings and ranges should
- be provided in supported_encodings and supported_ranges bitmasks.
- Each bit set in the bitmask indicates that its number as enum
- value is supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- if (WARN_ON(supported_encodings == 0 ||
(supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
(supported_encodings & BIT(default_encoding)) == 0))
return -EINVAL;
- if (WARN_ON(supported_ranges == 0 ||
(supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
#endifenum drm_color_range default_range);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /**
* @color_encoding:
*
* Color encoding for non RGB formats
*/
- enum drm_color_encoding color_encoding;
- /**
* @color_range:
*
* Color range for non RGB formats
*/
- enum drm_color_range color_range;
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
/**
* @color_encoding_property:
*
* Optional "COLOR_ENCODING" enum property for specifying
* color encoding for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_encoding_property;
/**
* @color_range_property:
*
* Optional "COLOR_RANGE" enum property for specifying
* color range for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
RGB is just RGB. There is no encoding. It's assumed to be full range because no one really uses anything else.
- How userspace should inform drm that given buffer has specified
non-default color encoding and range?
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
BT.601 specifies how to encoder RGB data as YCbCr. So without YCbCr BT.601 does not mean anything. Well, the standard does contain other things as well I suppose, but for the purposes of the color encoding prop only that one part is relevant.
B. Reuse current enums, but remove format information from them: DRM_COLOR_YCBCR_BT601 => DRM_COLOR_BT601.
Regards
Andrzej
Regards, Chris
On 02/19/2018 09:28 PM, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
- are set up by calling drm_plane_create_color_properties().
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
- standard enum values supported by the DRM plane.
*/
/**
@@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to @plane. The supported encodings and ranges should
- be provided in supported_encodings and supported_ranges bitmasks.
- Each bit set in the bitmask indicates that its number as enum
- value is supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- if (WARN_ON(supported_encodings == 0 ||
(supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
(supported_encodings & BIT(default_encoding)) == 0))
return -EINVAL;
- if (WARN_ON(supported_ranges == 0 ||
(supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
#endifenum drm_color_range default_range);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /**
* @color_encoding:
*
* Color encoding for non RGB formats
*/
- enum drm_color_encoding color_encoding;
- /**
* @color_range:
*
* Color range for non RGB formats
*/
- enum drm_color_range color_range;
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
/**
* @color_encoding_property:
*
* Optional "COLOR_ENCODING" enum property for specifying
* color encoding for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_encoding_property;
/**
* @color_range_property:
*
* Optional "COLOR_RANGE" enum property for specifying
* color range for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
On 11/30/18 15:29, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
RGB is just RGB. There is no encoding. It's assumed to be full range because no one really uses anything else.
For simple desktop usage that's true. When dealing with video inputs, this becomes much more complicated.
- How userspace should inform drm that given buffer has specified
non-default color encoding and range?
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
BT.601 specifies how to encoder RGB data as YCbCr. So without YCbCr BT.601 does not mean anything. Well, the standard does contain other things as well I suppose, but for the purposes of the color encoding prop only that one part is relevant.
Ah, I misunderstood the meaning of DRM_COLOR_RGB_BT601. This is the equivalent of V4L2_YCBCR_ENC_601, and that's indeed only defined for Y'CbCr. But it is often (ab)used as an alias for the SMPTE170M colorspace (used by SDTV).
V4L2 has the following defines for colorspaces, transfer functions, Y'CbCr (and HSV) encodings and quantization ranges:
https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces-defs.html
Missing in this list is the color encoding (RGB vs YCbCr vs HSV) which is set through the pixelformat fourcc.
And indeed, we don't have an RGB encoding define since RGB is just RGB :-)
Regards,
Hans
B. Reuse current enums, but remove format information from them: DRM_COLOR_YCBCR_BT601 => DRM_COLOR_BT601.
Regards
Andrzej
Regards, Chris
On 02/19/2018 09:28 PM, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
- are set up by calling drm_plane_create_color_properties().
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
- standard enum values supported by the DRM plane.
*/
/**
@@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to @plane. The supported encodings and ranges should
- be provided in supported_encodings and supported_ranges bitmasks.
- Each bit set in the bitmask indicates that its number as enum
- value is supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- if (WARN_ON(supported_encodings == 0 ||
(supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
(supported_encodings & BIT(default_encoding)) == 0))
return -EINVAL;
- if (WARN_ON(supported_ranges == 0 ||
(supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
#endifenum drm_color_range default_range);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /**
* @color_encoding:
*
* Color encoding for non RGB formats
*/
- enum drm_color_encoding color_encoding;
- /**
* @color_range:
*
* Color range for non RGB formats
*/
- enum drm_color_range color_range;
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
/**
* @color_encoding_property:
*
* Optional "COLOR_ENCODING" enum property for specifying
* color encoding for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_encoding_property;
/**
* @color_range_property:
*
* Optional "COLOR_RANGE" enum property for specifying
* color range for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
On Fri, Nov 30, 2018 at 03:48:00PM +0100, Hans Verkuil wrote:
On 11/30/18 15:29, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
RGB is just RGB. There is no encoding. It's assumed to be full range because no one really uses anything else.
For simple desktop usage that's true. When dealing with video inputs, this becomes much more complicated.
- How userspace should inform drm that given buffer has specified
non-default color encoding and range?
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
BT.601 specifies how to encoder RGB data as YCbCr. So without YCbCr BT.601 does not mean anything. Well, the standard does contain other things as well I suppose, but for the purposes of the color encoding prop only that one part is relevant.
Ah, I misunderstood the meaning of DRM_COLOR_RGB_BT601. This is the equivalent of V4L2_YCBCR_ENC_601, and that's indeed only defined for Y'CbCr. But it is often (ab)used as an alias for the SMPTE170M colorspace (used by SDTV).
V4L2 has the following defines for colorspaces, transfer functions, Y'CbCr (and HSV) encodings and quantization ranges:
https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces-defs.html
Yeah, we're going to be introducing other properties to control colorspace and transfer function in kms as well. Actually some patches towards that have been floated a few times already.
On 11/30/18 16:16, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:48:00PM +0100, Hans Verkuil wrote:
On 11/30/18 15:29, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
RGB is just RGB. There is no encoding. It's assumed to be full range because no one really uses anything else.
For simple desktop usage that's true. When dealing with video inputs, this becomes much more complicated.
- How userspace should inform drm that given buffer has specified
non-default color encoding and range?
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
BT.601 specifies how to encoder RGB data as YCbCr. So without YCbCr BT.601 does not mean anything. Well, the standard does contain other things as well I suppose, but for the purposes of the color encoding prop only that one part is relevant.
Ah, I misunderstood the meaning of DRM_COLOR_RGB_BT601. This is the equivalent of V4L2_YCBCR_ENC_601, and that's indeed only defined for Y'CbCr. But it is often (ab)used as an alias for the SMPTE170M colorspace (used by SDTV).
V4L2 has the following defines for colorspaces, transfer functions, Y'CbCr (and HSV) encodings and quantization ranges:
https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces-defs.html
Yeah, we're going to be introducing other properties to control colorspace and transfer function in kms as well. Actually some patches towards that have been floated a few times already.
Great. Let's try to keep drm and V4L2 in sync for this. It should be possible to convert from one to the other without having to do weird things.
I'll try to pay attention to these patches, but just ping me if you want me to take a look at something.
I put a lot of effort into the V4L2 colorspace documentation, trying to put all the information in one place, esp. all the formulas.
Regards,
Hans
Hi,
On Fri, Nov 30, 2018 at 04:34:54PM +0100, Hans Verkuil wrote:
On 11/30/18 16:16, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:48:00PM +0100, Hans Verkuil wrote:
On 11/30/18 15:29, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote: > Hi, > > I am looking for a way to export the color encoding and range selection > to user space. I came across those properties and am wondering, why > they are meant only for non RGB color encodings. Would it be okay, to > modify them and use with RGB formats as well? What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
This is where I personally think we've got an unfortunate disconnect in the KMS UAPI.
For YCbCr buffers, these properties specify the encoding and range of the data in the buffer. But everything else in the pipe is described in terms of the processing to apply - i.e. the KMS driver doesn't know what transfer function the data uses, it only knows the degamma LUT it's told to apply to it.
It would have been more uniform if the COLOR_ENCODING/COLOR_RANGE properties were a single "ENCODING_CONVERSION" property stating what conversion should be applied.
RGB is just RGB. There is no encoding. It's assumed to be full range because no one really uses anything else.
For simple desktop usage that's true. When dealing with video inputs, this becomes much more complicated.
When the plane degamma/ctm/gamma properties land, those could be used to convert limited range to whatever the pipe-internal format is, I think.
That pipe-internal format would be whatever userspace decides it is, via converting input buffers using the various color conversion properties.
- How userspace should inform drm that given buffer has specified
non-default color encoding and range?
My understanding is that DRM would never be informed of this - only what to do with the data (which does of-course imply an encoding, but it's not told to DRM explicitly).
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
BT.601 specifies how to encoder RGB data as YCbCr. So without YCbCr BT.601 does not mean anything. Well, the standard does contain other things as well I suppose, but for the purposes of the color encoding prop only that one part is relevant.
Ah, I misunderstood the meaning of DRM_COLOR_RGB_BT601. This is the equivalent of V4L2_YCBCR_ENC_601, and that's indeed only defined for Y'CbCr. But it is often (ab)used as an alias for the SMPTE170M colorspace (used by SDTV).
V4L2 has the following defines for colorspaces, transfer functions, Y'CbCr (and HSV) encodings and quantization ranges:
https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces-defs.html
Yeah, we're going to be introducing other properties to control colorspace and transfer function in kms as well. Actually some patches towards that have been floated a few times already.
Great. Let's try to keep drm and V4L2 in sync for this. It should be possible to convert from one to the other without having to do weird things.
I'll try to pay attention to these patches, but just ping me if you want me to take a look at something.
I put a lot of effort into the V4L2 colorspace documentation, trying to put all the information in one place, esp. all the formulas.
There's always going to be a bit of a disconnect here - in KMS, it's userspace which needs to handle all this stuff. It would be up to userspace to set e.g. DEGAMMA_LUT to a LUT which corresponds to SMPTE 2084, rather than the kernel driver being told directly that the buffer is encoded using the SMPTE 2084 transfer function.
Actually I want to put an RFC together to allow DEGAMMA_LUT/GAMMA_LUT to be set to some pre-defined values (e.g. sRGB, PQ, HLG) to suit hardware which has built-in hard-coded transfer functions (and potentially also save userspace some effort of coming up with LUTs).
Cheers, -Brian
Regards,
Hans _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
On 30.11.2018 15:48, Hans Verkuil wrote:
On 11/30/18 15:29, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
RGB is just RGB. There is no encoding.
OK, Now I see I have confused encoding with colorspace, Hans thanks for the documentation.
As I understand drm by default should expect sRGB colorspace, also for Y'CbCr buffers, and currently there are no standard ways to specify buffer colorspace.
Looking at current users of drm_plane_create_color_properties for Y'CbCr buffers it seems default range should be LIMITED.
But default encoding is different: mali, armada, nouveau use DRM_COLOR_YCBCR_BT601, i915 uses DRM_COLOR_YCBCR_BT709 - shouldn't this be somehow standardized?
What I still do not understand is colorspace conversion(not encoding!) - between pipeline input (framebuffers) and output (HDMI connector for example):
1. Since sRGB, SMPTE170M/BT.601, BT.709 colorspaces are 'almost identical in coverage' (according to wikipedia[1]) no colorspace conversion is performed at all.
2. It is performed somewhere by HW, just my IP documentation is not clear about it.
Another thing which still bothers me is RGB range in case of HDMI - CEA-861 expects than on CEA modes limited RGB range should be sent, but the pipeline on the particular hardware I have do not perform any conversion of input buffers. So only limited range RGB buffers are displayed correctly. In such case property describing plane with limited RGB would be useful.
[1]: https://en.wikipedia.org/wiki/Rec._709#Primary_chromaticities
It's assumed to be full range
because no one really uses anything else.
For simple desktop usage that's true. When dealing with video inputs, this becomes much more complicated.
As I said earlier there are cases where output stream should be limited RGB, and no conversion in pipeline - thus framebuffers also should be 'limited RGB'.
Regards
Andrzej
- How userspace should inform drm that given buffer has specified
non-default color encoding and range?
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
BT.601 specifies how to encoder RGB data as YCbCr. So without YCbCr BT.601 does not mean anything. Well, the standard does contain other things as well I suppose, but for the purposes of the color encoding prop only that one part is relevant.
Ah, I misunderstood the meaning of DRM_COLOR_RGB_BT601. This is the equivalent of V4L2_YCBCR_ENC_601, and that's indeed only defined for Y'CbCr. But it is often (ab)used as an alias for the SMPTE170M colorspace (used by SDTV).
V4L2 has the following defines for colorspaces, transfer functions, Y'CbCr (and HSV) encodings and quantization ranges:
https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces-defs.html
Missing in this list is the color encoding (RGB vs YCbCr vs HSV) which is set through the pixelformat fourcc.
And indeed, we don't have an RGB encoding define since RGB is just RGB :-)
Regards,
Hans
B. Reuse current enums, but remove format information from them: DRM_COLOR_YCBCR_BT601 => DRM_COLOR_BT601.
Regards
Andrzej
...
On 12/03/2018 12:23 PM, Andrzej Hajda wrote:
On 30.11.2018 15:48, Hans Verkuil wrote:
On 11/30/18 15:29, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
RGB is just RGB. There is no encoding.
OK, Now I see I have confused encoding with colorspace, Hans thanks for the documentation.
As I understand drm by default should expect sRGB colorspace, also for Y'CbCr buffers, and currently there are no standard ways to specify buffer colorspace.
Looking at current users of drm_plane_create_color_properties for Y'CbCr buffers it seems default range should be LIMITED.
Right. There is support for YCbCr quantization range signaling in HDMI, but that is for all intents and purposes broken in the standard. Don't use it, just output limited range YCbCr.
On the other hand, RGB Quantization range signaling should *always* be used if the EDID signals support for it. I believe that's what drm does today already (this certainly works for i915).
But default encoding is different: mali, armada, nouveau use DRM_COLOR_YCBCR_BT601, i915 uses DRM_COLOR_YCBCR_BT709 - shouldn't this be somehow standardized?
According to CEA-861 bt.601 should be used for SDTV (PAL/NTSC), 709 for everything else. So this is resolution dependent.
Although strictly speaking it is only userspace that knows the right encoding, since it depends on the source material. You can have SDTV video encoded with 709, or HDTV encoded with 601. But in the absence of any information, the default rule above is what should be used.
What I still do not understand is colorspace conversion(not encoding!) - between pipeline input (framebuffers) and output (HDMI connector for example):
- Since sRGB, SMPTE170M/BT.601, BT.709 colorspaces are 'almost
identical in coverage' (according to wikipedia[1]) no colorspace conversion is performed at all.
That's correct. There is a slight difference between SMPTE170M and sRGB/Rec709, but basically invisible to the naked eye unless you see it side-by-side, and even then it's is hard to detect.
However, sRGB uses a different transfer function compared to SMPTE170M and Rec709, and that difference *is* quite visible. Not all hardware (certainly not video capture hardware) is capable of converting between different transfer functions, though. I gather that this is more common for HDMI output hardware.
- It is performed somewhere by HW, just my IP documentation is not
clear about it.
Another thing which still bothers me is RGB range in case of HDMI - CEA-861 expects than on CEA modes limited RGB range should be sent, but the pipeline on the particular hardware I have do not perform any conversion of input buffers. So only limited range RGB buffers are displayed correctly. In such case property describing plane with limited RGB would be useful.
Are you sure? Usually the same block that does YCbCr encoding conversion (601 to 709 or vice versa), also deals with limited/full range conversion.
It is typically a 3x3 matrix + a vector adding the needed offsets. It is dead cheap to implement in hardware, so it would be very unusual if there is no support for this.
It's assumed to be full range
because no one really uses anything else.
For simple desktop usage that's true. When dealing with video inputs, this becomes much more complicated.
As I said earlier there are cases where output stream should be limited RGB, and no conversion in pipeline - thus framebuffers also should be 'limited RGB'.
Whether RGB output should be full or limited range depends entirely on the resolution and the EDID. I have tested i915 w.r.t. RGB quantization range, and that does it right.
The reality with RGB Quantization Range handling is that 50% of all devices do this wrong. So if the EDID signals selectable quantization range support, then use it and signal full range RGB.
If it is not available, then the i915 implementation is one I can point to that does it 100% correct. (This might be based on core drm code, I'm not sure if it is i915 specific or not)
Kudos to the i915 driver developers: the linux implementation is the only one that handles this correctly. The Windows implementation doesn't honor RGB Selectable Quantization and the macos driver seems to always output full range.
The only way to support all three variants in an HDMI receiver is to enable YCbCr support in the EDID: the macos driver will now output YCbCr, while all the others output RGB (Windows using default RGB Quantization rules and Linux explicitly signaling the RGB range).
It's insane.
Regards,
Hans
On 03.12.2018 12:52, Hans Verkuil wrote:
On 12/03/2018 12:23 PM, Andrzej Hajda wrote:
On 30.11.2018 15:48, Hans Verkuil wrote:
On 11/30/18 15:29, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 03:20:59PM +0100, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote: > Hi, > > I am looking for a way to export the color encoding and range selection > to user space. I came across those properties and am wondering, why > they are meant only for non RGB color encodings. Would it be okay, to > modify them and use with RGB formats as well? What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
RGB is just RGB. There is no encoding.
OK, Now I see I have confused encoding with colorspace, Hans thanks for the documentation.
As I understand drm by default should expect sRGB colorspace, also for Y'CbCr buffers, and currently there are no standard ways to specify buffer colorspace.
Looking at current users of drm_plane_create_color_properties for Y'CbCr buffers it seems default range should be LIMITED.
Right. There is support for YCbCr quantization range signaling in HDMI, but that is for all intents and purposes broken in the standard. Don't use it, just output limited range YCbCr.
On the other hand, RGB Quantization range signaling should *always* be used if the EDID signals support for it. I believe that's what drm does today already (this certainly works for i915).
But default encoding is different: mali, armada, nouveau use DRM_COLOR_YCBCR_BT601, i915 uses DRM_COLOR_YCBCR_BT709 - shouldn't this be somehow standardized?
According to CEA-861 bt.601 should be used for SDTV (PAL/NTSC), 709 for everything else. So this is resolution dependent.
Although strictly speaking it is only userspace that knows the right encoding, since it depends on the source material. You can have SDTV video encoded with 709, or HDTV encoded with 601. But in the absence of any information, the default rule above is what should be used.
Since drm plane is not tied to specific crtc default encoding will not be always known prior to setting mode on crtc and attaching plane to crtc, probably DRM_COLOR_YCBCR_DEFAULT or similar would solve the issue.
What I still do not understand is colorspace conversion(not encoding!) - between pipeline input (framebuffers) and output (HDMI connector for example):
- Since sRGB, SMPTE170M/BT.601, BT.709 colorspaces are 'almost
identical in coverage' (according to wikipedia[1]) no colorspace conversion is performed at all.
That's correct. There is a slight difference between SMPTE170M and sRGB/Rec709, but basically invisible to the naked eye unless you see it side-by-side, and even then it's is hard to detect.
However, sRGB uses a different transfer function compared to SMPTE170M and Rec709, and that difference *is* quite visible. Not all hardware (certainly not video capture hardware) is capable of converting between different transfer functions, though. I gather that this is more common for HDMI output hardware.
- It is performed somewhere by HW, just my IP documentation is not
clear about it.
Another thing which still bothers me is RGB range in case of HDMI - CEA-861 expects than on CEA modes limited RGB range should be sent, but the pipeline on the particular hardware I have do not perform any conversion of input buffers. So only limited range RGB buffers are displayed correctly. In such case property describing plane with limited RGB would be useful.
Are you sure? Usually the same block that does YCbCr encoding conversion (601 to 709 or vice versa), also deals with limited/full range conversion.
It is typically a 3x3 matrix + a vector adding the needed offsets. It is dead cheap to implement in hardware, so it would be very unusual if there is no support for this.
Yay, I have unusual hardware :)
There is register in HDMI output block for RGB->YCbCr conversion and I can specify there input RGB range and encoding, but it is only for cases where output is YCbCr4:4:4, In case RGB -> RGB no conversion is performed.
Regards
Andrzej
It's assumed to be full range
because no one really uses anything else.
For simple desktop usage that's true. When dealing with video inputs, this becomes much more complicated.
As I said earlier there are cases where output stream should be limited RGB, and no conversion in pipeline - thus framebuffers also should be 'limited RGB'.
Whether RGB output should be full or limited range depends entirely on the resolution and the EDID. I have tested i915 w.r.t. RGB quantization range, and that does it right.
The reality with RGB Quantization Range handling is that 50% of all devices do this wrong. So if the EDID signals selectable quantization range support, then use it and signal full range RGB.
If it is not available, then the i915 implementation is one I can point to that does it 100% correct. (This might be based on core drm code, I'm not sure if it is i915 specific or not)
Kudos to the i915 driver developers: the linux implementation is the only one that handles this correctly. The Windows implementation doesn't honor RGB Selectable Quantization and the macos driver seems to always output full range.
The only way to support all three variants in an HDMI receiver is to enable YCbCr support in the EDID: the macos driver will now output YCbCr, while all the others output RGB (Windows using default RGB Quantization rules and Linux explicitly signaling the RGB range).
It's insane.
Regards,
Hans
On 11/30/18 15:20, Andrzej Hajda wrote:
Hi Ville,
As Christoph cannot respond till middle next week I can try to respond in his absence, as I am familiar with the subject.
On 30.11.2018 14:25, Ville Syrjälä wrote:
On Fri, Nov 30, 2018 at 02:08:11PM +0100, Christoph Manszewski wrote:
Hi,
I am looking for a way to export the color encoding and range selection to user space. I came across those properties and am wondering, why they are meant only for non RGB color encodings. Would it be okay, to modify them and use with RGB formats as well?
What you trying to do? Input limited range RGB data and expand to full range?
For example. But there are two more general questions, which surprisingly we have not found answer for.
- What color encoding and range drm should expect on its input RGB
buffers by default?
While I am not a drm expert, I am pretty certain it always expects full range RGB.
There is a real use-case for being able to give drm limited range RGB: if the image was filled from an HDMI receiver and that receiver got limited range RGB. That said, most (but not all) receivers can expand it to full range before writing to memory.
- How userspace should inform drm that given buffer has specified
non-default color encoding and range?
Hopefully this patch introduces such properties but only for YCbCr formats, the question is what should be the best way to expand it to RGB formats:
A. Add another enums: DRM_COLOR_RGB_BT601 and friends.
B. Reuse current enums, but remove format information from them: DRM_COLOR_YCBCR_BT601 => DRM_COLOR_BT601.
The colorspace (BT601, REC709, BT2020) is independent of the quantization range (full/limited) and of the color encoding (YCbCr, RGB). There is also the transfer function, another independent setting.
More background info is here:
https://hverkuil.home.xs4all.nl/spec/uapi/v4l/colorspaces.html
If all you use is a desktop, then it is all simple: full range sRGB. But if you start mixing video captured from an HDMI receiver, then it can become much more complex.
Regards,
Hans
Regards
Andrzej
Regards, Chris
On 02/19/2018 09:28 PM, Ville Syrjala wrote:
From: Jyri Sarha jsarha@ti.com
Add a standard optional properties to support different non RGB color encodings in DRM planes. COLOR_ENCODING select the supported non RGB color encoding, for instance ITU-R BT.709 YCbCr. COLOR_RANGE selects the value ranges within the selected color encoding. The properties are stored to drm_plane object to allow different set of supported encoding for different planes on the device.
v2: Add/fix kerneldocs, verify bitmasks (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jyri Sarha jsarha@ti.com [vsyrjala v2: Add/fix kerneldocs, verify bitmasks] Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 8 +++ drivers/gpu/drm/drm_color_mgmt.c | 103 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 19 ++++++++ include/drm/drm_plane.h | 32 ++++++++++++ 4 files changed, 162 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 46733d534587..452a0b0bafbc 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == plane->zpos_property) { state->zpos = val;
- } else if (property == plane->color_encoding_property) {
state->color_encoding = val;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val);state->color_range = val;
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == plane->zpos_property) { *val = state->zpos;
- } else if (property == plane->color_encoding_property) {
*val = state->color_encoding;
- } else if (property == plane->color_range_property) {
} else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else {*val = state->color_range;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 0d002b045bd2..4b83e078d3e9 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -88,6 +88,20 @@
- drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- "GAMMA_LUT" property above.
- Support for different non RGB color encodings is controlled through
- &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
- are set up by calling drm_plane_create_color_properties().
- "COLOR_ENCODING"
- Optional plane enum property to support different non RGB
- color encodings. The driver can provide a subset of standard
- enum values supported by the DRM plane.
- "COLOR_RANGE"
- Optional plane enum property to support different non RGB
- color parameter ranges. The driver can provide a subset of
- standard enum values supported by the DRM plane.
*/
/**
@@ -339,3 +353,92 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_unlock(&crtc->mutex); return ret; }
+static const char * const color_encoding_name[] = {
- [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
- [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
- [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
+};
+static const char * const color_range_name[] = {
- [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
- [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
+};
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
- @supported_ranges: bitfileld indicating supported color ranges
- @default_encoding: default color encoding
- @default_range: default color range
- Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
- properties to @plane. The supported encodings and ranges should
- be provided in supported_encodings and supported_ranges bitmasks.
- Each bit set in the bitmask indicates that its number as enum
- value is supported.
- */
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range)
+{
- struct drm_device *dev = plane->dev;
- struct drm_property *prop;
- struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
DRM_COLOR_RANGE_MAX)];
- int i, len;
- if (WARN_ON(supported_encodings == 0 ||
(supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
(supported_encodings & BIT(default_encoding)) == 0))
return -EINVAL;
- if (WARN_ON(supported_ranges == 0 ||
(supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;
- len = 0;
- for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
if ((supported_encodings & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_encoding_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_encoding_property = prop;
- drm_object_attach_property(&plane->base, prop, default_encoding);
- if (plane->state)
plane->state->color_encoding = default_encoding;
- len = 0;
- for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
if ((supported_ranges & BIT(i)) == 0)
continue;
enum_list[len].type = i;
enum_list[len].name = color_range_name[i];
len++;
- }
- prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
enum_list, len);
- if (!prop)
return -ENOMEM;
- plane->color_range_property = prop;
- drm_object_attach_property(&plane->base, prop, default_range);
- if (plane->state)
plane->state->color_range = default_range;
- return 0;
+} +EXPORT_SYMBOL(drm_plane_create_color_properties); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..b3b6d302ca8c 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h>
struct drm_crtc; +struct drm_plane;
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_ENCODING_MAX,
+};
+enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
- DRM_COLOR_RANGE_MAX,
+};
+int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
enum drm_color_encoding default_encoding,
#endifenum drm_color_range default_range);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h>
struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos;
- /**
* @color_encoding:
*
* Color encoding for non RGB formats
*/
- enum drm_color_encoding color_encoding;
- /**
* @color_range:
*
* Color range for non RGB formats
*/
- enum drm_color_range color_range;
- /* Clipped coordinates */ struct drm_rect src, dst;
@@ -558,6 +573,23 @@ struct drm_plane {
struct drm_property *zpos_property; struct drm_property *rotation_property;
/**
* @color_encoding_property:
*
* Optional "COLOR_ENCODING" enum property for specifying
* color encoding for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_encoding_property;
/**
* @color_range_property:
*
* Optional "COLOR_RANGE" enum property for specifying
* color range for non RGB formats.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_range_property; };
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
From: Ville Syrjälä ville.syrjala@linux.intel.com
BT.2020 specifies two YCbCr<->RGB conversion formulas. The more traditional non-constant luminance and a more complicate one constant luminance one. Add an enum value for the constant luminance variant as well in case someone has hardware supporting it.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl CC: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_color_mgmt.c | 1 + include/drm/drm_color_mgmt.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index a84fc861e406..061d342f9d96 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -357,6 +357,7 @@ static const char * const color_encoding_name[] = { [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr", [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr", [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr", + [DRM_COLOR_YCBCR_BT2020_CONST] = "ITU-R BT.2020 YCbCr constant luminance", };
static const char * const color_range_name[] = { diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index b3b6d302ca8c..175943c87d5b 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -41,7 +41,8 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, enum drm_color_encoding { DRM_COLOR_YCBCR_BT601, DRM_COLOR_YCBCR_BT709, - DRM_COLOR_YCBCR_BT2020, + DRM_COLOR_YCBCR_BT2020, /* non-constant luminance */ + DRM_COLOR_YCBCR_BT2020_CONST, /* constant luminance */ DRM_COLOR_ENCODING_MAX, };
On Wed, Feb 14, 2018 at 09:23:21PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
BT.2020 specifies two YCbCr<->RGB conversion formulas. The more traditional non-constant luminance and a more complicate one constant luminance one. Add an enum value for the constant luminance variant as well in case someone has hardware supporting it.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl CC: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
drivers/gpu/drm/drm_color_mgmt.c | 1 + include/drm/drm_color_mgmt.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index a84fc861e406..061d342f9d96 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -357,6 +357,7 @@ static const char * const color_encoding_name[] = { [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr", [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr", [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
- [DRM_COLOR_YCBCR_BT2020_CONST] = "ITU-R BT.2020 YCbCr constant luminance",
I just realized that this exceeds the max prop enum name length of 31 characters. I guess we'll just have to truncate it to something like "ITU-R BT.2020 YCbCr const". Any better suggestions?
/me goes add some WARN_ON()s for invalid prop/enum names...
};
static const char * const color_range_name[] = { diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index b3b6d302ca8c..175943c87d5b 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -41,7 +41,8 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, enum drm_color_encoding { DRM_COLOR_YCBCR_BT601, DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
- DRM_COLOR_YCBCR_BT2020, /* non-constant luminance */
- DRM_COLOR_YCBCR_BT2020_CONST, /* constant luminance */ DRM_COLOR_ENCODING_MAX,
};
-- 2.13.6
From: Ville Syrjälä ville.syrjala@linux.intel.com
Include color_enconding and color_range in the plane state dump.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_atomic.c | 4 ++++ drivers/gpu/drm/drm_color_mgmt.c | 16 ++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 ++ 3 files changed, 22 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 452a0b0bafbc..9552052ed31a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -952,6 +952,10 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest)); drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src)); drm_printf(p, "\trotation=%x\n", state->rotation); + drm_printf(p, "\tcolor-encoding=%s\n", + drm_get_color_encoding_name(state->color_encoding)); + drm_printf(p, "\tcolor-range=%s\n", + drm_get_color_range_name(state->color_range));
if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state); diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 061d342f9d96..06851d575f14 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -365,6 +365,22 @@ static const char * const color_range_name[] = { [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range", };
+const char *drm_get_color_encoding_name(enum drm_color_encoding encoding) +{ + if (WARN_ON(encoding >= ARRAY_SIZE(color_encoding_name))) + return "unknown"; + + return color_encoding_name[encoding]; +} + +const char *drm_get_color_range_name(enum drm_color_range range) +{ + if (WARN_ON(range >= ARRAY_SIZE(color_range_name))) + return "unknown"; + + return color_range_name[range]; +} + /** * drm_plane_create_color_properties - color encoding related plane properties * @supported_encodings: bitfield indicating supported color encodings diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index af00f42ba269..8ca2ffef6231 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -71,6 +71,8 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
/* drm_color_mgmt.c */ +const char *drm_get_color_encoding_name(enum drm_color_encoding encoding); +const char *drm_get_color_range_name(enum drm_color_range range);
/* IOCTLs */ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
On Wed, Feb 14, 2018 at 09:23:22PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Include color_enconding and color_range in the plane state dump.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
drivers/gpu/drm/drm_atomic.c | 4 ++++ drivers/gpu/drm/drm_color_mgmt.c | 16 ++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 ++ 3 files changed, 22 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 452a0b0bafbc..9552052ed31a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -952,6 +952,10 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest)); drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src)); drm_printf(p, "\trotation=%x\n", state->rotation);
drm_printf(p, "\tcolor-encoding=%s\n",
drm_get_color_encoding_name(state->color_encoding));
drm_printf(p, "\tcolor-range=%s\n",
drm_get_color_range_name(state->color_range));
if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 061d342f9d96..06851d575f14 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -365,6 +365,22 @@ static const char * const color_range_name[] = { [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range", };
kerneldoc would be neat here ... -Daniel
+const char *drm_get_color_encoding_name(enum drm_color_encoding encoding) +{
- if (WARN_ON(encoding >= ARRAY_SIZE(color_encoding_name)))
return "unknown";
- return color_encoding_name[encoding];
+}
+const char *drm_get_color_range_name(enum drm_color_range range) +{
- if (WARN_ON(range >= ARRAY_SIZE(color_range_name)))
return "unknown";
- return color_range_name[range];
+}
/**
- drm_plane_create_color_properties - color encoding related plane properties
- @supported_encodings: bitfield indicating supported color encodings
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index af00f42ba269..8ca2ffef6231 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -71,6 +71,8 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
/* drm_color_mgmt.c */ +const char *drm_get_color_encoding_name(enum drm_color_encoding encoding); +const char *drm_get_color_range_name(enum drm_color_range range);
/* IOCTLs */ int drm_mode_gamma_get_ioctl(struct drm_device *dev, -- 2.13.6
From: Ville Syrjälä ville.syrjala@linux.intel.com
Include color_enconding and color_range in the plane state dump.
v2: Add kerneldoc (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_atomic.c | 4 ++++ drivers/gpu/drm/drm_color_mgmt.c | 30 ++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 ++ 3 files changed, 36 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 452a0b0bafbc..9552052ed31a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -952,6 +952,10 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest)); drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src)); drm_printf(p, "\trotation=%x\n", state->rotation); + drm_printf(p, "\tcolor-encoding=%s\n", + drm_get_color_encoding_name(state->color_encoding)); + drm_printf(p, "\tcolor-range=%s\n", + drm_get_color_range_name(state->color_range));
if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state); diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 7b0f1c2d9190..a11a838741c2 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -367,6 +367,36 @@ static const char * const color_range_name[] = { };
/** + * drm_get_color_encoding_name - return a string for color encoding + * @encoding: color encoding 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_color_encoding_name(enum drm_color_encoding encoding) +{ + if (WARN_ON(encoding >= ARRAY_SIZE(color_encoding_name))) + return "unknown"; + + return color_encoding_name[encoding]; +} + +/** + * drm_get_color_range_name - return a string for color range + * @range: color range 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_color_range_name(enum drm_color_range range) +{ + if (WARN_ON(range >= ARRAY_SIZE(color_range_name))) + return "unknown"; + + return color_range_name[range]; +} + +/** * drm_plane_create_color_properties - color encoding related plane properties * @plane: plane object * @supported_encodings: bitfield indicating supported color encodings diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index af00f42ba269..8ca2ffef6231 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -71,6 +71,8 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
/* drm_color_mgmt.c */ +const char *drm_get_color_encoding_name(enum drm_color_encoding encoding); +const char *drm_get_color_range_name(enum drm_color_range range);
/* IOCTLs */ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
On Mon, Feb 19, 2018 at 10:28:46PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Include color_enconding and color_range in the plane state dump.
v2: Add kerneldoc (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic.c | 4 ++++ drivers/gpu/drm/drm_color_mgmt.c | 30 ++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 ++ 3 files changed, 36 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 452a0b0bafbc..9552052ed31a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -952,6 +952,10 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest)); drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src)); drm_printf(p, "\trotation=%x\n", state->rotation);
drm_printf(p, "\tcolor-encoding=%s\n",
drm_get_color_encoding_name(state->color_encoding));
drm_printf(p, "\tcolor-range=%s\n",
drm_get_color_range_name(state->color_range));
if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 7b0f1c2d9190..a11a838741c2 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -367,6 +367,36 @@ static const char * const color_range_name[] = { };
/**
- drm_get_color_encoding_name - return a string for color encoding
- @encoding: color encoding 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_color_encoding_name(enum drm_color_encoding encoding) +{
- if (WARN_ON(encoding >= ARRAY_SIZE(color_encoding_name)))
return "unknown";
- return color_encoding_name[encoding];
+}
+/**
- drm_get_color_range_name - return a string for color range
- @range: color range 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_color_range_name(enum drm_color_range range) +{
- if (WARN_ON(range >= ARRAY_SIZE(color_range_name)))
return "unknown";
- return color_range_name[range];
+}
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index af00f42ba269..8ca2ffef6231 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -71,6 +71,8 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
/* drm_color_mgmt.c */ +const char *drm_get_color_encoding_name(enum drm_color_encoding encoding); +const char *drm_get_color_range_name(enum drm_color_range range);
/* IOCTLs */ int drm_mode_gamma_get_ioctl(struct drm_device *dev, -- 2.13.6
On 2018-02-19 03:28 PM, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Include color_enconding and color_range in the plane state dump.
v2: Add kerneldoc (danvet)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
Latest patches for 1-3 are Acked-by: Harry Wentland harry.wentland@amd.com
Harry
drivers/gpu/drm/drm_atomic.c | 4 ++++ drivers/gpu/drm/drm_color_mgmt.c | 30 ++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 ++ 3 files changed, 36 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 452a0b0bafbc..9552052ed31a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -952,6 +952,10 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest)); drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src)); drm_printf(p, "\trotation=%x\n", state->rotation);
drm_printf(p, "\tcolor-encoding=%s\n",
drm_get_color_encoding_name(state->color_encoding));
drm_printf(p, "\tcolor-range=%s\n",
drm_get_color_range_name(state->color_range));
if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 7b0f1c2d9190..a11a838741c2 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -367,6 +367,36 @@ static const char * const color_range_name[] = { };
/**
- drm_get_color_encoding_name - return a string for color encoding
- @encoding: color encoding 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_color_encoding_name(enum drm_color_encoding encoding) +{
- if (WARN_ON(encoding >= ARRAY_SIZE(color_encoding_name)))
return "unknown";
- return color_encoding_name[encoding];
+}
+/**
- drm_get_color_range_name - return a string for color range
- @range: color range 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_color_range_name(enum drm_color_range range) +{
- if (WARN_ON(range >= ARRAY_SIZE(color_range_name)))
return "unknown";
- return color_range_name[range];
+}
+/**
- drm_plane_create_color_properties - color encoding related plane properties
- @plane: plane object
- @supported_encodings: bitfield indicating supported color encodings
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index af00f42ba269..8ca2ffef6231 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -71,6 +71,8 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
/* drm_color_mgmt.c */ +const char *drm_get_color_encoding_name(enum drm_color_encoding encoding); +const char *drm_get_color_range_name(enum drm_color_range range);
/* IOCTLs */ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
From: Ville Syrjälä ville.syrjala@linux.intel.com
Turns out the VLV/CHV fixed function sprite CSC expects full range data as input. We've been feeding it limited range data to it all along. To expand the data out to full range we'll use the color correction registers (brightness, contrast, and saturation).
On CHV pipe B we were actually doing the right thing already because we progammed the custom CSC matrix to do expect limited range input. Now that well pre-expand the data out with the color correction unit, we need to change the CSC matrix to operate with full range input instead.
This should make the sprite output of the other pipes match the sprite output of pipe B reasonably well. Looking at the resulting pipe CRCs, there can be a slight difference in the output, but as I don't know the formula used by the fixed function CSC of the other pipes, I don't think it's worth the effort to try to match the output exactly. It might not even be possible due to difference in internal precision etc.
One slight caveat here is that the color correction registers are single bufferred, so we should really be updating them during vblank, but we still don't have a mechanism for that, so just toss in another FIXME.
v2: Rebase v3: s/bri/brightness/ s/con/contrast/ (Shashank) v4: Clarify the constants and math (Shashank)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Shashank Sharma shashank.sharma@intel.com Cc: Uma Shankar uma.shankar@intel.com Cc: Jyri Sarha jsarha@ti.com Cc: "Tang, Jun" jun.tang@intel.com Reported-by: "Tang, Jun" jun.tang@intel.com Cc: stable@vger.kernel.org Fixes: 7f1f3851feb0 ("drm/i915: sprite support for ValleyView v4") Reviewed-by: Shashank Sharma shashank.sharma@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 10 +++++ drivers/gpu/drm/i915/intel_sprite.c | 81 ++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f6afa5e5e7c1..28b36eac064e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6305,6 +6305,12 @@ enum { #define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4) #define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8) #define SP_CONST_ALPHA_ENABLE (1<<31) +#define _SPACLRC0 (VLV_DISPLAY_BASE + 0x721d0) +#define SP_CONTRAST(x) ((x) << 18) /* u3.6 */ +#define SP_BRIGHTNESS(x) ((x) & 0xff) /* s8 */ +#define _SPACLRC1 (VLV_DISPLAY_BASE + 0x721d4) +#define SP_SH_SIN(x) (((x) & 0x7ff) << 16) /* s4.7 */ +#define SP_SH_COS(x) (x) /* u3.7 */ #define _SPAGAMC (VLV_DISPLAY_BASE + 0x721f4)
#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280) @@ -6318,6 +6324,8 @@ enum { #define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0) #define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4) #define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8) +#define _SPBCLRC0 (VLV_DISPLAY_BASE + 0x722d0) +#define _SPBCLRC1 (VLV_DISPLAY_BASE + 0x722d4) #define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4)
#define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \ @@ -6334,6 +6342,8 @@ enum { #define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL) #define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF) #define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA) +#define SPCLRC0(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC0, _SPBCLRC0) +#define SPCLRC1(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC1, _SPBCLRC1) #define SPGAMC(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAGAMC, _SPBGAMC)
/* diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index e098e4b2c85c..fac9e01b4795 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -346,44 +346,87 @@ skl_plane_get_hw_state(struct intel_plane *plane) }
static void -chv_update_csc(struct intel_plane *plane, uint32_t format) +chv_update_csc(const struct intel_plane_state *plane_state) { + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + const struct drm_framebuffer *fb = plane_state->base.fb; enum plane_id plane_id = plane->id;
/* Seems RGB data bypasses the CSC always */ - if (!format_is_yuv(format)) + if (!format_is_yuv(fb->format->format)) return;
/* - * BT.601 limited range YCbCr -> full range RGB + * BT.601 full range YCbCr -> full range RGB * - * |r| | 6537 4769 0| |cr | - * |g| = |-3330 4769 -1605| x |y-64| - * |b| | 0 4769 8263| |cb | + * |r| | 5743 4096 0| |cr| + * |g| = |-2925 4096 -1410| x |y | + * |b| | 0 4096 7258| |cb| * - * Cb and Cr apparently come in as signed already, so no - * need for any offset. For Y we need to remove the offset. + * Cb and Cr apparently come in as signed already, + * and we get full range data in on account of CLRC0/1 */ - I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(-64)); + I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
- I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4769) | SPCSC_C0(6537)); - I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-3330) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1605) | SPCSC_C0(4769)); - I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4769) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(8263)); + I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4096) | SPCSC_C0(5743)); + I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-2925) | SPCSC_C0(0)); + I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1410) | SPCSC_C0(4096)); + I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4096) | SPCSC_C0(0)); + I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(7258));
- I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(940) | SPCSC_IMIN(64)); - I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); - I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); + I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); + I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); + I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); }
+#define SIN_0 0 +#define COS_0 1 + +static void +vlv_update_clrc(const struct intel_plane_state *plane_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + const struct drm_framebuffer *fb = plane_state->base.fb; + enum pipe pipe = plane->pipe; + enum plane_id plane_id = plane->id; + int contrast, brightness, sh_scale, sh_sin, sh_cos; + + if (format_is_yuv(fb->format->format)) { + /* + * Expand limited range to full range: + * Contrast is applied first and is used to expand Y range. + * Brightness is applied second and is used to remove the + * offset from Y. Saturation/hue is used to expand CbCr range. + */ + contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16); + brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16); + sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128); + sh_sin = SIN_0 * sh_scale; + sh_cos = COS_0 * sh_scale; + } else { + /* Pass-through everything. */ + contrast = 1 << 6; + brightness = 0; + sh_scale = 1 << 7; + sh_sin = SIN_0 * sh_scale; + sh_cos = COS_0 * sh_scale; + } + + /* FIXME these register are single buffered :( */ + I915_WRITE_FW(SPCLRC0(pipe, plane_id), + SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness)); + I915_WRITE_FW(SPCLRC1(pipe, plane_id), + SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos)); +} + static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -477,8 +520,10 @@ vlv_update_plane(struct intel_plane *plane,
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+ vlv_update_clrc(plane_state); + if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) - chv_update_csc(plane, fb->format->format); + chv_update_csc(plane_state);
if (key->flags) { I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
From: Ville Syrjälä ville.syrjala@linux.intel.com
On GLK the plane CSC controls moved into the COLOR_CTL register. Update the code to progam the YCbCr->RGB CSC mode correctly when faced with an YCbCr framebuffer.
The spec is rather confusing as it calls the mode "YUV601 to RGB709". I'm going to assume that just means it's going to use the YCbCr->RGB matrix as specified in BT.601 and doesn't actually change the gamut.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 5 +++++ drivers/gpu/drm/i915/intel_display.c | 3 +++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_sprite.c | 10 +++++----- 4 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 28b36eac064e..6abeaf64c2d2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6463,6 +6463,11 @@ enum { #define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ #define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) #define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) +#define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17) +#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17) +#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 (2 << 17) +#define PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020 (3 << 17) +#define PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020 (4 << 17) #define PLANE_COLOR_PLANE_GAMMA_DISABLE (1 << 13) #define PLANE_COLOR_ALPHA_MASK (0x3 << 4) #define PLANE_COLOR_ALPHA_DISABLE (0 << 4) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 286a9591d179..a22b583838f7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3573,6 +3573,9 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
+ if (intel_format_is_yuv(fb->format->format)) + plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + return plane_color_ctl; }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 898064e8bea7..6e43da40c859 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1591,6 +1591,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); +u32 glk_color_ctl(const struct intel_plane_state *plane_state); u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, unsigned int rotation); int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, @@ -2016,6 +2017,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
/* intel_sprite.c */ +bool intel_format_is_yuv(u32 format); int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, int usecs); struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index fac9e01b4795..b4acde2058fe 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -41,8 +41,7 @@ #include <drm/i915_drm.h> #include "i915_drv.h"
-static bool -format_is_yuv(uint32_t format) +bool intel_format_is_yuv(u32 format) { switch (format) { case DRM_FORMAT_YUYV: @@ -266,6 +265,7 @@ skl_update_plane(struct intel_plane *plane, if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_state->color_ctl); + if (key->flags) { I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value); @@ -354,7 +354,7 @@ chv_update_csc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id;
/* Seems RGB data bypasses the CSC always */ - if (!format_is_yuv(fb->format->format)) + if (!intel_format_is_yuv(fb->format->format)) return;
/* @@ -399,7 +399,7 @@ vlv_update_clrc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id; int contrast, brightness, sh_scale, sh_sin, sh_cos;
- if (format_is_yuv(fb->format->format)) { + if (intel_format_is_yuv(fb->format->format)) { /* * Expand limited range to full range: * Contrast is applied first and is used to expand Y range. @@ -1024,7 +1024,7 @@ intel_check_sprite_plane(struct intel_plane *plane, src_y = src->y1 >> 16; src_h = drm_rect_height(src) >> 16;
- if (format_is_yuv(fb->format->format)) { + if (intel_format_is_yuv(fb->format->format)) { src_x &= ~1; src_w &= ~1;
On Wed, Feb 14, 2018 at 09:23:24PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
On GLK the plane CSC controls moved into the COLOR_CTL register. Update the code to progam the YCbCr->RGB CSC mode correctly when faced with an YCbCr framebuffer.
The spec is rather confusing as it calls the mode "YUV601 to RGB709". I'm going to assume that just means it's going to use the YCbCr->RGB matrix as specified in BT.601 and doesn't actually change the gamut.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
Matches the spec, so: Reviewed-by: Imre Deak imre.deak@intel.com
I asked for clarification in the spec about the BT.601 vs. 709 oddity you noticed.
drivers/gpu/drm/i915/i915_reg.h | 5 +++++ drivers/gpu/drm/i915/intel_display.c | 3 +++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_sprite.c | 10 +++++----- 4 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 28b36eac064e..6abeaf64c2d2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6463,6 +6463,11 @@ enum { #define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ #define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) #define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) +#define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17) +#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17) +#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 (2 << 17) +#define PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020 (3 << 17) +#define PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020 (4 << 17) #define PLANE_COLOR_PLANE_GAMMA_DISABLE (1 << 13) #define PLANE_COLOR_ALPHA_MASK (0x3 << 4) #define PLANE_COLOR_ALPHA_DISABLE (0 << 4) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 286a9591d179..a22b583838f7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3573,6 +3573,9 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
- if (intel_format_is_yuv(fb->format->format))
plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709;
- return plane_color_ctl;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 898064e8bea7..6e43da40c859 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1591,6 +1591,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); +u32 glk_color_ctl(const struct intel_plane_state *plane_state); u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, unsigned int rotation); int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, @@ -2016,6 +2017,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
/* intel_sprite.c */ +bool intel_format_is_yuv(u32 format); int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, int usecs); struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index fac9e01b4795..b4acde2058fe 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -41,8 +41,7 @@ #include <drm/i915_drm.h> #include "i915_drv.h"
-static bool -format_is_yuv(uint32_t format) +bool intel_format_is_yuv(u32 format) { switch (format) { case DRM_FORMAT_YUYV: @@ -266,6 +265,7 @@ skl_update_plane(struct intel_plane *plane, if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_state->color_ctl);
- if (key->flags) { I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value);
@@ -354,7 +354,7 @@ chv_update_csc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id;
/* Seems RGB data bypasses the CSC always */
- if (!format_is_yuv(fb->format->format))
if (!intel_format_is_yuv(fb->format->format)) return;
/*
@@ -399,7 +399,7 @@ vlv_update_clrc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id; int contrast, brightness, sh_scale, sh_sin, sh_cos;
- if (format_is_yuv(fb->format->format)) {
- if (intel_format_is_yuv(fb->format->format)) { /*
- Expand limited range to full range:
- Contrast is applied first and is used to expand Y range.
@@ -1024,7 +1024,7 @@ intel_check_sprite_plane(struct intel_plane *plane, src_y = src->y1 >> 16; src_h = drm_rect_height(src) >> 16;
if (format_is_yuv(fb->format->format)) {
if (intel_format_is_yuv(fb->format->format)) { src_x &= ~1; src_w &= ~1;
-- 2.13.6
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
From: Ville Syrjälä ville.syrjala@linux.intel.com
Add support for the COLOR_ENCODING plane property which selects the matrix coefficients used for the YCbCr->RGB conversion. Our hardware can generally handle BT.601 and BT.709.
CHV pipe B sprites have a fully programmable matrix, so in theory we could handle anything, but it doesn't seem all that useful to expose anything beyond BT.601 and BT.709 at this time.
GLK can supposedly do BT.2020, but let's leave enabling that for the future as well.
v2: Rename bit defines to match the spec more closely (Shashank)
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Reviewed-by: Shashank Sharma shashank.sharma@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 5 ++- drivers/gpu/drm/i915/intel_display.c | 19 +++++++++-- drivers/gpu/drm/i915/intel_sprite.c | 61 +++++++++++++++++++++++++++--------- 3 files changed, 67 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6abeaf64c2d2..6061f418c88d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6140,6 +6140,7 @@ enum { #define DVS_PIPE_CSC_ENABLE (1<<24) #define DVS_SOURCE_KEY (1<<22) #define DVS_RGB_ORDER_XBGR (1<<20) +#define DVS_YUV_FORMAT_BT709 (1<<18) #define DVS_YUV_BYTE_ORDER_MASK (3<<16) #define DVS_YUV_ORDER_YUYV (0<<16) #define DVS_YUV_ORDER_UYVY (1<<16) @@ -6210,7 +6211,7 @@ enum { #define SPRITE_SOURCE_KEY (1<<22) #define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */ #define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19) -#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */ +#define SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */ #define SPRITE_YUV_BYTE_ORDER_MASK (3<<16) #define SPRITE_YUV_ORDER_YUYV (0<<16) #define SPRITE_YUV_ORDER_UYVY (1<<16) @@ -6286,6 +6287,7 @@ enum { #define SP_FORMAT_RGBA8888 (0xf<<26) #define SP_ALPHA_PREMULTIPLY (1<<23) /* CHV pipe B */ #define SP_SOURCE_KEY (1<<22) +#define SP_YUV_FORMAT_BT709 (1<<18) #define SP_YUV_BYTE_ORDER_MASK (3<<16) #define SP_YUV_ORDER_YUYV (0<<16) #define SP_YUV_ORDER_UYVY (1<<16) @@ -6410,6 +6412,7 @@ enum { #define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21) #define PLANE_CTL_ORDER_BGRX (0 << 20) #define PLANE_CTL_ORDER_RGBX (1 << 20) +#define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 (1 << 18) #define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16) #define PLANE_CTL_YUV422_YUYV ( 0 << 16) #define PLANE_CTL_YUV422_UYVY ( 1 << 16) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a22b583838f7..8c11d2a993a8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3544,6 +3544,9 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, PLANE_CTL_PIPE_GAMMA_ENABLE | PLANE_CTL_PIPE_CSC_ENABLE | PLANE_CTL_PLANE_GAMMA_DISABLE; + + if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709; }
plane_ctl |= skl_plane_ctl_format(fb->format->format); @@ -3573,8 +3576,12 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
- if (intel_format_is_yuv(fb->format->format)) - plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + if (intel_format_is_yuv(fb->format->format)) { + if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709; + else + plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + }
return plane_color_ctl; } @@ -13314,6 +13321,14 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) DRM_MODE_ROTATE_0, supported_rotations);
+ if (INTEL_GEN(dev_priv) >= 9) + drm_plane_create_color_properties(&primary->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_LIMITED_RANGE); + drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
return primary; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index b4acde2058fe..3a79a641a343 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -352,30 +352,45 @@ chv_update_csc(const struct intel_plane_state *plane_state) struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->base.fb; enum plane_id plane_id = plane->id; + /* + * |r| | c0 c1 c2 | |cr| + * |g| = | c3 c4 c5 | x |y | + * |b| | c6 c7 c8 | |cb| + * + * Coefficients are s3.12. + * + * Cb and Cr apparently come in as signed already, and + * we always get full range data in on account of CLRC0/1. + */ + static const s16 csc_matrix[][9] = { + /* BT.601 full range YCbCr -> full range RGB */ + [DRM_COLOR_YCBCR_BT601] = { + 5743, 4096, 0, + -2925, 4096, -1410, + 0, 4096, 7258, + }, + /* BT.709 full range YCbCr -> full range RGB */ + [DRM_COLOR_YCBCR_BT709] = { + 6450, 4096, 0, + -1917, 4096, -767, + 0, 4096, 7601, + }, + }; + const s16 *csc = csc_matrix[plane_state->base.color_encoding];
/* Seems RGB data bypasses the CSC always */ if (!intel_format_is_yuv(fb->format->format)) return;
- /* - * BT.601 full range YCbCr -> full range RGB - * - * |r| | 5743 4096 0| |cr| - * |g| = |-2925 4096 -1410| x |y | - * |b| | 0 4096 7258| |cb| - * - * Cb and Cr apparently come in as signed already, - * and we get full range data in on account of CLRC0/1 - */ I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
- I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4096) | SPCSC_C0(5743)); - I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-2925) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1410) | SPCSC_C0(4096)); - I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4096) | SPCSC_C0(0)); - I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(7258)); + I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0])); + I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2])); + I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4])); + I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6])); + I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); @@ -476,6 +491,9 @@ static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, return 0; }
+ if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + sprctl |= SP_YUV_FORMAT_BT709; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SP_TILED;
@@ -629,6 +647,9 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, return 0; }
+ if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SPRITE_TILED;
@@ -785,6 +806,9 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, return 0; }
+ if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) + dvscntr |= DVS_YUV_FORMAT_BT709; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) dvscntr |= DVS_TILED;
@@ -1504,6 +1528,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, DRM_MODE_ROTATE_0, supported_rotations);
+ drm_plane_create_color_properties(&intel_plane->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_LIMITED_RANGE); + drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
return intel_plane;
From: Ville Syrjälä ville.syrjala@linux.intel.com
Bring us forward from the stone age and switch our default YCbCr->RGB conversion matrix to BT.709 from BT.601. I would expect most matrial to be BT.709 these days.
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Acked-by: Shashank Sharma shashank.sharma@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_sprite.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8c11d2a993a8..89c4bda91ecb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13326,7 +13326,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), - DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE);
drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 3a79a641a343..49969b2f3494 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1532,7 +1532,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), - DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE);
drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
From: Ville Syrjälä ville.syrjala@linux.intel.com
Add support for the COLOR_RANGE property on planes. This property selects whether the input YCbCr data is to treated as limited range or full range.
On most platforms this is a matter of setting the "YUV range correction disable" bit, and on VLV/CHV we'll just have to program the color correction logic to pass the data through unmodified.
v2: Rebase
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com Cc: Jyri Sarha jsarha@ti.com Reviewed-by: Shashank Sharma shashank.sharma@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ drivers/gpu/drm/i915/intel_display.c | 9 ++++++++- drivers/gpu/drm/i915/intel_sprite.c | 12 ++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6061f418c88d..405a651eea11 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6132,6 +6132,7 @@ enum { #define _DVSACNTR 0x72180 #define DVS_ENABLE (1<<31) #define DVS_GAMMA_ENABLE (1<<30) +#define DVS_YUV_RANGE_CORRECTION_DISABLE (1<<27) #define DVS_PIXFORMAT_MASK (3<<25) #define DVS_FORMAT_YUV422 (0<<25) #define DVS_FORMAT_RGBX101010 (1<<25) @@ -6200,6 +6201,7 @@ enum { #define _SPRA_CTL 0x70280 #define SPRITE_ENABLE (1<<31) #define SPRITE_GAMMA_ENABLE (1<<30) +#define SPRITE_YUV_RANGE_CORRECTION_DISABLE (1<<28) #define SPRITE_PIXFORMAT_MASK (7<<25) #define SPRITE_FORMAT_YUV422 (0<<25) #define SPRITE_FORMAT_RGBX101010 (1<<25) @@ -6391,6 +6393,7 @@ enum { #define _PLANE_CTL_3_A 0x70380 #define PLANE_CTL_ENABLE (1 << 31) #define PLANE_CTL_PIPE_GAMMA_ENABLE (1 << 30) /* Pre-GLK */ +#define PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE (1 << 28) /* * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition * expanded to include bit 23 as well. However, the shift-24 based values @@ -6465,6 +6468,7 @@ enum { #define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */ #define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ #define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) +#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE (1 << 28) #define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) #define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17) #define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 89c4bda91ecb..3d21eca18602 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3547,6 +3547,9 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709; + + if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE; }
plane_ctl |= skl_plane_ctl_format(fb->format->format); @@ -3581,6 +3584,9 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709; else plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709; + + if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE; }
return plane_color_ctl; @@ -13325,7 +13331,8 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) drm_plane_create_color_properties(&primary->base, BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), - BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 49969b2f3494..dbdcf85032df 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -414,7 +414,8 @@ vlv_update_clrc(const struct intel_plane_state *plane_state) enum plane_id plane_id = plane->id; int contrast, brightness, sh_scale, sh_sin, sh_cos;
- if (intel_format_is_yuv(fb->format->format)) { + if (intel_format_is_yuv(fb->format->format) && + plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) { /* * Expand limited range to full range: * Contrast is applied first and is used to expand Y range. @@ -650,6 +651,9 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
+ if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) sprctl |= SPRITE_TILED;
@@ -809,6 +813,9 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) dvscntr |= DVS_YUV_FORMAT_BT709;
+ if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE) + dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE; + if (fb->modifier == I915_FORMAT_MOD_X_TILED) dvscntr |= DVS_TILED;
@@ -1531,7 +1538,8 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, drm_plane_create_color_properties(&intel_plane->base, BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709), - BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE);
On Wed, Feb 14, 2018 at 09:23:19PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Here's a refresh of Jyri's COLOR_ENCODING and COLOR_RANGE properties, and the i915 implementation I did on top. I tossed in a few core updates as well: plane state dump, and the BT.2020 constant luminance variant.
Apparently nouveau is already exposing a "iturbt_709" bool property which allows one to choose between BT.601 and BT.709 encodings, but given that we want at least BT.2020 in addition I don't think that property is good enough. Trying to implement it, and somehow extend it beyond BT.601 vs. BT.709 seems like wasted effort. Hence I think we should just ignore it and move on.
Yeah, with those legacy props in various kernels I think it's best if we ignore them, and leave the burden of figuring out compatibility interactions to the driver that went their own way. I'll ping Illia as fyi on irc at least. -Daniel
My userspace implementation in the form of intel ddx XV_COLORSPACE attribute: https://patchwork.freedesktop.org/patch/204696/
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com
Jyri Sarha (1): drm: Add optional COLOR_ENCODING and COLOR_RANGE properties to drm_plane
Ville Syrjälä (7): drm: Add BT.2020 constant luminance enum value for the COLOR_ENCODING property drm/atomic: Include color encoding/range in plane state dump drm/i915: Correctly handle limited range YCbCr data on VLV/CHV drm/i915: Fix plane YCbCr->RGB conversion for GLK drm/i915: Add support for the YCbCr COLOR_ENCODING property drm/i915: Change the COLOR_ENCODING prop default value to BT.709 drm/i915: Add support for the YCbCr COLOR_RANGE property
drivers/gpu/drm/drm_atomic.c | 12 ++++ drivers/gpu/drm/drm_color_mgmt.c | 108 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 24 ++++++- drivers/gpu/drm/i915/intel_display.c | 25 +++++++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_sprite.c | 134 ++++++++++++++++++++++++++++------- include/drm/drm_color_mgmt.h | 20 ++++++ include/drm/drm_plane.h | 8 +++ 9 files changed, 309 insertions(+), 26 deletions(-)
-- 2.13.6
On Wed, Feb 14, 2018 at 09:23:19PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Here's a refresh of Jyri's COLOR_ENCODING and COLOR_RANGE properties, and the i915 implementation I did on top. I tossed in a few core updates as well: plane state dump, and the BT.2020 constant luminance variant.
Apparently nouveau is already exposing a "iturbt_709" bool property which allows one to choose between BT.601 and BT.709 encodings, but given that we want at least BT.2020 in addition I don't think that property is good enough. Trying to implement it, and somehow extend it beyond BT.601 vs. BT.709 seems like wasted effort. Hence I think we should just ignore it and move on.
My userspace implementation in the form of intel ddx XV_COLORSPACE attribute: https://patchwork.freedesktop.org/patch/204696/
Any plans to get this going for -modesetting too? Distro's kinda stopped shipping -intel. -Daniel
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com
Jyri Sarha (1): drm: Add optional COLOR_ENCODING and COLOR_RANGE properties to drm_plane
Ville Syrjälä (7): drm: Add BT.2020 constant luminance enum value for the COLOR_ENCODING property drm/atomic: Include color encoding/range in plane state dump drm/i915: Correctly handle limited range YCbCr data on VLV/CHV drm/i915: Fix plane YCbCr->RGB conversion for GLK drm/i915: Add support for the YCbCr COLOR_ENCODING property drm/i915: Change the COLOR_ENCODING prop default value to BT.709 drm/i915: Add support for the YCbCr COLOR_RANGE property
drivers/gpu/drm/drm_atomic.c | 12 ++++ drivers/gpu/drm/drm_color_mgmt.c | 108 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 24 ++++++- drivers/gpu/drm/i915/intel_display.c | 25 +++++++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_sprite.c | 134 ++++++++++++++++++++++++++++------- include/drm/drm_color_mgmt.h | 20 ++++++ include/drm/drm_plane.h | 8 +++ 9 files changed, 309 insertions(+), 26 deletions(-)
-- 2.13.6
On Mon, Feb 19, 2018 at 04:09:24PM +0100, Daniel Vetter wrote:
On Wed, Feb 14, 2018 at 09:23:19PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Here's a refresh of Jyri's COLOR_ENCODING and COLOR_RANGE properties, and the i915 implementation I did on top. I tossed in a few core updates as well: plane state dump, and the BT.2020 constant luminance variant.
Apparently nouveau is already exposing a "iturbt_709" bool property which allows one to choose between BT.601 and BT.709 encodings, but given that we want at least BT.2020 in addition I don't think that property is good enough. Trying to implement it, and somehow extend it beyond BT.601 vs. BT.709 seems like wasted effort. Hence I think we should just ignore it and move on.
My userspace implementation in the form of intel ddx XV_COLORSPACE attribute: https://patchwork.freedesktop.org/patch/204696/
Any plans to get this going for -modesetting too? Distro's kinda stopped shipping -intel.
No plans by me since I don't use -modesetting. Volunteers welcome.
On Wed, Feb 14, 2018 at 09:23:19PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Here's a refresh of Jyri's COLOR_ENCODING and COLOR_RANGE properties, and the i915 implementation I did on top. I tossed in a few core updates as well: plane state dump, and the BT.2020 constant luminance variant.
Apparently nouveau is already exposing a "iturbt_709" bool property which allows one to choose between BT.601 and BT.709 encodings, but given that we want at least BT.2020 in addition I don't think that property is good enough. Trying to implement it, and somehow extend it beyond BT.601 vs. BT.709 seems like wasted effort. Hence I think we should just ignore it and move on.
I discussed the nouveau situation with Illia, and apparently there's not yet any userspace using it. Which means we could still quickly rename it, before Illia adds the ddx support. Would be great if someone could do that :-)
Cheers, Daniel
My userspace implementation in the form of intel ddx XV_COLORSPACE attribute: https://patchwork.freedesktop.org/patch/204696/
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com
Jyri Sarha (1): drm: Add optional COLOR_ENCODING and COLOR_RANGE properties to drm_plane
Ville Syrjälä (7): drm: Add BT.2020 constant luminance enum value for the COLOR_ENCODING property drm/atomic: Include color encoding/range in plane state dump drm/i915: Correctly handle limited range YCbCr data on VLV/CHV drm/i915: Fix plane YCbCr->RGB conversion for GLK drm/i915: Add support for the YCbCr COLOR_ENCODING property drm/i915: Change the COLOR_ENCODING prop default value to BT.709 drm/i915: Add support for the YCbCr COLOR_RANGE property
drivers/gpu/drm/drm_atomic.c | 12 ++++ drivers/gpu/drm/drm_color_mgmt.c | 108 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 24 ++++++- drivers/gpu/drm/i915/intel_display.c | 25 +++++++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_sprite.c | 134 ++++++++++++++++++++++++++++------- include/drm/drm_color_mgmt.h | 20 ++++++ include/drm/drm_plane.h | 8 +++ 9 files changed, 309 insertions(+), 26 deletions(-)
-- 2.13.6
On Tue, Feb 20, 2018 at 12:26:59PM +0100, Daniel Vetter wrote:
On Wed, Feb 14, 2018 at 09:23:19PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Here's a refresh of Jyri's COLOR_ENCODING and COLOR_RANGE properties, and the i915 implementation I did on top. I tossed in a few core updates as well: plane state dump, and the BT.2020 constant luminance variant.
Apparently nouveau is already exposing a "iturbt_709" bool property which allows one to choose between BT.601 and BT.709 encodings, but given that we want at least BT.2020 in addition I don't think that property is good enough. Trying to implement it, and somehow extend it beyond BT.601 vs. BT.709 seems like wasted effort. Hence I think we should just ignore it and move on.
I discussed the nouveau situation with Illia, and apparently there's not yet any userspace using it.
Hmm. Yeah, looks like the Xv port attribute is there in nv/nouveau ddx but it's not implemented via the kms property.
Which means we could still quickly rename it, before Illia adds the ddx support. Would be great if someone could do that :-)
Cheers, Daniel
My userspace implementation in the form of intel ddx XV_COLORSPACE attribute: https://patchwork.freedesktop.org/patch/204696/
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com
Jyri Sarha (1): drm: Add optional COLOR_ENCODING and COLOR_RANGE properties to drm_plane
Ville Syrjälä (7): drm: Add BT.2020 constant luminance enum value for the COLOR_ENCODING property drm/atomic: Include color encoding/range in plane state dump drm/i915: Correctly handle limited range YCbCr data on VLV/CHV drm/i915: Fix plane YCbCr->RGB conversion for GLK drm/i915: Add support for the YCbCr COLOR_ENCODING property drm/i915: Change the COLOR_ENCODING prop default value to BT.709 drm/i915: Add support for the YCbCr COLOR_RANGE property
drivers/gpu/drm/drm_atomic.c | 12 ++++ drivers/gpu/drm/drm_color_mgmt.c | 108 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_internal.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 24 ++++++- drivers/gpu/drm/i915/intel_display.c | 25 +++++++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_sprite.c | 134 ++++++++++++++++++++++++++++------- include/drm/drm_color_mgmt.h | 20 ++++++ include/drm/drm_plane.h | 8 +++ 9 files changed, 309 insertions(+), 26 deletions(-)
-- 2.13.6
-- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
On Wed, Feb 14, 2018 at 09:23:19PM +0200, Ville Syrjala wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
Here's a refresh of Jyri's COLOR_ENCODING and COLOR_RANGE properties, and the i915 implementation I did on top. I tossed in a few core updates as well: plane state dump, and the BT.2020 constant luminance variant.
Apparently nouveau is already exposing a "iturbt_709" bool property which allows one to choose between BT.601 and BT.709 encodings, but given that we want at least BT.2020 in addition I don't think that property is good enough. Trying to implement it, and somehow extend it beyond BT.601 vs. BT.709 seems like wasted effort. Hence I think we should just ignore it and move on.
My userspace implementation in the form of intel ddx XV_COLORSPACE attribute: https://patchwork.freedesktop.org/patch/204696/
Cc: Harry Wentland harry.wentland@amd.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Daniel Stone daniel@fooishbar.org Cc: Russell King - ARM Linux linux@armlinux.org.uk Cc: Ilia Mirkin imirkin@alum.mit.edu Cc: Hans Verkuil hverkuil@xs4all.nl Cc: Uma Shankar uma.shankar@intel.com Cc: Shashank Sharma shashank.sharma@intel.com
Jyri Sarha (1): drm: Add optional COLOR_ENCODING and COLOR_RANGE properties to drm_plane
Ville Syrjälä (7): drm: Add BT.2020 constant luminance enum value for the COLOR_ENCODING property drm/atomic: Include color encoding/range in plane state dump drm/i915: Correctly handle limited range YCbCr data on VLV/CHV drm/i915: Fix plane YCbCr->RGB conversion for GLK drm/i915: Add support for the YCbCr COLOR_ENCODING property drm/i915: Change the COLOR_ENCODING prop default value to BT.709 drm/i915: Add support for the YCbCr COLOR_RANGE property
Userspace for i915 was deemed ready [1] so I've pushed the series (apart from the BT2020_CONST thing) to drm-misc-next. Thanks to everyone who worked on this.
[1] https://lists.freedesktop.org/archives/intel-gfx/2018-March/157512.html
dri-devel@lists.freedesktop.org