From: "NĂcolas F. R. A. Prado" <[email protected]> Introduce a post-blend color pipeline with the same colorop blocks as the pre-blend color pipeline.
Signed-off-by: NĂcolas F. R. A. Prado <[email protected]> Co-developed-by: Ariel D'Alessandro <[email protected]> Signed-off-by: Ariel D'Alessandro <[email protected]> --- drivers/gpu/drm/vkms/tests/vkms_config_test.c | 70 ++++++++++------- drivers/gpu/drm/vkms/vkms_colorop.c | 103 ++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_composer.c | 5 +- drivers/gpu/drm/vkms/vkms_config.c | 5 +- drivers/gpu/drm/vkms/vkms_config.h | 29 +++++++- drivers/gpu/drm/vkms/vkms_crtc.c | 6 +- drivers/gpu/drm/vkms/vkms_drv.c | 7 +- drivers/gpu/drm/vkms/vkms_drv.h | 6 +- drivers/gpu/drm/vkms/vkms_output.c | 3 +- 9 files changed, 202 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c index 1e4ea1863420f..ec1d84ae508ad 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c @@ -84,6 +84,7 @@ struct default_config_case { bool enable_writeback; bool enable_overlay; bool enable_plane_pipeline; + bool enable_crtc_pipeline; }; static void vkms_config_test_empty_config(struct kunit *test) @@ -109,22 +110,38 @@ static void vkms_config_test_empty_config(struct kunit *test) } static struct default_config_case default_config_cases[] = { - { false, false, false, false }, - { true, false, false, false }, - { true, true, false, false }, - { true, false, true, false }, - { false, true, false, false }, - { false, true, true, false }, - { false, false, true, false }, - { true, true, true, false }, - { false, false, false, true }, - { true, false, false, true }, - { true, true, false, true }, - { true, false, true, true }, - { false, true, false, true }, - { false, true, true, true }, - { false, false, true, true }, - { true, true, true, true }, + { false, false, false, false, false }, + { true, false, false, false, false }, + { true, true, false, false, false }, + { true, false, true, false, false }, + { false, true, false, false, false }, + { false, true, true, false, false }, + { false, false, true, false, false }, + { true, true, true, false, false }, + { false, false, false, true, false }, + { true, false, false, true, false }, + { true, true, false, true, false }, + { true, false, true, true, false }, + { false, true, false, true, false }, + { false, true, true, true, false }, + { false, false, true, true, false }, + { true, true, true, true, false }, + { false, false, false, false, true }, + { true, false, false, false, true }, + { true, true, false, false, true }, + { true, false, true, false, true }, + { false, true, false, false, true }, + { false, true, true, false, true }, + { false, false, true, false, true }, + { true, true, true, false, true }, + { false, false, false, true, true }, + { true, false, false, true, true }, + { true, true, false, true, true }, + { true, false, true, true, true }, + { false, true, false, true, true }, + { false, true, true, true, true }, + { false, false, true, true, true }, + { true, true, true, true, true }, }; KUNIT_ARRAY_PARAM(default_config, default_config_cases, NULL); @@ -142,7 +159,8 @@ static void vkms_config_test_default_config(struct kunit *test) config = vkms_config_default_create(params->enable_cursor, params->enable_writeback, params->enable_overlay, - params->enable_plane_pipeline); + params->enable_plane_pipeline, + params->enable_crtc_pipeline); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); /* Planes */ @@ -174,6 +192,8 @@ static void vkms_config_test_default_config(struct kunit *test) crtc_cfg = get_first_crtc(config); KUNIT_EXPECT_EQ(test, vkms_config_crtc_get_writeback(crtc_cfg), params->enable_writeback); + KUNIT_EXPECT_EQ(test, vkms_config_crtc_get_default_pipeline(crtc_cfg), + params->enable_crtc_pipeline); vkms_config_for_each_plane(config, plane_cfg) { struct vkms_config_crtc *possible_crtc; @@ -381,7 +401,7 @@ static void vkms_config_test_invalid_plane_number(struct kunit *test) struct vkms_config_plane *plane_cfg; int n; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); /* Invalid: No planes */ @@ -406,7 +426,7 @@ static void vkms_config_test_valid_plane_type(struct kunit *test) struct vkms_config_encoder *encoder_cfg; int err; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); plane_cfg = get_first_plane(config); @@ -487,7 +507,7 @@ static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test) struct vkms_config_plane *plane_cfg; struct vkms_config_crtc *crtc_cfg; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); plane_cfg = get_first_plane(config); @@ -506,7 +526,7 @@ static void vkms_config_test_invalid_crtc_number(struct kunit *test) struct vkms_config_crtc *crtc_cfg; int n; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); /* Invalid: No CRTCs */ @@ -529,7 +549,7 @@ static void vkms_config_test_invalid_encoder_number(struct kunit *test) struct vkms_config_encoder *encoder_cfg; int n; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); /* Invalid: No encoders */ @@ -554,7 +574,7 @@ static void vkms_config_test_valid_encoder_possible_crtcs(struct kunit *test) struct vkms_config_encoder *encoder_cfg; int err; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); crtc_cfg1 = get_first_crtc(config); @@ -600,7 +620,7 @@ static void vkms_config_test_invalid_connector_number(struct kunit *test) struct vkms_config_connector *connector_cfg; int n; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); /* Invalid: No connectors */ @@ -623,7 +643,7 @@ static void vkms_config_test_valid_connector_possible_encoders(struct kunit *tes struct vkms_config_encoder *encoder_cfg; struct vkms_config_connector *connector_cfg; - config = vkms_config_default_create(false, false, false, false); + config = vkms_config_default_create(false, false, false, false, false); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); encoder_cfg = get_first_encoder(config); diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c b/drivers/gpu/drm/vkms/vkms_colorop.c index dd6120434690e..6c4a6cb186564 100644 --- a/drivers/gpu/drm/vkms/vkms_colorop.c +++ b/drivers/gpu/drm/vkms/vkms_colorop.c @@ -102,6 +102,91 @@ static int vkms_initialize_plane_color_pipeline(struct drm_plane *plane, return ret; } +static int vkms_initialize_crtc_color_pipeline(struct drm_crtc *crtc, + struct drm_prop_enum_list *list) +{ + struct drm_colorop *ops[MAX_COLOR_PIPELINE_OPS]; + struct drm_device *dev = crtc->dev; + int ret; + int i = 0, j = 0; + + memset(ops, 0, sizeof(ops)); + + /* 1st op: 1d curve */ + ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + if (!ops[i]) { + ret = -ENOMEM; + goto cleanup; + } + + ret = drm_crtc_colorop_curve_1d_init(dev, ops[i], crtc, supported_tfs, + DRM_COLOROP_FLAG_ALLOW_BYPASS); + if (ret) + goto err_colorop_init; + + list->type = ops[i]->base.id; + list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", ops[i]->base.id); + + i++; + + /* 2nd op: 3x4 matrix */ + ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + if (!ops[i]) { + ret = -ENOMEM; + goto cleanup; + } + + ret = drm_crtc_colorop_ctm_3x4_init(dev, ops[i], crtc, DRM_COLOROP_FLAG_ALLOW_BYPASS); + if (ret) + goto err_colorop_init; + + drm_colorop_set_next_property(ops[i - 1], ops[i]); + + i++; + + /* 3rd op: 3x4 matrix */ + ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + if (!ops[i]) { + ret = -ENOMEM; + goto cleanup; + } + + ret = drm_crtc_colorop_ctm_3x4_init(dev, ops[i], crtc, DRM_COLOROP_FLAG_ALLOW_BYPASS); + if (ret) + goto err_colorop_init; + + drm_colorop_set_next_property(ops[i - 1], ops[i]); + + i++; + + /* 4th op: 1d curve */ + ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + if (!ops[i]) { + ret = -ENOMEM; + goto cleanup; + } + + ret = drm_crtc_colorop_curve_1d_init(dev, ops[i], crtc, supported_tfs, + DRM_COLOROP_FLAG_ALLOW_BYPASS); + if (ret) + goto err_colorop_init; + + drm_colorop_set_next_property(ops[i - 1], ops[i]); + + return 0; + +err_colorop_init: + kfree(ops[i]); + +cleanup: + for (j = 0; j < i; j++) { + drm_colorop_cleanup(ops[j]); + kfree(ops[j]); + } + + return ret; +} + int vkms_initialize_plane_colorops(struct drm_plane *plane) { struct drm_prop_enum_list pipeline; @@ -119,3 +204,21 @@ int vkms_initialize_plane_colorops(struct drm_plane *plane) return 0; } + +int vkms_initialize_crtc_colorops(struct drm_crtc *crtc) +{ + struct drm_prop_enum_list pipeline; + int ret; + + /* Add color pipeline */ + ret = vkms_initialize_crtc_color_pipeline(crtc, &pipeline); + if (ret) + return ret; + + /* Create COLOR_PIPELINE property and attach */ + ret = drm_crtc_create_color_pipeline_property(crtc, &pipeline, 1); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index d4f87a2aa3359..621f008b165a6 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -495,7 +495,10 @@ static void blend(struct vkms_writeback_job *wb, blend_line(plane[i], y, crtc_x_limit, stage_buffer, output_buffer); } - apply_lut(crtc_state, output_buffer); + if (crtc_state->base.color_pipeline_enabled) + color_transform(crtc_state->base.color_pipeline, output_buffer); + else + apply_lut(crtc_state, output_buffer); *crc32 = crc32_le(*crc32, (void *)output_buffer->pixels, row_size); diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 8788df9edb7ca..a65c3638eff4d 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -34,7 +34,8 @@ EXPORT_SYMBOL_IF_KUNIT(vkms_config_create); struct vkms_config *vkms_config_default_create(bool enable_cursor, bool enable_writeback, bool enable_overlay, - bool enable_plane_pipeline) + bool enable_plane_pipeline, + bool enable_crtc_pipeline) { struct vkms_config *config; struct vkms_config_plane *plane_cfg; @@ -56,6 +57,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor, if (IS_ERR(crtc_cfg)) goto err_alloc; vkms_config_crtc_set_writeback(crtc_cfg, enable_writeback); + vkms_config_crtc_set_default_pipeline(crtc_cfg, enable_crtc_pipeline); if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg)) goto err_alloc; @@ -454,6 +456,7 @@ struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *config) crtc_cfg->config = config; vkms_config_crtc_set_writeback(crtc_cfg, false); + vkms_config_crtc_set_default_pipeline(crtc_cfg, false); list_add_tail(&crtc_cfg->link, &config->crtcs); diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h index 8f7f286a4bdd7..e12e4065f01f0 100644 --- a/drivers/gpu/drm/vkms/vkms_config.h +++ b/drivers/gpu/drm/vkms/vkms_config.h @@ -61,6 +61,7 @@ struct vkms_config_plane { * @link: Link to the others CRTCs in vkms_config * @config: The vkms_config this CRTC belongs to * @writeback: If true, a writeback buffer can be attached to the CRTC + * @default_pipeline: If true, CRTC will be created with the default pipeline. * @crtc: Internal usage. This pointer should never be considered as valid. * It can be used to store a temporary reference to a VKMS CRTC during * device creation. This pointer is not managed by the configuration and @@ -71,6 +72,7 @@ struct vkms_config_crtc { struct vkms_config *config; bool writeback; + bool default_pipeline; /* Internal usage */ struct vkms_output *crtc; @@ -205,7 +207,8 @@ struct vkms_config *vkms_config_create(const char *dev_name); struct vkms_config *vkms_config_default_create(bool enable_cursor, bool enable_writeback, bool enable_overlay, - bool enable_plane_pipeline); + bool enable_plane_pipeline, + bool enable_crtc_pipeline); /** * vkms_config_destroy() - Free a VKMS configuration @@ -314,6 +317,30 @@ vkms_config_plane_set_default_pipeline(struct vkms_config_plane *plane_cfg, plane_cfg->default_pipeline = default_pipeline; } +/** + * vkms_config_crtc_get_default_pipeline() - Return if the CRTC will + * be created with the default pipeline + * @crtc_cfg: CRTC to get the information from + */ +static inline bool +vkms_config_crtc_get_default_pipeline(struct vkms_config_crtc *crtc_cfg) +{ + return crtc_cfg->default_pipeline; +} + +/** + * vkms_config_crtc_set_default_pipeline() - Set if the CRTC will + * be created with the default pipeline + * @crtc_cfg: CRTC to configure the pipeline + * @default_pipeline: New default pipeline value + */ +static inline void +vkms_config_crtc_set_default_pipeline(struct vkms_config_crtc *crtc_cfg, + bool default_pipeline) +{ + crtc_cfg->default_pipeline = default_pipeline; +} + /** * vkms_config_plane_attach_crtc - Attach a plane to a CRTC * @plane_cfg: Plane to attach diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 9a7db1d510222..60c372c0ce2d8 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -10,6 +10,7 @@ #include <drm/drm_vblank.h> #include <drm/drm_vblank_helper.h> +#include "vkms_config.h" #include "vkms_drv.h" static bool vkms_crtc_handle_vblank_timeout(struct drm_crtc *crtc) @@ -202,7 +203,7 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = { }; struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary, - struct drm_plane *cursor) + struct drm_plane *cursor, struct vkms_config_crtc *crtc_cfg) { struct vkms_output *vkms_out; struct drm_crtc *crtc; @@ -228,6 +229,9 @@ struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *pri drm_crtc_enable_color_mgmt(crtc, 0, false, VKMS_LUT_SIZE); + if (vkms_config_crtc_get_default_pipeline(crtc_cfg)) + vkms_initialize_crtc_colorops(crtc); + spin_lock_init(&vkms_out->lock); spin_lock_init(&vkms_out->composer_lock); diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index dd1402f437736..39195540fe2b1 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -55,6 +55,10 @@ static bool enable_plane_pipeline; module_param_named(enable_plane_pipeline, enable_plane_pipeline, bool, 0444); MODULE_PARM_DESC(enable_plane_pipeline, "Enable/Disable plane pipeline support"); +static bool enable_crtc_pipeline; +module_param_named(enable_crtc_pipeline, enable_crtc_pipeline, bool, 0444); +MODULE_PARM_DESC(enable_crtc_pipeline, "Enable/Disable CRTC pipeline support"); + static bool create_default_dev = true; module_param_named(create_default_dev, create_default_dev, bool, 0444); MODULE_PARM_DESC(create_default_dev, "Create or not the default VKMS device"); @@ -232,7 +236,8 @@ static int __init vkms_init(void) return 0; config = vkms_config_default_create(enable_cursor, enable_writeback, - enable_overlay, enable_plane_pipeline); + enable_overlay, enable_plane_pipeline, + enable_crtc_pipeline); if (IS_ERR(config)) return PTR_ERR(config); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index bdeb52623f4d6..1688c885f2285 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -229,6 +229,7 @@ struct vkms_output { }; struct vkms_config; +struct vkms_config_crtc; struct vkms_config_plane; /** @@ -287,10 +288,12 @@ void vkms_destroy(struct vkms_config *config); * @crtc: uninitialized CRTC device * @primary: primary plane to attach to the CRTC * @cursor: plane to attach to the CRTC + * @crtc_cfg: CRTC configuration */ struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary, - struct drm_plane *cursor); + struct drm_plane *cursor, + struct vkms_config_crtc *crtc_cfg); /** * vkms_output_init() - Initialize all sub-components needed for a VKMS device. @@ -325,5 +328,6 @@ int vkms_enable_writeback_connector(struct vkms_device *vkmsdev, struct vkms_out /* Colorops */ int vkms_initialize_plane_colorops(struct drm_plane *plane); +int vkms_initialize_crtc_colorops(struct drm_crtc *crtc); #endif /* _VKMS_DRV_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 86ce07a617f52..a0856ba90ac24 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -34,7 +34,8 @@ int vkms_output_init(struct vkms_device *vkmsdev) cursor = vkms_config_crtc_cursor_plane(vkmsdev->config, crtc_cfg); crtc_cfg->crtc = vkms_crtc_init(dev, &primary->plane->base, - cursor ? &cursor->plane->base : NULL); + cursor ? &cursor->plane->base : NULL, + crtc_cfg); if (IS_ERR(crtc_cfg->crtc)) { DRM_ERROR("Failed to allocate CRTC\n"); return PTR_ERR(crtc_cfg->crtc); -- 2.51.0
