Advertise the supported values and add the conversion matrix of the
currently selected values to writeback jobs.

This does not have any effect yet as no YUV/YCbCr formats are advertised.

Signed-off-by: Robert Mader <robert.ma...@collabora.com>
---
 drivers/gpu/drm/vkms/vkms_drv.h       | 33 ++++++++---------
 drivers/gpu/drm/vkms/vkms_writeback.c | 51 +++++++++++++++++++++++++--
 2 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 8013c31efe3b..7fa58e17c286 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -81,10 +81,27 @@ struct line_buffer {
  */
 typedef void (*pixel_write_t)(u8 *out_pixel, const struct pixel_argb_u16 
*in_pixel);
 
+/**
+ * struct conversion_matrix - Matrix to use for a specific encoding and range
+ *
+ * @matrix: Conversion matrix from yuv to rgb. The matrix is stored in a 
row-major manner and is
+ * used to compute rgb values from yuv values:
+ *     [[r],[g],[b]] = @matrix * [[y],[u],[v]]
+ *   OR for yvu formats:
+ *     [[r],[g],[b]] = @matrix * [[y],[v],[u]]
+ *  The values of the matrix are signed fixed-point values with 32 bits 
fractional part.
+ * @y_offset: Offset to apply on the y value.
+ */
+struct conversion_matrix {
+       s64 matrix[3][3];
+       int y_offset;
+};
+
 struct vkms_writeback_job {
        struct iosys_map data[DRM_FORMAT_MAX_PLANES];
        struct vkms_frame_info wb_frame_info;
        pixel_write_t pixel_write;
+       struct conversion_matrix conversion_matrix;
 };
 
 /**
@@ -119,22 +136,6 @@ typedef void (*pixel_read_line_t)(const struct 
vkms_plane_state *plane, int x_st
                                  int y_start, enum pixel_read_direction 
direction, int count,
                                  struct pixel_argb_u16 out_pixel[]);
 
-/**
- * struct conversion_matrix - Matrix to use for a specific encoding and range
- *
- * @matrix: Conversion matrix from yuv to rgb. The matrix is stored in a 
row-major manner and is
- * used to compute rgb values from yuv values:
- *     [[r],[g],[b]] = @matrix * [[y],[u],[v]]
- *   OR for yvu formats:
- *     [[r],[g],[b]] = @matrix * [[y],[v],[u]]
- *  The values of the matrix are signed fixed-point values with 32 bits 
fractional part.
- * @y_offset: Offset to apply on the y value.
- */
-struct conversion_matrix {
-       s64 matrix[3][3];
-       int y_offset;
-};
-
 /**
  * struct vkms_plane_state - Driver specific plane state
  * @base: base plane state
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c 
b/drivers/gpu/drm/vkms/vkms_writeback.c
index 45d69a3b85f6..59e7a980533c 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -14,6 +14,9 @@
 #include "vkms_drv.h"
 #include "vkms_formats.h"
 
+#define DEFAULT_COLOR_ENCODING DRM_COLOR_YCBCR_BT601
+#define DEFAULT_COLOR_RANGE DRM_COLOR_YCBCR_LIMITED_RANGE
+
 static const u32 vkms_wb_formats[] = {
        DRM_FORMAT_ARGB8888,
        DRM_FORMAT_XRGB8888,
@@ -23,9 +26,17 @@ static const u32 vkms_wb_formats[] = {
        DRM_FORMAT_RGB565
 };
 
+static void vkms_wb_connector_reset(struct drm_connector *connector)
+{
+       drm_atomic_helper_connector_reset(connector);
+
+       connector->state->writeback_color_encoding = DEFAULT_COLOR_ENCODING;
+       connector->state->writeback_color_range = DEFAULT_COLOR_RANGE;
+}
+
 static const struct drm_connector_funcs vkms_wb_connector_funcs = {
        .fill_modes = drm_helper_probe_single_connector_modes,
-       .reset = drm_atomic_helper_connector_reset,
+       .reset = vkms_wb_connector_reset,
        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
@@ -60,6 +71,21 @@ static int vkms_wb_atomic_check(struct drm_connector 
*connector,
        if (ret < 0)
                return ret;
 
+       if (conn_state->writeback_color_encoding != DRM_COLOR_YCBCR_BT601 &&
+           conn_state->writeback_color_encoding != DRM_COLOR_YCBCR_BT709 &&
+           conn_state->writeback_color_encoding != DRM_COLOR_YCBCR_BT2020) {
+               DRM_DEBUG_KMS("Invalid color encoding %u\n",
+                             conn_state->writeback_color_encoding);
+               return -EINVAL;
+       }
+
+       if (conn_state->writeback_color_range != DRM_COLOR_YCBCR_LIMITED_RANGE 
&&
+           conn_state->writeback_color_range != DRM_COLOR_YCBCR_FULL_RANGE) {
+               DRM_DEBUG_KMS("Invalid color range %u\n",
+                             conn_state->writeback_color_range);
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -151,6 +177,10 @@ static void vkms_wb_atomic_commit(struct drm_connector 
*conn,
        spin_unlock_irq(&output->composer_lock);
        drm_writeback_queue_job(wb_conn, connector_state);
        active_wb->pixel_write = get_pixel_write_function(wb_format);
+       get_conversion_matrix_from_argb_u16(wb_format,
+                                           
conn_state->writeback_color_encoding,
+                                           conn_state->writeback_color_range,
+                                           &active_wb->conversion_matrix);
        drm_rect_init(&wb_frame_info->src, 0, 0, crtc_width, crtc_height);
        drm_rect_init(&wb_frame_info->dst, 0, 0, crtc_width, crtc_height);
 }
@@ -179,9 +209,26 @@ int vkms_enable_writeback_connector(struct vkms_device 
*vkmsdev,
 
        drm_connector_helper_add(&wb->base, &vkms_wb_conn_helper_funcs);
 
-       return drmm_writeback_connector_init(&vkmsdev->drm, wb,
+       ret = drmm_writeback_connector_init(&vkmsdev->drm, wb,
                                             &vkms_wb_connector_funcs,
                                             &vkms_output->wb_encoder,
                                             vkms_wb_formats,
                                             ARRAY_SIZE(vkms_wb_formats));
+       if (ret)
+               return ret;
+
+       ret = drm_writeback_create_color_properties(wb,
+                                                   BIT(DRM_COLOR_YCBCR_BT601) |
+                                                   BIT(DRM_COLOR_YCBCR_BT709) |
+                                                   BIT(DRM_COLOR_YCBCR_BT2020),
+                                                   
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+                                                   
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+                                                   DEFAULT_COLOR_ENCODING,
+                                                   DEFAULT_COLOR_RANGE);
+       if (ret) {
+               DRM_ERROR("adding color properties failed: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
 }
-- 
2.50.1

Reply via email to