Commit e5719e7f authored by Harry Wentland's avatar Harry Wentland Committed by Simon Ser
Browse files

drm/colorop: Add 3x4 CTM type



This type is used to support a 3x4 matrix in colorops. A 3x4
matrix uses the last column as a "bias" column. Some HW exposes
support for 3x4. The calculation looks like:

 out   matrix    in
 |R|   |0  1  2  3 |   | R |
 |G| = |4  5  6  7 | x | G |
 |B|   |8  9  10 11|   | B |
                       |1.0|

This is also the first colorop where we need a blob property to
program the property. For that we'll introduce a new DATA
property that can be used by all colorop TYPEs requiring a
blob. The way a DATA blob is read depends on the TYPE of
the colorop.

We only create the DATA property for property types that
need it.

Reviewed-by: default avatarSimon Ser <contact@emersion.fr>
Reviewed-by: default avatarLouis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: default avatarAlex Hung <alex.hung@amd.com>
Signed-off-by: default avatarHarry Wentland <harry.wentland@amd.com>
Reviewed-by: default avatarDaniel Stone <daniels@collabora.com>
Reviewed-by: default avatarMelissa Wen <mwen@igalia.com>
Reviewed-by: default avatarSebastian Wick <sebastian.wick@redhat.com>
Signed-off-by: default avatarSimon Ser <contact@emersion.fr>
Link: https://patch.msgid.link/20251115000237.3561250-19-alex.hung@amd.com
parent cb500b4c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -794,6 +794,9 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
		drm_printf(p, "\tcurve_1d_type=%s\n",
			   drm_get_colorop_curve_1d_type_name(state->curve_1d_type));
		break;
	case DRM_COLOROP_CTM_3X4:
		drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
		break;
	default:
		break;
	}
+31 −0
Original line number Diff line number Diff line
@@ -689,6 +689,32 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
	return 0;
}

static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
					      struct drm_colorop_state *state,
					      struct drm_property *property,
					      uint64_t val)
{
	ssize_t elem_size = -1;
	ssize_t size = -1;
	bool replaced = false;

	switch (colorop->type) {
	case DRM_COLOROP_CTM_3X4:
		size = sizeof(struct drm_color_ctm_3x4);
		break;
	default:
		/* should never get here */
		return -EINVAL;
	}

	return drm_property_replace_blob_from_id(colorop->dev,
						 &state->data,
						 val,
						 size,
						 elem_size,
						 &replaced);
}

static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
					   struct drm_colorop_state *state,
					   struct drm_file *file_priv,
@@ -699,6 +725,9 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
		state->bypass = val;
	} else if (property == colorop->curve_1d_type_property) {
		state->curve_1d_type = val;
	} else if (property == colorop->data_property) {
		return drm_atomic_color_set_data_property(colorop, state,
							  property, val);
	} else {
		drm_dbg_atomic(colorop->dev,
			       "[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
@@ -721,6 +750,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
		*val = state->bypass;
	else if (property == colorop->curve_1d_type_property)
		*val = state->curve_1d_type;
	else if (property == colorop->data_property)
		*val = (state->data) ? state->data->base.id : 0;
	else
		return -EINVAL;

+47 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@

static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = {
	{ DRM_COLOROP_1D_CURVE, "1D Curve" },
	{ DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
};

static const char * const colorop_curve_1d_type_names[] = {
@@ -147,6 +148,11 @@ void drm_colorop_cleanup(struct drm_colorop *colorop)
	list_del(&colorop->head);
	config->num_colorop--;

	if (colorop->state && colorop->state->data) {
		drm_property_blob_put(colorop->state->data);
		colorop->state->data = NULL;
	}

	kfree(colorop->state);
}
EXPORT_SYMBOL(drm_colorop_cleanup);
@@ -236,11 +242,51 @@ int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *
}
EXPORT_SYMBOL(drm_plane_colorop_curve_1d_init);

static int drm_colorop_create_data_prop(struct drm_device *dev, struct drm_colorop *colorop)
{
	struct drm_property *prop;

	/* data */
	prop = drm_property_create(dev, DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
				   "DATA", 0);
	if (!prop)
		return -ENOMEM;

	colorop->data_property = prop;
	drm_object_attach_property(&colorop->base,
				   colorop->data_property,
				   0);

	return 0;
}

int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop,
				   struct drm_plane *plane)
{
	int ret;

	ret = drm_plane_colorop_init(dev, colorop, plane, DRM_COLOROP_CTM_3X4);
	if (ret)
		return ret;

	ret = drm_colorop_create_data_prop(dev, colorop);
	if (ret)
		return ret;

	drm_colorop_reset(colorop);

	return 0;
}
EXPORT_SYMBOL(drm_plane_colorop_ctm_3x4_init);

static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop,
							struct drm_colorop_state *state)
{
	memcpy(state, colorop->state, sizeof(*state));

	if (state->data)
		drm_property_blob_get(state->data);

	state->bypass = true;
}

@@ -321,6 +367,7 @@ void drm_colorop_reset(struct drm_colorop *colorop)

static const char * const colorop_type_name[] = {
	[DRM_COLOROP_1D_CURVE] = "1D Curve",
	[DRM_COLOROP_CTM_3X4] = "3x4 Matrix",
};

const char *drm_get_colorop_type_name(enum drm_colorop_type type)
+24 −0
Original line number Diff line number Diff line
@@ -97,6 +97,17 @@ struct drm_colorop_state {
	 */
	enum drm_colorop_curve_1d_type curve_1d_type;

	/**
	 * @data:
	 *
	 * Data blob for any TYPE that requires such a blob. The
	 * interpretation of the blob is TYPE-specific.
	 *
	 * See the &drm_colorop_type documentation for how blob is laid
	 * out.
	 */
	struct drm_property_blob *data;

	/** @state: backpointer to global drm_atomic_state */
	struct drm_atomic_state *state;
};
@@ -206,6 +217,17 @@ struct drm_colorop {
	 */
	struct drm_property *curve_1d_type_property;

	/**
	 * @data_property:
	 *
	 * blob property for any TYPE that requires a blob of data,
	 * such as 1DLUT, CTM, 3DLUT, etc.
	 *
	 * The way this blob is interpreted depends on the TYPE of
	 * this
	 */
	struct drm_property *data_property;

	/**
	 * @next_property:
	 *
@@ -242,6 +264,8 @@ void drm_colorop_cleanup(struct drm_colorop *colorop);

int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop,
				    struct drm_plane *plane, u64 supported_tfs);
int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop,
				   struct drm_plane *plane);

struct drm_colorop_state *
drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
+0 −9
Original line number Diff line number Diff line
@@ -1656,15 +1656,6 @@ struct drm_amdgpu_info_uq_metadata {
#define AMDGPU_FAMILY_GC_11_5_0			150 /* GC 11.5.0 */
#define AMDGPU_FAMILY_GC_12_0_0			152 /* GC 12.0.0 */

/* FIXME wrong namespace! */
struct drm_color_ctm_3x4 {
	/*
	 * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude
	 * (not two's complement!) format.
	 */
	__u64 matrix[12];
};

#if defined(__cplusplus)
}
#endif
Loading