sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget*/translations/zh_CN/gpu/rfc/color_pipelinemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/zh_TW/gpu/rfc/color_pipelinemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/it_IT/gpu/rfc/color_pipelinemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ja_JP/gpu/rfc/color_pipelinemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ko_KR/gpu/rfc/color_pipelinemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/sp_SP/gpu/rfc/color_pipelinemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhD/var/lib/git/docbuild/linux/Documentation/gpu/rfc/color_pipeline.rsthKubhsection)}(hhh](htitle)}(hLinux Color Pipeline APIh]hLinux Color Pipeline API}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hWhat problem are we solving?h]hWhat problem are we solving?}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hWe would like to support pre-, and post-blending complex color transformations in display controller hardware in order to allow for HW-supported HDR use-cases, as well as to provide support to color-managed applications, such as video or image editors.h]hWe would like to support pre-, and post-blending complex color transformations in display controller hardware in order to allow for HW-supported HDR use-cases, as well as to provide support to color-managed applications, such as video or image editors.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hXIt is possible to support an HDR output on HW supporting the Colorspace and HDR Metadata drm_connector properties, but that requires the compositor or application to render and compose the content into one final buffer intended for display. Doing so is costly.h]hXIt is possible to support an HDR output on HW supporting the Colorspace and HDR Metadata drm_connector properties, but that requires the compositor or application to render and compose the content into one final buffer intended for display. Doing so is costly.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXMost modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other operations to support color transformations. These operations are often implemented in fixed-function HW and therefore much more power efficient than performing similar operations via shaders or CPU.h]hXMost modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other operations to support color transformations. These operations are often implemented in fixed-function HW and therefore much more power efficient than performing similar operations via shaders or CPU.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hX"We would like to make use of this HW functionality to support complex color transformations with no, or minimal CPU or shader load. The switch between HW fixed-function blocks and shaders/CPU must be seamless with no visible difference when fallback to shaders/CPU is neceesary at any time.h]hX"We would like to make use of this HW functionality to support complex color transformations with no, or minimal CPU or shader load. The switch between HW fixed-function blocks and shaders/CPU must be seamless with no visible difference when fallback to shaders/CPU is neceesary at any time.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]what-problem-are-we-solvingah ]h"]what problem are we solving?ah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h(How are other OSes solving this problem?h]h(How are other OSes solving this problem?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK ubh)}(hPThe most widely supported use-cases regard HDR content, whether video or gaming.h]hPThe most widely supported use-cases regard HDR content, whether video or gaming.}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK"hjhhubh)}(hX!Most OSes will specify the source content format (color gamut, encoding transfer function, and other metadata, such as max and average light levels) to a driver. Drivers will then program their fixed-function HW accordingly to map from a source content buffer's space to a display's space.h]hX%Most OSes will specify the source content format (color gamut, encoding transfer function, and other metadata, such as max and average light levels) to a driver. Drivers will then program their fixed-function HW accordingly to map from a source content buffer’s space to a display’s space.}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK%hjhhubh)}(hWhen fixed-function HW is not available the compositor will assemble a shader to ask the GPU to perform the transformation from the source content format to the display's format.h]hWhen fixed-function HW is not available the compositor will assemble a shader to ask the GPU to perform the transformation from the source content format to the display’s format.}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK*hjhhubh)}(hXxA compositor's mapping function and a driver's mapping function are usually entirely separate concepts. On OSes where a HW vendor has no insight into closed-source compositor code such a vendor will tune their color management code to visually match the compositor's. On other OSes, where both mapping functions are open to an implementer they will ensure both mappings match.h]hX~A compositor’s mapping function and a driver’s mapping function are usually entirely separate concepts. On OSes where a HW vendor has no insight into closed-source compositor code such a vendor will tune their color management code to visually match the compositor’s. On other OSes, where both mapping functions are open to an implementer they will ensure both mappings match.}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjhhubh)}(hThis results in mapping algorithm lock-in, meaning that no-one alone can experiment with or introduce new mapping algorithms and achieve consistent results regardless of which implementation path is taken.h]hThis results in mapping algorithm lock-in, meaning that no-one alone can experiment with or introduce new mapping algorithms and achieve consistent results regardless of which implementation path is taken.}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK4hjhhubeh}(h]'how-are-other-oses-solving-this-problemah ]h"](how are other oses solving this problem?ah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(hWhy is Linux different?h]hWhy is Linux different?}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj{hhhhhK9ubh)}(hX)Unlike other OSes, where there is one compositor for one or more drivers, on Linux we have a many-to-many relationship. Many compositors; many drivers. In addition each compositor vendor or community has their own view of how color management should be done. This is what makes Linux so beautiful.h]hX)Unlike other OSes, where there is one compositor for one or more drivers, on Linux we have a many-to-many relationship. Many compositors; many drivers. In addition each compositor vendor or community has their own view of how color management should be done. This is what makes Linux so beautiful.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK;hj{hhubh)}(hThis means that a HW vendor can now no longer tune their driver to one compositor, as tuning it to one could make it look fairly different from another compositor's color mapping.h]hThis means that a HW vendor can now no longer tune their driver to one compositor, as tuning it to one could make it look fairly different from another compositor’s color mapping.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK@hj{hhubh)}(hWe need a better solution.h]hWe need a better solution.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhj{hhubeh}(h]why-is-linux-differentah ]h"]why is linux different?ah$]h&]uh1hhhhhhhhK9ubh)}(hhh](h)}(hDescriptive APIh]hDescriptive API}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKHubh)}(hX&An API that describes the source and destination colorspaces is a descriptive API. It describes the input and output color spaces but does not describe how precisely they should be mapped. Such a mapping includes many minute design decision that can greatly affect the look of the final result.h]hX&An API that describes the source and destination colorspaces is a descriptive API. It describes the input and output color spaces but does not describe how precisely they should be mapped. Such a mapping includes many minute design decision that can greatly affect the look of the final result.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjhhubh)}(hIt is not feasible to describe such mapping with enough detail to ensure the same result from each implementation. In fact, these mappings are a very active research area.h]hIt is not feasible to describe such mapping with enough detail to ensure the same result from each implementation. In fact, these mappings are a very active research area.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKOhjhhubeh}(h]descriptive-apiah ]h"]descriptive apiah$]h&]uh1hhhhhhhhKHubh)}(hhh](h)}(hPrescriptive APIh]hPrescriptive API}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKUubh)}(hA prescriptive API describes not the source and destination colorspaces. It instead prescribes a recipe for how to manipulate pixel values to arrive at the desired outcome.h]hA prescriptive API describes not the source and destination colorspaces. It instead prescribes a recipe for how to manipulate pixel values to arrive at the desired outcome.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKWhjhhubh)}(hThis recipe is generally an ordered list of straight-forward operations, with clear mathematical definitions, such as 1D LUTs, 3D LUTs, matrices, or other operations that can be described in a precise manner.h]hThis recipe is generally an ordered list of straight-forward operations, with clear mathematical definitions, such as 1D LUTs, 3D LUTs, matrices, or other operations that can be described in a precise manner.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK[hjhhubeh}(h]prescriptive-apiah ]h"]prescriptive apiah$]h&]uh1hhhhhhhhKUubh)}(hhh](h)}(hThe Color Pipeline APIh]hThe Color Pipeline API}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj(hhhhhKaubh)}(hXHW color management pipelines can significantly differ between HW vendors in terms of availability, ordering, and capabilities of HW blocks. This makes a common definition of color management blocks and their ordering nigh impossible. Instead we are defining an API that allows user space to discover the HW capabilities in a generic manner, agnostic of specific drivers and hardware.h]hXHW color management pipelines can significantly differ between HW vendors in terms of availability, ordering, and capabilities of HW blocks. This makes a common definition of color management blocks and their ordering nigh impossible. Instead we are defining an API that allows user space to discover the HW capabilities in a generic manner, agnostic of specific drivers and hardware.}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKchj(hhubeh}(h]the-color-pipeline-apiah ]h"]the color pipeline apiah$]h&]uh1hhhhhhhhKaubh)}(hhh](h)}(hdrm_colorop Objecth]hdrm_colorop Object}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjOhhhhhKlubh)}(hX}To support the definition of color pipelines we define the DRM core object type drm_colorop. Individual drm_colorop objects will be chained via the NEXT property of a drm_colorop to constitute a color pipeline. Each drm_colorop object is unique, i.e., even if multiple color pipelines have the same operation they won't share the same drm_colorop object to describe that operation.h]hXTo support the definition of color pipelines we define the DRM core object type drm_colorop. Individual drm_colorop objects will be chained via the NEXT property of a drm_colorop to constitute a color pipeline. Each drm_colorop object is unique, i.e., even if multiple color pipelines have the same operation they won’t share the same drm_colorop object to describe that operation.}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKnhjOhhubh)}(hXNote that drivers are not expected to map drm_colorop objects statically to specific HW blocks. The mapping of drm_colorop objects is entirely a driver-internal detail and can be as dynamic or static as a driver needs it to be. See more in the Driver Implementation Guide section below.h]hXNote that drivers are not expected to map drm_colorop objects statically to specific HW blocks. The mapping of drm_colorop objects is entirely a driver-internal detail and can be as dynamic or static as a driver needs it to be. See more in the Driver Implementation Guide section below.}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKuhjOhhubh)}(h+Each drm_colorop has three core properties:h]h+Each drm_colorop has three core properties:}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhjOhhubh)}(hTYPE: An enumeration property, defining the type of transformation, such as * enumerated curve * custom (uniform) 1D LUT * 3x3 matrix * 3x4 matrix * 3D LUT * etc.h]hTYPE: An enumeration property, defining the type of transformation, such as * enumerated curve * custom (uniform) 1D LUT * 3x3 matrix * 3x4 matrix * 3D LUT * etc.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjOhhubh)}(hTDepending on the type of transformation other properties will describe more details.h]hTDepending on the type of transformation other properties will describe more details.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOhhubh)}(hBYPASS: A boolean property that can be used to easily put a block into bypass mode. The BYPASS property is not mandatory for a colorop, as long as the entire pipeline can get bypassed by setting the COLOR_PIPELINE on a plane to '0'.h]hBYPASS: A boolean property that can be used to easily put a block into bypass mode. The BYPASS property is not mandatory for a colorop, as long as the entire pipeline can get bypassed by setting the COLOR_PIPELINE on a plane to ‘0’.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOhhubh)}(hlNEXT: The ID of the next drm_colorop in a color pipeline, or 0 if this drm_colorop is the last in the chain.h]hlNEXT: The ID of the next drm_colorop in a color pipeline, or 0 if this drm_colorop is the last in the chain.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOhhubh)}(hAAn example of a drm_colorop object might look like one of these::h]h@An example of a drm_colorop object might look like one of these:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOhhubh literal_block)}(hX/* 1D enumerated curve */ Color operation 42 ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 1D enumerated curve ├─ "BYPASS": bool {true, false} ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, sRGB inverse EOTF, PQ EOTF, PQ inverse EOTF, …} └─ "NEXT": immutable color operation ID = 43 /* custom 4k entry 1D LUT */ Color operation 52 ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 1D LUT ├─ "BYPASS": bool {true, false} ├─ "SIZE": immutable range = 4096 ├─ "DATA": blob └─ "NEXT": immutable color operation ID = 0 /* 17^3 3D LUT */ Color operation 72 ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 3D LUT ├─ "BYPASS": bool {true, false} ├─ "SIZE": immutable range = 17 ├─ "DATA": blob └─ "NEXT": immutable color operation ID = 73h]hX/* 1D enumerated curve */ Color operation 42 ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 1D enumerated curve ├─ "BYPASS": bool {true, false} ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, sRGB inverse EOTF, PQ EOTF, PQ inverse EOTF, …} └─ "NEXT": immutable color operation ID = 43 /* custom 4k entry 1D LUT */ Color operation 52 ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 1D LUT ├─ "BYPASS": bool {true, false} ├─ "SIZE": immutable range = 4096 ├─ "DATA": blob └─ "NEXT": immutable color operation ID = 0 /* 17^3 3D LUT */ Color operation 72 ├─ "TYPE": immutable enum {1D enumerated curve, 1D LUT, 3x3 matrix, 3x4 matrix, 3D LUT, etc.} = 3D LUT ├─ "BYPASS": bool {true, false} ├─ "SIZE": immutable range = 17 ├─ "DATA": blob └─ "NEXT": immutable color operation ID = 73}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjOhhubh)}(hhh](h)}(hdrm_colorop extensibilityh]hdrm_colorop extensibility}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hUnlike existing DRM core objects, like &drm_plane, drm_colorop is not extensible. This simplifies implementations and keeps all functionality for managing &drm_colorop objects in the DRM core.h]hUnlike existing DRM core objects, like &drm_plane, drm_colorop is not extensible. This simplifies implementations and keeps all functionality for managing &drm_colorop objects in the DRM core.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hIf there is a need one may introduce a simple &drm_colorop_funcs function table in the future, for example to support an IN_FORMATS property on a &drm_colorop.h]hIf there is a need one may introduce a simple &drm_colorop_funcs function table in the future, for example to support an IN_FORMATS property on a &drm_colorop.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hIf a driver requires the ability to create a driver-specific colorop object they will need to add &drm_colorop func table support with support for the usual functions, like destroy, atomic_duplicate_state, and atomic_destroy_state.h]hIf a driver requires the ability to create a driver-specific colorop object they will need to add &drm_colorop func table support with support for the usual functions, like destroy, atomic_duplicate_state, and atomic_destroy_state.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]drm-colorop-extensibilityah ]h"]drm_colorop extensibilityah$]h&]uh1hhjOhhhhhKubeh}(h]drm-colorop-objectah ]h"]drm_colorop objectah$]h&]uh1hhhhhhhhKlubh)}(hhh](h)}(hCOLOR_PIPELINE Plane Propertyh]hCOLOR_PIPELINE Plane Property}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj+hhhhhKubh)}(hXColor Pipelines are created by a driver and advertised via a new COLOR_PIPELINE enum property on each plane. Values of the property always include object id 0, which is the default and means all color processing is disabled. Additional values will be the object IDs of the first drm_colorop in a pipeline. A driver can create and advertise none, one, or more possible color pipelines. A DRM client will select a color pipeline by setting the COLOR PIPELINE to the respective value.h]hXColor Pipelines are created by a driver and advertised via a new COLOR_PIPELINE enum property on each plane. Values of the property always include object id 0, which is the default and means all color processing is disabled. Additional values will be the object IDs of the first drm_colorop in a pipeline. A driver can create and advertise none, one, or more possible color pipelines. A DRM client will select a color pipeline by setting the COLOR PIPELINE to the respective value.}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubh)}(hXNOTE: Many DRM clients will set enumeration properties via the string value, often hard-coding it. Since this enumeration is generated based on the colorop object IDs it is important to perform the Color Pipeline Discovery, described below, instead of hard-coding color pipeline assignment. Drivers might generate the enum strings dynamically. Hard-coded strings might only work for specific drivers on a specific pieces of HW. Color Pipeline Discovery can work universally, as long as drivers implement the required color operations.h]hXNOTE: Many DRM clients will set enumeration properties via the string value, often hard-coding it. Since this enumeration is generated based on the colorop object IDs it is important to perform the Color Pipeline Discovery, described below, instead of hard-coding color pipeline assignment. Drivers might generate the enum strings dynamically. Hard-coded strings might only work for specific drivers on a specific pieces of HW. Color Pipeline Discovery can work universally, as long as drivers implement the required color operations.}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubh)}(hXThe COLOR_PIPELINE property is only exposed when the DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE is set. Drivers shall ignore any existing pre-blend color operations when this cap is set, such as COLOR_RANGE and COLOR_ENCODING. If drivers want to support COLOR_RANGE or COLOR_ENCODING functionality when the color pipeline client cap is set, they are expected to expose colorops in the pipeline to allow for the appropriate color transformation.h]hXThe COLOR_PIPELINE property is only exposed when the DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE is set. Drivers shall ignore any existing pre-blend color operations when this cap is set, such as COLOR_RANGE and COLOR_ENCODING. If drivers want to support COLOR_RANGE or COLOR_ENCODING functionality when the color pipeline client cap is set, they are expected to expose colorops in the pipeline to allow for the appropriate color transformation.}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubh)}(hSetting of the COLOR_PIPELINE plane property or drm_colorop properties is only allowed for userspace that sets this client cap.h]hSetting of the COLOR_PIPELINE plane property or drm_colorop properties is only allowed for userspace that sets this client cap.}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubh)}(hIAn example of a COLOR_PIPELINE property on a plane might look like this::h]hHAn example of a COLOR_PIPELINE property on a plane might look like this:}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubj)}(hPlane 10 ├─ "TYPE": immutable enum {Overlay, Primary, Cursor} = Primary ├─ … └─ "COLOR_PIPELINE": enum {0, 42, 52} = 0h]hPlane 10 ├─ "TYPE": immutable enum {Overlay, Primary, Cursor} = Primary ├─ … └─ "COLOR_PIPELINE": enum {0, 42, 52} = 0}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhj+hhubeh}(h]color-pipeline-plane-propertyah ]h"]color_pipeline plane propertyah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hColor Pipeline Discoveryh]hColor Pipeline Discovery}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(h:A DRM client wanting color management on a drm_plane will:h]h:A DRM client wanting color management on a drm_plane will:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubhenumerated_list)}(hhh](h list_item)}(h,Get the COLOR_PIPELINE property of the planeh]h)}(hjh]h,Get the COLOR_PIPELINE property of the plane}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h&iterate all COLOR_PIPELINE enum valuesh]h)}(hjh]h&iterate all COLOR_PIPELINE enum values}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hfor each enum value walk the color pipeline (via the NEXT pointers) and see if the available color operations are suitable for the desired color management operations h]h)}(hfor each enum value walk the color pipeline (via the NEXT pointers) and see if the available color operations are suitable for the desired color management operationsh]hfor each enum value walk the color pipeline (via the NEXT pointers) and see if the available color operations are suitable for the desired color management operations}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1jhjhhhhhKubh)}(hXIf userspace encounters an unknown or unsuitable color operation during discovery it does not need to reject the entire color pipeline outright, as long as the unknown or unsuitable colorop has a "BYPASS" property. Drivers will ensure that a bypassed block does not have any effect.h]hXIf userspace encounters an unknown or unsuitable color operation during discovery it does not need to reject the entire color pipeline outright, as long as the unknown or unsuitable colorop has a “BYPASS” property. Drivers will ensure that a bypassed block does not have any effect.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hdAn example of chained properties to define an AMD pre-blending color pipeline might look like this::h]hcAn example of chained properties to define an AMD pre-blending color pipeline might look like this:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hXPlane 10 ├─ "TYPE" (immutable) = Primary └─ "COLOR_PIPELINE": enum {0, 44} = 0 Color operation 44 ├─ "TYPE" (immutable) = 1D enumerated curve ├─ "BYPASS": bool ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, PQ EOTF} = sRGB EOTF └─ "NEXT" (immutable) = 45 Color operation 45 ├─ "TYPE" (immutable) = 3x4 Matrix ├─ "BYPASS": bool ├─ "DATA": blob └─ "NEXT" (immutable) = 46 Color operation 46 ├─ "TYPE" (immutable) = 1D enumerated curve ├─ "BYPASS": bool ├─ "CURVE_1D_TYPE": enum {sRGB Inverse EOTF, PQ Inverse EOTF} = sRGB EOTF └─ "NEXT" (immutable) = 47 Color operation 47 ├─ "TYPE" (immutable) = 1D LUT ├─ "SIZE": immutable range = 4096 ├─ "DATA": blob └─ "NEXT" (immutable) = 48 Color operation 48 ├─ "TYPE" (immutable) = 3D LUT ├─ "DATA": blob └─ "NEXT" (immutable) = 49 Color operation 49 ├─ "TYPE" (immutable) = 1D enumerated curve ├─ "BYPASS": bool ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, PQ EOTF} = sRGB EOTF └─ "NEXT" (immutable) = 0h]hXPlane 10 ├─ "TYPE" (immutable) = Primary └─ "COLOR_PIPELINE": enum {0, 44} = 0 Color operation 44 ├─ "TYPE" (immutable) = 1D enumerated curve ├─ "BYPASS": bool ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, PQ EOTF} = sRGB EOTF └─ "NEXT" (immutable) = 45 Color operation 45 ├─ "TYPE" (immutable) = 3x4 Matrix ├─ "BYPASS": bool ├─ "DATA": blob └─ "NEXT" (immutable) = 46 Color operation 46 ├─ "TYPE" (immutable) = 1D enumerated curve ├─ "BYPASS": bool ├─ "CURVE_1D_TYPE": enum {sRGB Inverse EOTF, PQ Inverse EOTF} = sRGB EOTF └─ "NEXT" (immutable) = 47 Color operation 47 ├─ "TYPE" (immutable) = 1D LUT ├─ "SIZE": immutable range = 4096 ├─ "DATA": blob └─ "NEXT" (immutable) = 48 Color operation 48 ├─ "TYPE" (immutable) = 3D LUT ├─ "DATA": blob └─ "NEXT" (immutable) = 49 Color operation 49 ├─ "TYPE" (immutable) = 1D enumerated curve ├─ "BYPASS": bool ├─ "CURVE_1D_TYPE": enum {sRGB EOTF, PQ EOTF} = sRGB EOTF └─ "NEXT" (immutable) = 0}hj+sbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubeh}(h]color-pipeline-discoveryah ]h"]color pipeline discoveryah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hColor Pipeline Programmingh]hColor Pipeline Programming}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjAhhhhhMubh)}(h8Once a DRM client has found a suitable pipeline it will:h]h8Once a DRM client has found a suitable pipeline it will:}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjAhhubj)}(hhh](j)}(hmSet the COLOR_PIPELINE enum value to the one pointing at the first drm_colorop object of the desired pipelineh]h)}(hmSet the COLOR_PIPELINE enum value to the one pointing at the first drm_colorop object of the desired pipelineh]hmSet the COLOR_PIPELINE enum value to the one pointing at the first drm_colorop object of the desired pipeline}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjcubah}(h]h ]h"]h$]h&]uh1jhj`hhhhhNubj)}(hSet the properties for all drm_colorop objects in the pipeline to the desired values, setting BYPASS to true for unused drm_colorop blocks, and false for enabled drm_colorop blocksh]h)}(hSet the properties for all drm_colorop objects in the pipeline to the desired values, setting BYPASS to true for unused drm_colorop blocks, and false for enabled drm_colorop blocksh]hSet the properties for all drm_colorop objects in the pipeline to the desired values, setting BYPASS to true for unused drm_colorop blocks, and false for enabled drm_colorop blocks}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM"hj{ubah}(h]h ]h"]h$]h&]uh1jhj`hhhhhNubj)}(h[Perform (TEST_ONLY or not) atomic commit with all the other KMS states it wishes to change h]h)}(hZPerform (TEST_ONLY or not) atomic commit with all the other KMS states it wishes to changeh]hZPerform (TEST_ONLY or not) atomic commit with all the other KMS states it wishes to change}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hjubah}(h]h ]h"]h$]h&]uh1jhj`hhhhhNubeh}(h]h ]h"]h$]h&]j j j hj juh1jhjAhhhhhM ubh)}(hTo configure the pipeline for an HDR10 PQ plane and blending in linear space, a compositor might perform an atomic commit with the following property values::h]hTo configure the pipeline for an HDR10 PQ plane and blending in linear space, a compositor might perform an atomic commit with the following property values:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM(hjAhhubj)}(hXPlane 10 └─ "COLOR_PIPELINE" = 42 Color operation 42 └─ "BYPASS" = true Color operation 44 └─ "BYPASS" = true Color operation 45 └─ "BYPASS" = true Color operation 46 └─ "BYPASS" = true Color operation 47 ├─ "DATA" = Gamut mapping + tone mapping + night mode └─ "BYPASS" = false Color operation 48 ├─ "CURVE_1D_TYPE" = PQ EOTF └─ "BYPASS" = falseh]hXPlane 10 └─ "COLOR_PIPELINE" = 42 Color operation 42 └─ "BYPASS" = true Color operation 44 └─ "BYPASS" = true Color operation 45 └─ "BYPASS" = true Color operation 46 └─ "BYPASS" = true Color operation 47 ├─ "DATA" = Gamut mapping + tone mapping + night mode └─ "BYPASS" = false Color operation 48 ├─ "CURVE_1D_TYPE" = PQ EOTF └─ "BYPASS" = false}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhM,hjAhhubeh}(h]color-pipeline-programmingah ]h"]color pipeline programmingah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(hDriver Implementer's Guideh]hDriver Implementer’s Guide}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMEubh)}(hWhat does this all mean for driver implementations? As noted above the colorops can map to HW directly but don't need to do so. Here are some suggestions on how to think about creating your color pipelines:h]hWhat does this all mean for driver implementations? As noted above the colorops can map to HW directly but don’t need to do so. Here are some suggestions on how to think about creating your color pipelines:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMGhjhhubh bullet_list)}(hhh](j)}(hTry to expose pipelines that use already defined colorops, even if your hardware pipeline is split differently. This allows existing userspace to immediately take advantage of the hardware. h]h)}(hTry to expose pipelines that use already defined colorops, even if your hardware pipeline is split differently. This allows existing userspace to immediately take advantage of the hardware.h]hTry to expose pipelines that use already defined colorops, even if your hardware pipeline is split differently. This allows existing userspace to immediately take advantage of the hardware.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hAdditionally, try to expose your actual hardware blocks as colorops. Define new colorop types where you believe it can offer significant benefits if userspace learns to program them. h]h)}(hAdditionally, try to expose your actual hardware blocks as colorops. Define new colorop types where you believe it can offer significant benefits if userspace learns to program them.h]hAdditionally, try to expose your actual hardware blocks as colorops. Define new colorop types where you believe it can offer significant benefits if userspace learns to program them.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMOhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXCAvoid defining new colorops for compound operations with very narrow scope. If you have a hardware block for a special operation that cannot be split further, you can expose that as a new colorop type. However, try to not define colorops for "use cases", especially if they require you to combine multiple hardware blocks. h]h)}(hXBAvoid defining new colorops for compound operations with very narrow scope. If you have a hardware block for a special operation that cannot be split further, you can expose that as a new colorop type. However, try to not define colorops for "use cases", especially if they require you to combine multiple hardware blocks.h]hXFAvoid defining new colorops for compound operations with very narrow scope. If you have a hardware block for a special operation that cannot be split further, you can expose that as a new colorop type. However, try to not define colorops for “use cases”, especially if they require you to combine multiple hardware blocks.}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMShj)ubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hxDesign new colorops as prescriptive, not descriptive; by the mathematical formula, not by the assumed input and output. h]h)}(hwDesign new colorops as prescriptive, not descriptive; by the mathematical formula, not by the assumed input and output.h]hwDesign new colorops as prescriptive, not descriptive; by the mathematical formula, not by the assumed input and output.}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMYhjAubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhMKhjhhubh)}(hXA defined colorop type must be deterministic. The exact behavior of the colorop must be documented entirely, whether via a mathematical formula or some other description. Its operation can depend only on its properties and input and nothing else, allowed error tolerance notwithstanding.h]hXA defined colorop type must be deterministic. The exact behavior of the colorop must be documented entirely, whether via a mathematical formula or some other description. Its operation can depend only on its properties and input and nothing else, allowed error tolerance notwithstanding.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM\hjhhubeh}(h]driver-implementer-s-guideah ]h"]driver implementer's guideah$]h&]uh1hhhhhhhhMEubh)}(hhh](h)}(h%Driver Forward/Backward Compatibilityh]h%Driver Forward/Backward Compatibility}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjwhhhhhMdubh)}(hXYAs this is uAPI drivers can't regress color pipelines that have been introduced for a given HW generation. New HW generations are free to abandon color pipelines advertised for previous generations. Nevertheless, it can be beneficial to carry support for existing color pipelines forward as those will likely already have support in DRM clients.h]hX[As this is uAPI drivers can’t regress color pipelines that have been introduced for a given HW generation. New HW generations are free to abandon color pipelines advertised for previous generations. Nevertheless, it can be beneficial to carry support for existing color pipelines forward as those will likely already have support in DRM clients.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMfhjwhhubh)}(hXIntroducing new colorops to a pipeline is fine, as long as they can be bypassed or are purely informational. DRM clients implementing support for the pipeline can always skip unknown properties as long as they can be confident that doing so will not cause unexpected results.h]hXIntroducing new colorops to a pipeline is fine, as long as they can be bypassed or are purely informational. DRM clients implementing support for the pipeline can always skip unknown properties as long as they can be confident that doing so will not cause unexpected results.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMmhjwhhubh)}(hIf a new colorop doesn't fall into one of the above categories (bypassable or informational) the modified pipeline would be unusable for user space. In this case a new pipeline should be defined.h]hIf a new colorop doesn’t fall into one of the above categories (bypassable or informational) the modified pipeline would be unusable for user space. In this case a new pipeline should be defined.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMrhjwhhubeh}(h]%driver-forward-backward-compatibilityah ]h"]%driver forward/backward compatibilityah$]h&]uh1hhhhhhhhMdubh)}(hhh](h)}(h Referencesh]h References}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMxubj)}(hhh]j)}(hhttps://lore.kernel.org/dri-devel/QMers3awXvNCQlyhWdTtsPwkp5ie9bze_hD5nAccFW7a_RXlWjYB7MoUW_8CKLT2bSQwIXVi5H6VULYIxCdgvryZoAoJnC5lZgyK1QWn488=@emersion.fr/h]h)}(hjh]h reference)}(hjh]hhttps://lore.kernel.org/dri-devel/QMers3awXvNCQlyhWdTtsPwkp5ie9bze_hD5nAccFW7a_RXlWjYB7MoUW_8CKLT2bSQwIXVi5H6VULYIxCdgvryZoAoJnC5lZgyK1QWn488=@emersion.fr/}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhMzhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubah}(h]h ]h"]h$]h&]j j j hj juh1jhjhhhhhMzubeh}(h] referencesah ]h"] referencesah$]h&]uh1hhhhhhhhMxubeh}(h]linux-color-pipeline-apiah ]h"]linux color pipeline apiah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj*error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjjjxjujjjjj%j"jLjIj(j%j jjjj>j;jjjtjqjjjju nametypes}(jjjxjjj%jLj(j jj>jjtjjuh}(jhjhjujjj{jjj"jjIj(j%jOjjjj+j;jjjAjqjjjwjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.