diff mbox series

[RFC,2/5] drm: Add Plane 3DLUT and 3DLUT mode properties

Message ID 20221004211451.1475215-3-alex.hung@amd.com (mailing list archive)
State New, archived
Headers show
Series Proposal for Pre-blending 3D LUT interfaces | expand

Commit Message

Alex Hung Oct. 4, 2022, 9:14 p.m. UTC
Add plane lut_3d mode and lut_3d as blob properties.

lut_3d mode is an enum property with values as blob_ids.
Userspace can get supported modes and also set one of the modes.

Note: A patchset "IGT tests for pre-blending 3D LUT interfaces" for this
proposal is sent to IGT mailing list.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 ++
 drivers/gpu/drm/drm_atomic_state_helper.c     |  3 ++
 drivers/gpu/drm/drm_atomic_uapi.c             | 11 ++++++
 drivers/gpu/drm/drm_color_mgmt.c              | 37 +++++++++++++++++++
 include/drm/drm_mode_object.h                 |  2 +-
 include/drm/drm_plane.h                       | 31 ++++++++++++++++
 6 files changed, 87 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f546c1326db3..ee277f357140 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8006,6 +8006,10 @@  static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 	drm_plane_attach_gamma_properties(plane);
 	drm_plane_attach_ctm_property(plane);
 
+	/* TODO need to check ASICs */
+	drm_plane_create_3d_lut_properties(plane->dev, plane, 1);
+	drm_plane_attach_3dlut_properties(plane);
+
 	/* Create (reset) the plane state */
 	if (plane->funcs->reset)
 		plane->funcs->reset(plane);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 7ddf6e4b956b..85900cd1bffe 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -318,6 +318,8 @@  void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 		drm_property_blob_get(state->ctm);
 	if (state->gamma_lut)
 		drm_property_blob_get(state->gamma_lut);
+	if (state->lut_3d)
+		drm_property_blob_get(state->lut_3d);
 
 	state->color_mgmt_changed = false;
 }
@@ -369,6 +371,7 @@  void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
 	drm_property_blob_put(state->degamma_lut);
 	drm_property_blob_put(state->ctm);
 	drm_property_blob_put(state->gamma_lut);
+	drm_property_blob_put(state->lut_3d);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index ba3e64cb184a..66e59e7c194d 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -622,6 +622,13 @@  static int drm_atomic_plane_set_property(struct drm_plane *plane,
 					&replaced);
 		state->color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == plane->lut_3d_property) {
+		ret = drm_atomic_replace_property_blob_from_id(dev,
+					&state->lut_3d, val, -1, 8, &replaced);
+		state->color_mgmt_changed |= replaced;
+		return 0;
+	} else if (property == plane->lut_3d_mode_property) {
+		state->lut_3d_mode = val;
 	} else if (property == config->prop_fb_damage_clips) {
 		ret = drm_atomic_replace_property_blob_from_id(dev,
 					&state->fb_damage_clips,
@@ -700,6 +707,10 @@  drm_atomic_plane_get_property(struct drm_plane *plane,
 	} else if (property == plane->gamma_lut_property) {
 		*val = (state->gamma_lut) ?
 			state->gamma_lut->base.id : 0;
+	} else if (property == plane->lut_3d_property) {
+		*val = (state->lut_3d) ? state->lut_3d->base.id : 0;
+	} else if (property == plane->lut_3d_mode_property) {
+		*val = state->lut_3d_mode;
 	} else if (property == config->prop_fb_damage_clips) {
 		*val = (state->fb_damage_clips) ?
 			state->fb_damage_clips->base.id : 0;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index b5b3ff7f654d..4bfe5b5c9670 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -706,6 +706,43 @@  void drm_plane_attach_gamma_properties(struct drm_plane *plane)
 }
 EXPORT_SYMBOL(drm_plane_attach_gamma_properties);
 
+int drm_plane_create_3d_lut_properties(struct drm_device *dev,
+					   struct drm_plane *plane,
+					   int num_values)
+{
+	struct drm_property *mode;
+	struct drm_property *blob;
+
+	mode = drm_property_create(dev, DRM_MODE_PROP_ENUM, "PLANE_3D_LUT_MODE", num_values);
+	if (!mode)
+		return -ENOMEM;
+
+	plane->lut_3d_mode_property = mode;
+
+	blob = drm_property_create(dev, DRM_MODE_PROP_BLOB, "PLANE_3D_LUT", 0);
+	if (!blob)
+		return -ENOMEM;
+
+	plane->lut_3d_property = blob;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_3d_lut_properties);
+
+void drm_plane_attach_3dlut_properties(struct drm_plane *plane)
+{
+	if (!plane->lut_3d_property)
+		return;
+
+	drm_object_attach_property(&plane->base, plane->lut_3d_property, 0);
+
+	if (!plane->lut_3d_mode_property)
+		return;
+
+	drm_object_attach_property(&plane->base, plane->lut_3d_mode_property, 0);
+}
+EXPORT_SYMBOL(drm_plane_attach_3dlut_properties);
+
 int drm_plane_color_add_gamma_degamma_mode_range(struct drm_plane *plane,
 						 const char *name,
 						 const struct drm_color_lut_range *ranges,
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index d4128c7daa08..c2b31dbf7325 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -60,7 +60,7 @@  struct drm_mode_object {
 	void (*free_cb)(struct kref *kref);
 };
 
-#define DRM_OBJECT_MAX_PROPERTY 26
+#define DRM_OBJECT_MAX_PROPERTY 28
 /**
  * struct drm_object_properties - property tracking for &drm_mode_object
  */
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 8989bb1aa46c..4e272144170f 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -275,6 +275,21 @@  struct drm_plane_state {
 	 */
 	struct drm_property_blob *gamma_lut;
 
+	/**
+	 * @lut_3d_mode:
+	 * This is a blob_id and exposes the platform capabilities wrt
+	 * various 3dlut. This also helps user select a 3dlut mode amongst
+	 * the supported ones.
+	 */
+	u32 lut_3d_mode;
+
+	/**
+	 * @lut_3d:
+	 * 3D lookup table blob. The blob data is laid out as defined by the
+	 * FOURCC value in color_format in the drm_mode_3dlut_mode struct.
+	 */
+	struct drm_property_blob *lut_3d;
+
 	u8 color_mgmt_changed : 1;
 };
 
@@ -818,6 +833,18 @@  struct drm_plane {
 	 * used to convert the framebuffer's colors to non-linear gamma.
 	 */
 	struct drm_property *gamma_lut_property;
+
+	/**
+	 * @lut_3d_mode_property: Optional Plane property to set the 3DLUT mode
+	 * used to convert the framebuffer's colors to non-linear gamma.
+	 */
+	struct drm_property *lut_3d_mode_property;
+
+	/**
+	 * @lut_3d_property: Optional Plane property to set the 3DLUT
+	 * used to convert the framebuffer's colors to non-linear gamma.
+	 */
+	struct drm_property *lut_3d_property;
 };
 
 #define obj_to_plane(x) container_of(x, struct drm_plane, base)
@@ -915,6 +942,10 @@  int drm_plane_create_color_mgmt_properties(struct drm_device *dev,
 void drm_plane_attach_degamma_properties(struct drm_plane *plane);
 void drm_plane_attach_ctm_property(struct drm_plane *plane);
 void drm_plane_attach_gamma_properties(struct drm_plane *plane);
+int drm_plane_create_3d_lut_properties(struct drm_device *dev,
+					   struct drm_plane *plane,
+					   int num_values);
+void drm_plane_attach_3dlut_properties(struct drm_plane *plane);
 int drm_plane_color_add_gamma_degamma_mode_range(struct drm_plane *plane,
 						 const char *name,
 						 const struct drm_color_lut_range *ranges,