DRM/KMS color pipeline API
A proposal for exposing more of the color pipeline in DRM/KMS.
TODO: explain why we want this, what are the shortcomings of the current APIs
TODO: explain the level of abstraction: not the exact hardware blocks, generic hardware independent, but enough info and control so that user space can correctly offload color operations with a guarantee for precision
-
CRTC_COLOR_PIPELINE
prop describes generic pipeline information - elements in the pipeline are number from 0 to n
- elements with a higher number come later in the pipeline
- elements have a description prop
CRTC_COLOR_PIPELINE_ELEMENT_DESCR_0-N
- elements can have a state prop
CRTC_COLOR_PIPELINE_ELEMENT_STATE_0-N
- elements can have a data prop
CRTC_COLOR_PIPELINE_ELEMENT_DATA_0-N
CRTC_COLOR_PIPELINE
is a read-only blob containing a struct drm_color_pipeline
.
struct drm_color_pipeline {
TODO
};
CRTC_COLOR_PIPELINE_ELEMENT_DESCR_n
is a read-only blob containing a struct drm_color_pipeline_element
derived struct.
struct drm_color_pipeline_element {
__u32 type;
__u32 size;
/* might want to reserve a few bytes here if we want to extend this with generic data */
};
struct drm_color_pipeline_description {
struct drm_color_pipeline_element base;
__u32 color_format;
};
struct drm_color_pipeline_source {
struct drm_color_pipeline_element base;
__u8 supported_dither;
};
struct drm_color_pipeline_lut1d_config {
__u32 size;
/* offset from the struct to an array of __u64 points */
__u32 points_offset;
/* number of points in the array */
__u16 points_count;
__u64 fp_one_in;
__u64 fp_one_out;
__u64 min;
__u64 max;
/* __u64 *points = config + config->points_offset; */
/* next: config += config->size; */
};
struct drm_color_pipeline_lut1d {
struct drm_color_pipeline_element base;
/* followed by a number of struct drm_color_pipeline_lut1d_config */
/* struct drm_color_pipeline_lut1d_config *config = lut1d + lut1d->base.size; */
};
struct drm_color_pipeline_ctm {
struct drm_color_pipeline_element base;
__u64 min_in;
__u64 max_in;
__u64 min_out;
__u64 max_out;
__u8 bit depth;
__u8 matrix_size;
};
CRTC_COLOR_PIPELINE_ELEMENT_STATE_0-N
and CRTC_COLOR_PIPELINE_ELEMENT_DATA_0-N
are read/write blobs which contain struct drm_color_pipeline_element::type
specific data.
For example CRTC_COLOR_PIPELINE_ELEMENT_STATE_3
, if CRTC_COLOR_PIPELINE_ELEMENT_DESCR_3
is of type lut1d
.
struct drm_color_pipeline_lut1d_state {
__u8 passthrough;
/* index of the struct drm_color_pipeline_lut1d_config, if not in passthrough */
__u8 config;
};
How is this compatible with existing color pipeline properties (DAGAMMA, GAMMA, CTM)? It's not. One solution would be a DRM cap which then hides the old properties and only makes the new ones available. If a client modified the old properties the state and values of the new ones should reflect that.
There is two use cases for the color pipeline which require different guarantees from the kernel. The first one is playing a movie where you try to set up a pipeline once and then play the movie and at the end you set a new pipeline. This is fine with a mode set for setting the pipeline. The other is desktop use cases where the color pipeline required for offloading can change at any frame. Modesetting must not happen here. Currently we can test if a commit requires a mode set or not with a TEST_ONLY commit but technically going back to any other pipeline, maybe the default pipeline, might then require a modeset as well. User space need better guarantees here to properly use the API.
Is this concept of a pipeline sufficient to describe most hardware features or is a DAG required?
Related: