All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH xf86-video-intel 1/2] sna: Refactor property parsing
@ 2019-02-18 19:50 Ville Syrjala
  2019-02-18 19:50 ` [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property Ville Syrjala
  2019-04-26 16:32 ` [PATCH xf86-video-intel v2 1/2] sna: Refactor property parsing Ville Syrjala
  0 siblings, 2 replies; 11+ messages in thread
From: Ville Syrjala @ 2019-02-18 19:50 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Generalize the code that parses the plane properties to be useable
for crtc (or any kms object) properties as well.

Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 src/sna/sna_display.c | 67 +++++++++++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index fe67f85b62f1..916cc3c04e07 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -215,6 +215,7 @@ struct sna_crtc {
 	uint32_t rotation;
 	struct plane {
 		uint32_t id;
+		uint32_t type;
 		struct {
 			uint32_t prop;
 			uint32_t supported;
@@ -3391,33 +3392,40 @@ void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,
 				 p->color_encoding.values[colorspace]);
 }
 
-static int plane_details(struct sna *sna, struct plane *p)
+typedef void (*parse_prop_func)(struct sna *sna,
+				struct drm_mode_get_property *prop,
+				uint64_t value,
+				void *data);
+static void parse_props(struct sna *sna,
+		       uint32_t obj_type, uint32_t obj_id,
+		       parse_prop_func parse_prop,
+		       void *data)
 {
 #define N_STACK_PROPS 32 /* must be a multiple of 2 */
 	struct local_mode_obj_get_properties arg;
 	uint64_t stack[N_STACK_PROPS + N_STACK_PROPS/2];
 	uint64_t *values = stack;
 	uint32_t *props = (uint32_t *)(values + N_STACK_PROPS);
-	int i, type = DRM_PLANE_TYPE_OVERLAY;
+	int i;
 
 	memset(&arg, 0, sizeof(struct local_mode_obj_get_properties));
-	arg.obj_id = p->id;
-	arg.obj_type = LOCAL_MODE_OBJECT_PLANE;
+	arg.obj_id = obj_id;
+	arg.obj_type = obj_type;
 
 	arg.props_ptr = (uintptr_t)props;
 	arg.prop_values_ptr = (uintptr_t)values;
 	arg.count_props = N_STACK_PROPS;
 
 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
-		return -1;
+		return;
 
 	DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__,
-	     p->id, LOCAL_MODE_OBJECT_PLANE, arg.count_props));
+	     obj_id, obj_type, arg.count_props));
 
 	if (arg.count_props > N_STACK_PROPS) {
 		values = malloc(2*sizeof(uint64_t)*arg.count_props);
 		if (values == NULL)
-			return -1;
+			return;
 
 		props = (uint32_t *)(values + arg.count_props);
 
@@ -3444,25 +3452,46 @@ static int plane_details(struct sna *sna, struct plane *p)
 		DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
 		     (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i]));
 
-		if (strcmp(prop.name, "type") == 0) {
-			type = values[i];
-		} else if (prop_is_rotation(&prop)) {
-			parse_rotation_prop(sna, p, &prop, values[i]);
-		} else if (prop_is_color_encoding(&prop)) {
-			parse_color_encoding_prop(sna, p, &prop, values[i]);
-		}
+		parse_prop(sna, &prop, values[i], data);
 	}
 
+	if (values != stack)
+		free(values);
+
+#undef N_STACK_PROPS
+}
+
+static bool prop_is_type(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 1, "type");
+}
+
+static void plane_parse_prop(struct sna *sna,
+			     struct drm_mode_get_property *prop,
+			     uint64_t value, void *data)
+{
+	struct plane *p = data;
+
+	if (prop_is_type(prop))
+		p->type = value;
+	else if (prop_is_rotation(prop))
+		parse_rotation_prop(sna, p, prop, value);
+	else if (prop_is_color_encoding(prop))
+		parse_color_encoding_prop(sna, p, prop, value);
+}
+
+static int plane_details(struct sna *sna, struct plane *p)
+{
+	parse_props(sna, LOCAL_MODE_OBJECT_PLANE, p->id,
+		    plane_parse_prop, p);
+
 	p->rotation.supported &= DBG_NATIVE_ROTATION;
 	if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE))
 		p->rotation.supported = RR_Rotate_0;
 
-	if (values != stack)
-		free(values);
+	DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, p->type));
 
-	DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, type));
-	return type;
-#undef N_STACK_PROPS
+	return p->type;
 }
 
 static void add_sprite_plane(struct sna_crtc *crtc,
-- 
2.19.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-02-18 19:50 [PATCH xf86-video-intel 1/2] sna: Refactor property parsing Ville Syrjala
@ 2019-02-18 19:50 ` Ville Syrjala
  2019-03-01 13:13   ` Chris Wilson
                     ` (2 more replies)
  2019-04-26 16:32 ` [PATCH xf86-video-intel v2 1/2] sna: Refactor property parsing Ville Syrjala
  1 sibling, 3 replies; 11+ messages in thread
From: Ville Syrjala @ 2019-02-18 19:50 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Probe the GAMMA_LUT/GAMMA_LUT_SIZE props and utilize them when
the running with > 8bpc.

Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 src/sna/sna_display.c | 247 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 208 insertions(+), 39 deletions(-)

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 916cc3c04e07..2f82e1fa3d86 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -127,6 +127,7 @@ struct local_mode_obj_get_properties {
 	uint32_t obj_type;
 	uint32_t pad;
 };
+#define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
 #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
 
 struct local_mode_set_plane {
@@ -229,6 +230,11 @@ struct sna_crtc {
 	} primary;
 	struct list sprites;
 
+	struct drm_color_lut *gamma_lut;
+	uint64_t gamma_lut_prop;
+	uint64_t gamma_lut_blob;
+	uint32_t gamma_lut_size;
+
 	uint32_t mode_serial, flip_serial;
 
 	uint32_t last_seq, wrap_seq;
@@ -317,6 +323,9 @@ static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
 static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
 static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
 			  struct kgem_bo *bo, int x, int y);
+static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
+			       CARD16 *red, CARD16 *green,
+			       CARD16 *blue, int size);
 
 static bool is_zaphod(ScrnInfoPtr scrn)
 {
@@ -3150,11 +3159,9 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	       mode->VDisplay <= sna->mode.max_crtc_height);
 
 #if HAS_GAMMA
-	drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc),
-			    crtc->gamma_size,
-			    crtc->gamma_red,
-			    crtc->gamma_green,
-			    crtc->gamma_blue);
+	sna_crtc_gamma_set(crtc,
+			   crtc->gamma_red, crtc->gamma_green,
+			   crtc->gamma_blue, crtc->gamma_size);
 #endif
 
 	saved_kmode = sna_crtc->kmode;
@@ -3212,12 +3219,44 @@ void sna_mode_adjust_frame(struct sna *sna, int x, int y)
 
 static void
 sna_crtc_gamma_set(xf86CrtcPtr crtc,
-		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
 {
-	assert(to_sna_crtc(crtc));
-	drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
-			    sna_crtc_id(crtc),
-			    size, red, green, blue);
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_color_lut *lut = sna_crtc->gamma_lut;
+	uint32_t blob_size = size * sizeof(lut[0]);
+	uint32_t blob_id;
+	int ret, i;
+
+	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
+
+	if (!lut) {
+		assert(size == 256);
+
+		drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
+				    sna_crtc_id(crtc),
+				    size, red, green, blue);
+		return;
+	}
+
+	assert(size == sna_crtc->gamma_lut_size);
+
+	for (i = 0; i < size; i++) {
+		lut[i].red = red[i];
+		lut[i].green = green[i];
+		lut[i].blue = blue[i];
+	}
+
+	ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
+	if (ret)
+		return;
+
+	ret = drmModeObjectSetProperty(sna->kgem.fd,
+				       sna_crtc->id, DRM_MODE_OBJECT_CRTC,
+				       sna_crtc->gamma_lut_prop,
+				       blob_id);
+
+	drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
 }
 
 static void
@@ -3229,6 +3268,8 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
 	if (sna_crtc == NULL)
 		return;
 
+	free(sna_crtc->gamma_lut);
+
 	list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
 		free(sprite);
 
@@ -3663,6 +3704,55 @@ bool sna_has_sprite_format(struct sna *sna, uint32_t format)
 	return false;
 }
 
+inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
+}
+
+inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
+}
+
+static void sna_crtc_parse_prop(struct sna *sna,
+				struct drm_mode_get_property *prop,
+				uint64_t value, void *data)
+{
+	struct sna_crtc *crtc = data;
+
+	if (prop_is_gamma_lut(prop)) {
+		crtc->gamma_lut_prop = prop->prop_id;
+		crtc->gamma_lut_blob = value;
+	} else if (prop_is_gamma_lut_size(prop)) {
+		crtc->gamma_lut_size = value;
+	}
+}
+
+static void
+sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+
+	parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
+		    sna_crtc_parse_prop, crtc);
+
+	/* use high precision gamma LUT for > 8bpc */
+	/* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
+	if (scrn->rgbBits <= 8 ||
+	    XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
+		crtc->gamma_lut_size = 0;
+
+	if (crtc->gamma_lut_size) {
+		crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
+					 sizeof(crtc->gamma_lut[0]));
+		if (!crtc->gamma_lut)
+			crtc->gamma_lut_size = 0;
+	}
+
+	DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
+	     sna_crtc_id(crtc), crtc->gamma_lut_size));
+}
+
 static void
 sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
 {
@@ -3723,6 +3813,9 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
 
 	list_init(&sna_crtc->sprites);
 	sna_crtc_init__rotation(sna, sna_crtc);
+
+	sna_crtc_init__props(sna, sna_crtc);
+
 	sna_crtc_find_planes(sna, sna_crtc);
 
 	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
@@ -7282,36 +7375,110 @@ static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
 			  mon->mon_gamma_blue);
 }
 
+static bool
+crtc_get_gamma_lut(xf86CrtcPtr crtc,
+		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+{
+
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_color_lut *lut = sna_crtc->gamma_lut;
+	struct drm_mode_get_blob blob;
+	int lut_size, i;
+
+	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
+
+	memset(&blob, 0, sizeof(blob));
+	blob.blob_id = sna_crtc->gamma_lut_blob;
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
+		return false;
+
+	lut_size = blob.length / sizeof(lut[0]);
+
+	if (lut_size == 0 ||
+	    lut_size > max(sna_crtc->gamma_lut_size, 256))
+		return false;
+
+	blob.data = (uintptr_t)lut;
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
+		return false;
+
+	for (i = 0; i < size; i++) {
+		struct drm_color_lut *entry =
+			&lut[i * (lut_size - 1) / (size - 1)];
+
+		red[i] = entry->red;
+		green[i] = entry->green;
+		blue[i] = entry->blue;
+	}
+
+	return red[size - 1] &&
+		green[size - 1] &&
+		blue[size - 1];
+}
+
+static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
+				  CARD16 *red,
+				  CARD16 *green,
+				  CARD16 *blue,
+				  int size)
+{
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_mode_crtc_lut lut = {
+		.crtc_id = __sna_crtc_id(sna_crtc),
+		.gamma_size = size,
+		.red = (uintptr_t)red,
+		.green = (uintptr_t)green,
+		.blue = (uintptr_t)blue,
+	};
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
+		return false;
+
+	VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
+	VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
+	VG(VALGRIND_MAKE_MEM_DEFINED(bluered, size*sizeof(blue[0])));
+
+	return red[size - 1] &&
+		green[size - 1] &&
+		blue[size - 1];
+}
+
 static void crtc_init_gamma(xf86CrtcPtr crtc)
 {
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 	uint16_t *gamma;
+	int size;
+
+	assert(sna_crtc);
+
+	size = sna_crtc->gamma_lut_size;
+	if (!size)
+		size = 256;
 
 	/* Initialize the gamma ramps */
 	gamma = NULL;
-	if (crtc->gamma_size == 256)
+	if (crtc->gamma_size == size)
 		gamma = crtc->gamma_red;
 	if (gamma == NULL)
-		gamma = malloc(3 * 256 * sizeof(uint16_t));
+		gamma = malloc(3 * size * sizeof(uint16_t));
 	if (gamma) {
-		struct sna *sna = to_sna(crtc->scrn);
-		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 		struct drm_mode_crtc_lut lut;
-		bool gamma_set = false;
-
-		assert(sna_crtc);
-
-		lut.crtc_id = __sna_crtc_id(sna_crtc);
-		lut.gamma_size = 256;
-		lut.red = (uintptr_t)(gamma);
-		lut.green = (uintptr_t)(gamma + 256);
-		lut.blue = (uintptr_t)(gamma + 2 * 256);
-		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) {
-			VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0])));
-			gamma_set =
-				gamma[256 - 1] &&
-				gamma[2*256 - 1] &&
-				gamma[3*256 - 1];
-		}
+		bool gamma_set;
+		uint16_t *red = gamma;
+		uint16_t *green = gamma + size;
+		uint16_t *blue = gamma + 2 * size;
+
+		if (sna_crtc->gamma_lut_size)
+			gamma_set = crtc_get_gamma_lut(crtc, red,
+						       green, blue, size);
+		else
+			gamma_set = crtc_get_gamma_legacy(crtc, red,
+							  green, blue, size);
 
 		DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
 		     __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
@@ -7319,19 +7486,21 @@ static void crtc_init_gamma(xf86CrtcPtr crtc)
 		if (!gamma_set) {
 			int i;
 
-			for (i = 0; i < 256; i++) {
-				gamma[i] = i << 8;
-				gamma[256 + i] = i << 8;
-				gamma[2*256 + i] = i << 8;
+			for (i = 0; i < size; i++) {
+				uint16_t val = i * 0xffff / (size - 1);
+
+				red[i] = val;
+				green[i] = val;
+				blue[i] = val;
 			}
 		}
 
-		if (gamma != crtc->gamma_red) {
+		if (red != crtc->gamma_red) {
 			free(crtc->gamma_red);
-			crtc->gamma_red = gamma;
-			crtc->gamma_green = gamma + 256;
-			crtc->gamma_blue = gamma + 2*256;
-			crtc->gamma_size = 256;
+			crtc->gamma_red = red;
+			crtc->gamma_green = green;
+			crtc->gamma_blue = blue;
+			crtc->gamma_size = size;
 		}
 	}
 }
-- 
2.19.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-02-18 19:50 ` [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property Ville Syrjala
@ 2019-03-01 13:13   ` Chris Wilson
  2019-04-26 16:32   ` [PATCH xf86-video-intel v2 " Ville Syrjala
  2019-05-17 13:51   ` [PATCH xf86-video-intel v3 " Ville Syrjala
  2 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2019-03-01 13:13 UTC (permalink / raw)
  To: Ville Syrjala, intel-gfx

Quoting Ville Syrjala (2019-02-18 19:50:52)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Probe the GAMMA_LUT/GAMMA_LUT_SIZE props and utilize them when
> the running with > 8bpc.
> 
> Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Looks fine to me, so I'll push unless any one objects.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH xf86-video-intel v2 1/2] sna: Refactor property parsing
  2019-02-18 19:50 [PATCH xf86-video-intel 1/2] sna: Refactor property parsing Ville Syrjala
  2019-02-18 19:50 ` [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property Ville Syrjala
@ 2019-04-26 16:32 ` Ville Syrjala
  2019-05-16 19:39   ` Mario Kleiner
  1 sibling, 1 reply; 11+ messages in thread
From: Ville Syrjala @ 2019-04-26 16:32 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Generalize the code that parses the plane properties to be useable
for crtc (or any kms object) properties as well.

v2: plane 'type' prop is enum not range!

Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 src/sna/sna_display.c | 69 ++++++++++++++++++++++++++++++-------------
 1 file changed, 49 insertions(+), 20 deletions(-)

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 119ea981d243..41edfec12839 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -215,6 +215,7 @@ struct sna_crtc {
 	uint32_t rotation;
 	struct plane {
 		uint32_t id;
+		uint32_t type;
 		struct {
 			uint32_t prop;
 			uint32_t supported;
@@ -3391,33 +3392,40 @@ void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,
 				 p->color_encoding.values[colorspace]);
 }
 
-static int plane_details(struct sna *sna, struct plane *p)
+typedef void (*parse_prop_func)(struct sna *sna,
+				struct drm_mode_get_property *prop,
+				uint64_t value,
+				void *data);
+static void parse_props(struct sna *sna,
+		       uint32_t obj_type, uint32_t obj_id,
+		       parse_prop_func parse_prop,
+		       void *data)
 {
 #define N_STACK_PROPS 32 /* must be a multiple of 2 */
 	struct local_mode_obj_get_properties arg;
 	uint64_t stack[N_STACK_PROPS + N_STACK_PROPS/2];
 	uint64_t *values = stack;
 	uint32_t *props = (uint32_t *)(values + N_STACK_PROPS);
-	int i, type = DRM_PLANE_TYPE_OVERLAY;
+	int i;
 
 	memset(&arg, 0, sizeof(struct local_mode_obj_get_properties));
-	arg.obj_id = p->id;
-	arg.obj_type = LOCAL_MODE_OBJECT_PLANE;
+	arg.obj_id = obj_id;
+	arg.obj_type = obj_type;
 
 	arg.props_ptr = (uintptr_t)props;
 	arg.prop_values_ptr = (uintptr_t)values;
 	arg.count_props = N_STACK_PROPS;
 
 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
-		return -1;
+		return;
 
 	DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__,
-	     p->id, LOCAL_MODE_OBJECT_PLANE, arg.count_props));
+	     obj_id, obj_type, arg.count_props));
 
 	if (arg.count_props > N_STACK_PROPS) {
 		values = malloc(2*sizeof(uint64_t)*arg.count_props);
 		if (values == NULL)
-			return -1;
+			return;
 
 		props = (uint32_t *)(values + arg.count_props);
 
@@ -3444,27 +3452,48 @@ static int plane_details(struct sna *sna, struct plane *p)
 		DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
 		     (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i]));
 
-		if (strcmp(prop.name, "type") == 0) {
-			type = values[i];
-		} else if (prop_is_rotation(&prop)) {
-			parse_rotation_prop(sna, p, &prop, values[i]);
-		} else if (prop_is_color_encoding(&prop)) {
-			parse_color_encoding_prop(sna, p, &prop, values[i]);
-		}
+		parse_prop(sna, &prop, values[i], data);
 	}
 
-	p->rotation.supported &= DBG_NATIVE_ROTATION;
-	if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE))
-		p->rotation.supported = RR_Rotate_0;
-
 	if (values != stack)
 		free(values);
 
-	DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, type));
-	return type;
 #undef N_STACK_PROPS
 }
 
+static bool prop_is_type(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 3, "type");
+}
+
+static void plane_parse_prop(struct sna *sna,
+			     struct drm_mode_get_property *prop,
+			     uint64_t value, void *data)
+{
+	struct plane *p = data;
+
+	if (prop_is_type(prop))
+		p->type = value;
+	else if (prop_is_rotation(prop))
+		parse_rotation_prop(sna, p, prop, value);
+	else if (prop_is_color_encoding(prop))
+		parse_color_encoding_prop(sna, p, prop, value);
+}
+
+static int plane_details(struct sna *sna, struct plane *p)
+{
+	parse_props(sna, LOCAL_MODE_OBJECT_PLANE, p->id,
+		    plane_parse_prop, p);
+
+	p->rotation.supported &= DBG_NATIVE_ROTATION;
+	if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE))
+		p->rotation.supported = RR_Rotate_0;
+
+	DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, p->type));
+
+	return p->type;
+}
+
 static void add_sprite_plane(struct sna_crtc *crtc,
 			     struct plane *details)
 {
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH xf86-video-intel v2 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-02-18 19:50 ` [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property Ville Syrjala
  2019-03-01 13:13   ` Chris Wilson
@ 2019-04-26 16:32   ` Ville Syrjala
  2019-05-16 19:54     ` Mario Kleiner
  2019-05-17 13:51   ` [PATCH xf86-video-intel v3 " Ville Syrjala
  2 siblings, 1 reply; 11+ messages in thread
From: Ville Syrjala @ 2019-04-26 16:32 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Probe the GAMMA_LUT/GAMMA_LUT_SIZE props and utilize them when
the running with > 8bpc.

v2: s/sna_crtc_id/__sna_crtc_id/ in DBG since we have a sna_crtc

Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 src/sna/sna_display.c | 245 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 207 insertions(+), 38 deletions(-)

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 41edfec12839..6d671dce8c14 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -127,6 +127,7 @@ struct local_mode_obj_get_properties {
 	uint32_t obj_type;
 	uint32_t pad;
 };
+#define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
 #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
 
 struct local_mode_set_plane {
@@ -229,6 +230,11 @@ struct sna_crtc {
 	} primary;
 	struct list sprites;
 
+	struct drm_color_lut *gamma_lut;
+	uint64_t gamma_lut_prop;
+	uint64_t gamma_lut_blob;
+	uint32_t gamma_lut_size;
+
 	uint32_t mode_serial, flip_serial;
 
 	uint32_t last_seq, wrap_seq;
@@ -317,6 +323,9 @@ static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
 static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
 static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
 			  struct kgem_bo *bo, int x, int y);
+static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
+			       CARD16 *red, CARD16 *green,
+			       CARD16 *blue, int size);
 
 static bool is_zaphod(ScrnInfoPtr scrn)
 {
@@ -3150,11 +3159,9 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	       mode->VDisplay <= sna->mode.max_crtc_height);
 
 #if HAS_GAMMA
-	drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc),
-			    crtc->gamma_size,
-			    crtc->gamma_red,
-			    crtc->gamma_green,
-			    crtc->gamma_blue);
+	sna_crtc_gamma_set(crtc,
+			   crtc->gamma_red, crtc->gamma_green,
+			   crtc->gamma_blue, crtc->gamma_size);
 #endif
 
 	saved_kmode = sna_crtc->kmode;
@@ -3212,12 +3219,44 @@ void sna_mode_adjust_frame(struct sna *sna, int x, int y)
 
 static void
 sna_crtc_gamma_set(xf86CrtcPtr crtc,
-		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
 {
-	assert(to_sna_crtc(crtc));
-	drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
-			    sna_crtc_id(crtc),
-			    size, red, green, blue);
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_color_lut *lut = sna_crtc->gamma_lut;
+	uint32_t blob_size = size * sizeof(lut[0]);
+	uint32_t blob_id;
+	int ret, i;
+
+	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
+
+	if (!lut) {
+		assert(size == 256);
+
+		drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
+				    sna_crtc_id(crtc),
+				    size, red, green, blue);
+		return;
+	}
+
+	assert(size == sna_crtc->gamma_lut_size);
+
+	for (i = 0; i < size; i++) {
+		lut[i].red = red[i];
+		lut[i].green = green[i];
+		lut[i].blue = blue[i];
+	}
+
+	ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
+	if (ret)
+		return;
+
+	ret = drmModeObjectSetProperty(sna->kgem.fd,
+				       sna_crtc->id, DRM_MODE_OBJECT_CRTC,
+				       sna_crtc->gamma_lut_prop,
+				       blob_id);
+
+	drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
 }
 
 static void
@@ -3229,6 +3268,8 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
 	if (sna_crtc == NULL)
 		return;
 
+	free(sna_crtc->gamma_lut);
+
 	list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
 		free(sprite);
 
@@ -3663,6 +3704,55 @@ bool sna_has_sprite_format(struct sna *sna, uint32_t format)
 	return false;
 }
 
+inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
+}
+
+inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
+}
+
+static void sna_crtc_parse_prop(struct sna *sna,
+				struct drm_mode_get_property *prop,
+				uint64_t value, void *data)
+{
+	struct sna_crtc *crtc = data;
+
+	if (prop_is_gamma_lut(prop)) {
+		crtc->gamma_lut_prop = prop->prop_id;
+		crtc->gamma_lut_blob = value;
+	} else if (prop_is_gamma_lut_size(prop)) {
+		crtc->gamma_lut_size = value;
+	}
+}
+
+static void
+sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+
+	parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
+		    sna_crtc_parse_prop, crtc);
+
+	/* use high precision gamma LUT for > 8bpc */
+	/* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
+	if (scrn->rgbBits <= 8 ||
+	    XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
+		crtc->gamma_lut_size = 0;
+
+	if (crtc->gamma_lut_size) {
+		crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
+					 sizeof(crtc->gamma_lut[0]));
+		if (!crtc->gamma_lut)
+			crtc->gamma_lut_size = 0;
+	}
+
+	DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
+	     __sna_crtc_id(crtc), crtc->gamma_lut_size));
+}
+
 static void
 sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
 {
@@ -3723,6 +3813,9 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
 
 	list_init(&sna_crtc->sprites);
 	sna_crtc_init__rotation(sna, sna_crtc);
+
+	sna_crtc_init__props(sna, sna_crtc);
+
 	sna_crtc_find_planes(sna, sna_crtc);
 
 	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
@@ -7274,36 +7367,110 @@ static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
 			  mon->mon_gamma_blue);
 }
 
+static bool
+crtc_get_gamma_lut(xf86CrtcPtr crtc,
+		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+{
+
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_color_lut *lut = sna_crtc->gamma_lut;
+	struct drm_mode_get_blob blob;
+	int lut_size, i;
+
+	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
+
+	memset(&blob, 0, sizeof(blob));
+	blob.blob_id = sna_crtc->gamma_lut_blob;
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
+		return false;
+
+	lut_size = blob.length / sizeof(lut[0]);
+
+	if (lut_size == 0 ||
+	    lut_size > max(sna_crtc->gamma_lut_size, 256))
+		return false;
+
+	blob.data = (uintptr_t)lut;
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
+		return false;
+
+	for (i = 0; i < size; i++) {
+		struct drm_color_lut *entry =
+			&lut[i * (lut_size - 1) / (size - 1)];
+
+		red[i] = entry->red;
+		green[i] = entry->green;
+		blue[i] = entry->blue;
+	}
+
+	return red[size - 1] &&
+		green[size - 1] &&
+		blue[size - 1];
+}
+
+static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
+				  CARD16 *red,
+				  CARD16 *green,
+				  CARD16 *blue,
+				  int size)
+{
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_mode_crtc_lut lut = {
+		.crtc_id = __sna_crtc_id(sna_crtc),
+		.gamma_size = size,
+		.red = (uintptr_t)red,
+		.green = (uintptr_t)green,
+		.blue = (uintptr_t)blue,
+	};
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
+		return false;
+
+	VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
+	VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
+	VG(VALGRIND_MAKE_MEM_DEFINED(bluered, size*sizeof(blue[0])));
+
+	return red[size - 1] &&
+		green[size - 1] &&
+		blue[size - 1];
+}
+
 static void crtc_init_gamma(xf86CrtcPtr crtc)
 {
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 	uint16_t *gamma;
+	int size;
+
+	assert(sna_crtc);
+
+	size = sna_crtc->gamma_lut_size;
+	if (!size)
+		size = 256;
 
 	/* Initialize the gamma ramps */
 	gamma = NULL;
-	if (crtc->gamma_size == 256)
+	if (crtc->gamma_size == size)
 		gamma = crtc->gamma_red;
 	if (gamma == NULL)
-		gamma = malloc(3 * 256 * sizeof(uint16_t));
+		gamma = malloc(3 * size * sizeof(uint16_t));
 	if (gamma) {
-		struct sna *sna = to_sna(crtc->scrn);
-		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 		struct drm_mode_crtc_lut lut;
-		bool gamma_set = false;
+		bool gamma_set;
+		uint16_t *red = gamma;
+		uint16_t *green = gamma + size;
+		uint16_t *blue = gamma + 2 * size;
 
-		assert(sna_crtc);
-
-		lut.crtc_id = __sna_crtc_id(sna_crtc);
-		lut.gamma_size = 256;
-		lut.red = (uintptr_t)(gamma);
-		lut.green = (uintptr_t)(gamma + 256);
-		lut.blue = (uintptr_t)(gamma + 2 * 256);
-		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) {
-			VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0])));
-			gamma_set =
-				gamma[256 - 1] &&
-				gamma[2*256 - 1] &&
-				gamma[3*256 - 1];
-		}
+		if (sna_crtc->gamma_lut_size)
+			gamma_set = crtc_get_gamma_lut(crtc, red,
+						       green, blue, size);
+		else
+			gamma_set = crtc_get_gamma_legacy(crtc, red,
+							  green, blue, size);
 
 		DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
 		     __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
@@ -7311,19 +7478,21 @@ static void crtc_init_gamma(xf86CrtcPtr crtc)
 		if (!gamma_set) {
 			int i;
 
-			for (i = 0; i < 256; i++) {
-				gamma[i] = i << 8;
-				gamma[256 + i] = i << 8;
-				gamma[2*256 + i] = i << 8;
+			for (i = 0; i < size; i++) {
+				uint16_t val = i * 0xffff / (size - 1);
+
+				red[i] = val;
+				green[i] = val;
+				blue[i] = val;
 			}
 		}
 
-		if (gamma != crtc->gamma_red) {
+		if (red != crtc->gamma_red) {
 			free(crtc->gamma_red);
-			crtc->gamma_red = gamma;
-			crtc->gamma_green = gamma + 256;
-			crtc->gamma_blue = gamma + 2*256;
-			crtc->gamma_size = 256;
+			crtc->gamma_red = red;
+			crtc->gamma_green = green;
+			crtc->gamma_blue = blue;
+			crtc->gamma_size = size;
 		}
 	}
 }
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH xf86-video-intel v2 1/2] sna: Refactor property parsing
  2019-04-26 16:32 ` [PATCH xf86-video-intel v2 1/2] sna: Refactor property parsing Ville Syrjala
@ 2019-05-16 19:39   ` Mario Kleiner
  0 siblings, 0 replies; 11+ messages in thread
From: Mario Kleiner @ 2019-05-16 19:39 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Fri, Apr 26, 2019 at 6:32 PM Ville Syrjala
<ville.syrjala@linux.intel.com> wrote:
>
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Generalize the code that parses the plane properties to be useable
> for crtc (or any kms object) properties as well.
>
> v2: plane 'type' prop is enum not range!
>
> Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---

This patch is

Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>

-mario

>  src/sna/sna_display.c | 69 ++++++++++++++++++++++++++++++-------------
>  1 file changed, 49 insertions(+), 20 deletions(-)
>
> diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
> index 119ea981d243..41edfec12839 100644
> --- a/src/sna/sna_display.c
> +++ b/src/sna/sna_display.c
> @@ -215,6 +215,7 @@ struct sna_crtc {
>         uint32_t rotation;
>         struct plane {
>                 uint32_t id;
> +               uint32_t type;
>                 struct {
>                         uint32_t prop;
>                         uint32_t supported;
> @@ -3391,33 +3392,40 @@ void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,
>                                  p->color_encoding.values[colorspace]);
>  }
>
> -static int plane_details(struct sna *sna, struct plane *p)
> +typedef void (*parse_prop_func)(struct sna *sna,
> +                               struct drm_mode_get_property *prop,
> +                               uint64_t value,
> +                               void *data);
> +static void parse_props(struct sna *sna,
> +                      uint32_t obj_type, uint32_t obj_id,
> +                      parse_prop_func parse_prop,
> +                      void *data)
>  {
>  #define N_STACK_PROPS 32 /* must be a multiple of 2 */
>         struct local_mode_obj_get_properties arg;
>         uint64_t stack[N_STACK_PROPS + N_STACK_PROPS/2];
>         uint64_t *values = stack;
>         uint32_t *props = (uint32_t *)(values + N_STACK_PROPS);
> -       int i, type = DRM_PLANE_TYPE_OVERLAY;
> +       int i;
>
>         memset(&arg, 0, sizeof(struct local_mode_obj_get_properties));
> -       arg.obj_id = p->id;
> -       arg.obj_type = LOCAL_MODE_OBJECT_PLANE;
> +       arg.obj_id = obj_id;
> +       arg.obj_type = obj_type;
>
>         arg.props_ptr = (uintptr_t)props;
>         arg.prop_values_ptr = (uintptr_t)values;
>         arg.count_props = N_STACK_PROPS;
>
>         if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
> -               return -1;
> +               return;
>
>         DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__,
> -            p->id, LOCAL_MODE_OBJECT_PLANE, arg.count_props));
> +            obj_id, obj_type, arg.count_props));
>
>         if (arg.count_props > N_STACK_PROPS) {
>                 values = malloc(2*sizeof(uint64_t)*arg.count_props);
>                 if (values == NULL)
> -                       return -1;
> +                       return;
>
>                 props = (uint32_t *)(values + arg.count_props);
>
> @@ -3444,27 +3452,48 @@ static int plane_details(struct sna *sna, struct plane *p)
>                 DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
>                      (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i]));
>
> -               if (strcmp(prop.name, "type") == 0) {
> -                       type = values[i];
> -               } else if (prop_is_rotation(&prop)) {
> -                       parse_rotation_prop(sna, p, &prop, values[i]);
> -               } else if (prop_is_color_encoding(&prop)) {
> -                       parse_color_encoding_prop(sna, p, &prop, values[i]);
> -               }
> +               parse_prop(sna, &prop, values[i], data);
>         }
>
> -       p->rotation.supported &= DBG_NATIVE_ROTATION;
> -       if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE))
> -               p->rotation.supported = RR_Rotate_0;
> -
>         if (values != stack)
>                 free(values);
>
> -       DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, type));
> -       return type;
>  #undef N_STACK_PROPS
>  }
>
> +static bool prop_is_type(const struct drm_mode_get_property *prop)
> +{
> +       return prop_has_type_and_name(prop, 3, "type");
> +}
> +
> +static void plane_parse_prop(struct sna *sna,
> +                            struct drm_mode_get_property *prop,
> +                            uint64_t value, void *data)
> +{
> +       struct plane *p = data;
> +
> +       if (prop_is_type(prop))
> +               p->type = value;
> +       else if (prop_is_rotation(prop))
> +               parse_rotation_prop(sna, p, prop, value);
> +       else if (prop_is_color_encoding(prop))
> +               parse_color_encoding_prop(sna, p, prop, value);
> +}
> +
> +static int plane_details(struct sna *sna, struct plane *p)
> +{
> +       parse_props(sna, LOCAL_MODE_OBJECT_PLANE, p->id,
> +                   plane_parse_prop, p);
> +
> +       p->rotation.supported &= DBG_NATIVE_ROTATION;
> +       if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE))
> +               p->rotation.supported = RR_Rotate_0;
> +
> +       DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, p->type));
> +
> +       return p->type;
> +}
> +
>  static void add_sprite_plane(struct sna_crtc *crtc,
>                              struct plane *details)
>  {
> --
> 2.21.0
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH xf86-video-intel v2 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-04-26 16:32   ` [PATCH xf86-video-intel v2 " Ville Syrjala
@ 2019-05-16 19:54     ` Mario Kleiner
  2019-05-17 13:49       ` Ville Syrjälä
  0 siblings, 1 reply; 11+ messages in thread
From: Mario Kleiner @ 2019-05-16 19:54 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

On Fri, Apr 26, 2019 at 6:32 PM Ville Syrjala
<ville.syrjala@linux.intel.com> wrote:
>
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Probe the GAMMA_LUT/GAMMA_LUT_SIZE props and utilize them when
> the running with > 8bpc.
>
> v2: s/sna_crtc_id/__sna_crtc_id/ in DBG since we have a sna_crtc
>
> Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  src/sna/sna_display.c | 245 +++++++++++++++++++++++++++++++++++-------
>  1 file changed, 207 insertions(+), 38 deletions(-)
>
> diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
> index 41edfec12839..6d671dce8c14 100644
> --- a/src/sna/sna_display.c
> +++ b/src/sna/sna_display.c
> @@ -127,6 +127,7 @@ struct local_mode_obj_get_properties {
>         uint32_t obj_type;
>         uint32_t pad;
>  };
> +#define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
>  #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
>
>  struct local_mode_set_plane {
> @@ -229,6 +230,11 @@ struct sna_crtc {
>         } primary;
>         struct list sprites;
>
> +       struct drm_color_lut *gamma_lut;
> +       uint64_t gamma_lut_prop;
> +       uint64_t gamma_lut_blob;
> +       uint32_t gamma_lut_size;
> +
>         uint32_t mode_serial, flip_serial;
>
>         uint32_t last_seq, wrap_seq;
> @@ -317,6 +323,9 @@ static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
>  static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
>  static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
>                           struct kgem_bo *bo, int x, int y);
> +static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
> +                              CARD16 *red, CARD16 *green,
> +                              CARD16 *blue, int size);
>
>  static bool is_zaphod(ScrnInfoPtr scrn)
>  {
> @@ -3150,11 +3159,9 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
>                mode->VDisplay <= sna->mode.max_crtc_height);
>
>  #if HAS_GAMMA
> -       drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc),
> -                           crtc->gamma_size,
> -                           crtc->gamma_red,
> -                           crtc->gamma_green,
> -                           crtc->gamma_blue);
> +       sna_crtc_gamma_set(crtc,
> +                          crtc->gamma_red, crtc->gamma_green,
> +                          crtc->gamma_blue, crtc->gamma_size);
>  #endif
>
>         saved_kmode = sna_crtc->kmode;
> @@ -3212,12 +3219,44 @@ void sna_mode_adjust_frame(struct sna *sna, int x, int y)
>
>  static void
>  sna_crtc_gamma_set(xf86CrtcPtr crtc,
> -                      CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> +                  CARD16 *red, CARD16 *green, CARD16 *blue, int size)
>  {
> -       assert(to_sna_crtc(crtc));
> -       drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
> -                           sna_crtc_id(crtc),
> -                           size, red, green, blue);
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> +       struct drm_color_lut *lut = sna_crtc->gamma_lut;
> +       uint32_t blob_size = size * sizeof(lut[0]);
> +       uint32_t blob_id;
> +       int ret, i;
> +
> +       DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
> +
> +       if (!lut) {
> +               assert(size == 256);
> +
> +               drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
> +                                   sna_crtc_id(crtc),
> +                                   size, red, green, blue);
> +               return;
> +       }
> +
> +       assert(size == sna_crtc->gamma_lut_size);
> +
> +       for (i = 0; i < size; i++) {
> +               lut[i].red = red[i];
> +               lut[i].green = green[i];
> +               lut[i].blue = blue[i];
> +       }
> +
> +       ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
> +       if (ret)
> +               return;
> +
> +       ret = drmModeObjectSetProperty(sna->kgem.fd,
> +                                      sna_crtc->id, DRM_MODE_OBJECT_CRTC,
> +                                      sna_crtc->gamma_lut_prop,
> +                                      blob_id);
> +
> +       drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
>  }
>
>  static void
> @@ -3229,6 +3268,8 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
>         if (sna_crtc == NULL)
>                 return;
>
> +       free(sna_crtc->gamma_lut);
> +
>         list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
>                 free(sprite);
>
> @@ -3663,6 +3704,55 @@ bool sna_has_sprite_format(struct sna *sna, uint32_t format)
>         return false;
>  }
>
> +inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
> +{
> +       return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
> +}
> +
> +inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
> +{
> +       return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
> +}
> +
> +static void sna_crtc_parse_prop(struct sna *sna,
> +                               struct drm_mode_get_property *prop,
> +                               uint64_t value, void *data)
> +{
> +       struct sna_crtc *crtc = data;
> +
> +       if (prop_is_gamma_lut(prop)) {
> +               crtc->gamma_lut_prop = prop->prop_id;
> +               crtc->gamma_lut_blob = value;
> +       } else if (prop_is_gamma_lut_size(prop)) {
> +               crtc->gamma_lut_size = value;
> +       }
> +}
> +
> +static void
> +sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
> +{
> +       ScrnInfoPtr scrn = sna->scrn;
> +
> +       parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
> +                   sna_crtc_parse_prop, crtc);
> +
> +       /* use high precision gamma LUT for > 8bpc */
> +       /* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
> +       if (scrn->rgbBits <= 8 ||
> +           XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
> +               crtc->gamma_lut_size = 0;
> +

One suggestion: Might make sense to print some xf86DrivMsg() info or
warning message
to the startup output of the driver [sna_driver.c - sna_pre_init()]
iff one tries to select a
X-Screen depth >= 30 aka scrn->rgbBits > 8 on a pre-1.20.0 server, so
users get some
hint that they need a 1.20+ server to actually get any extra precision
out of a depth 30
screen beyond the 8 bpc of the legacy gamma lut's?

Of course this could also be done in a followup up patch, not to stop
this from getting merged.

> +       if (crtc->gamma_lut_size) {
> +               crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
> +                                        sizeof(crtc->gamma_lut[0]));
> +               if (!crtc->gamma_lut)
> +                       crtc->gamma_lut_size = 0;
> +       }
> +
> +       DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
> +            __sna_crtc_id(crtc), crtc->gamma_lut_size));
> +}
> +
>  static void
>  sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
>  {
> @@ -3723,6 +3813,9 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
>
>         list_init(&sna_crtc->sprites);
>         sna_crtc_init__rotation(sna, sna_crtc);
> +
> +       sna_crtc_init__props(sna, sna_crtc);
> +
>         sna_crtc_find_planes(sna, sna_crtc);
>
>         DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
> @@ -7274,36 +7367,110 @@ static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
>                           mon->mon_gamma_blue);
>  }
>
> +static bool
> +crtc_get_gamma_lut(xf86CrtcPtr crtc,
> +                  CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> +{
> +
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> +       struct drm_color_lut *lut = sna_crtc->gamma_lut;
> +       struct drm_mode_get_blob blob;
> +       int lut_size, i;
> +
> +       DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
> +
> +       memset(&blob, 0, sizeof(blob));
> +       blob.blob_id = sna_crtc->gamma_lut_blob;
> +
> +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
> +               return false;
> +
> +       lut_size = blob.length / sizeof(lut[0]);
> +
> +       if (lut_size == 0 ||
> +           lut_size > max(sna_crtc->gamma_lut_size, 256))
> +               return false;
> +
> +       blob.data = (uintptr_t)lut;
> +
> +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
> +               return false;
> +
> +       for (i = 0; i < size; i++) {
> +               struct drm_color_lut *entry =
> +                       &lut[i * (lut_size - 1) / (size - 1)];
> +
> +               red[i] = entry->red;
> +               green[i] = entry->green;
> +               blue[i] = entry->blue;
> +       }
> +
> +       return red[size - 1] &&
> +               green[size - 1] &&
> +               blue[size - 1];
> +}
> +
> +static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
> +                                 CARD16 *red,
> +                                 CARD16 *green,
> +                                 CARD16 *blue,
> +                                 int size)
> +{
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> +       struct drm_mode_crtc_lut lut = {
> +               .crtc_id = __sna_crtc_id(sna_crtc),
> +               .gamma_size = size,
> +               .red = (uintptr_t)red,
> +               .green = (uintptr_t)green,
> +               .blue = (uintptr_t)blue,
> +       };
> +
> +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
> +               return false;
> +
> +       VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
> +       VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
> +       VG(VALGRIND_MAKE_MEM_DEFINED(bluered, size*sizeof(blue[0])));

Typo in last VALGRIND_MAKE... macro: bluered -> blue

Other than that this looks fine and testing on an Ironlake and
Baytrail gpu under X-Server 1.20 with depth 24 and depth 30 confirms
it working.

With that fix, this patch is

Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>

Thanks a lot for adding the 10 bpc gamma lut support to the driver and
also i915-kms for Linux 5.2!
-mario

> +
> +       return red[size - 1] &&
> +               green[size - 1] &&
> +               blue[size - 1];
> +}
> +
>  static void crtc_init_gamma(xf86CrtcPtr crtc)
>  {
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
>         uint16_t *gamma;
> +       int size;
> +
> +       assert(sna_crtc);
> +
> +       size = sna_crtc->gamma_lut_size;
> +       if (!size)
> +               size = 256;
>
>         /* Initialize the gamma ramps */
>         gamma = NULL;
> -       if (crtc->gamma_size == 256)
> +       if (crtc->gamma_size == size)
>                 gamma = crtc->gamma_red;
>         if (gamma == NULL)
> -               gamma = malloc(3 * 256 * sizeof(uint16_t));
> +               gamma = malloc(3 * size * sizeof(uint16_t));
>         if (gamma) {
> -               struct sna *sna = to_sna(crtc->scrn);
> -               struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
>                 struct drm_mode_crtc_lut lut;
> -               bool gamma_set = false;
> +               bool gamma_set;
> +               uint16_t *red = gamma;
> +               uint16_t *green = gamma + size;
> +               uint16_t *blue = gamma + 2 * size;
>
> -               assert(sna_crtc);
> -
> -               lut.crtc_id = __sna_crtc_id(sna_crtc);
> -               lut.gamma_size = 256;
> -               lut.red = (uintptr_t)(gamma);
> -               lut.green = (uintptr_t)(gamma + 256);
> -               lut.blue = (uintptr_t)(gamma + 2 * 256);
> -               if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) {
> -                       VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0])));
> -                       gamma_set =
> -                               gamma[256 - 1] &&
> -                               gamma[2*256 - 1] &&
> -                               gamma[3*256 - 1];
> -               }
> +               if (sna_crtc->gamma_lut_size)
> +                       gamma_set = crtc_get_gamma_lut(crtc, red,
> +                                                      green, blue, size);
> +               else
> +                       gamma_set = crtc_get_gamma_legacy(crtc, red,
> +                                                         green, blue, size);
>
>                 DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
>                      __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
> @@ -7311,19 +7478,21 @@ static void crtc_init_gamma(xf86CrtcPtr crtc)
>                 if (!gamma_set) {
>                         int i;
>
> -                       for (i = 0; i < 256; i++) {
> -                               gamma[i] = i << 8;
> -                               gamma[256 + i] = i << 8;
> -                               gamma[2*256 + i] = i << 8;
> +                       for (i = 0; i < size; i++) {
> +                               uint16_t val = i * 0xffff / (size - 1);
> +
> +                               red[i] = val;
> +                               green[i] = val;
> +                               blue[i] = val;
>                         }
>                 }
>
> -               if (gamma != crtc->gamma_red) {
> +               if (red != crtc->gamma_red) {
>                         free(crtc->gamma_red);
> -                       crtc->gamma_red = gamma;
> -                       crtc->gamma_green = gamma + 256;
> -                       crtc->gamma_blue = gamma + 2*256;
> -                       crtc->gamma_size = 256;
> +                       crtc->gamma_red = red;
> +                       crtc->gamma_green = green;
> +                       crtc->gamma_blue = blue;
> +                       crtc->gamma_size = size;
>                 }
>         }
>  }
> --
> 2.21.0
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH xf86-video-intel v2 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-05-16 19:54     ` Mario Kleiner
@ 2019-05-17 13:49       ` Ville Syrjälä
  0 siblings, 0 replies; 11+ messages in thread
From: Ville Syrjälä @ 2019-05-17 13:49 UTC (permalink / raw)
  To: Mario Kleiner; +Cc: intel-gfx

On Thu, May 16, 2019 at 09:54:55PM +0200, Mario Kleiner wrote:
> On Fri, Apr 26, 2019 at 6:32 PM Ville Syrjala
> <ville.syrjala@linux.intel.com> wrote:
> >
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > Probe the GAMMA_LUT/GAMMA_LUT_SIZE props and utilize them when
> > the running with > 8bpc.
> >
> > v2: s/sna_crtc_id/__sna_crtc_id/ in DBG since we have a sna_crtc
> >
> > Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  src/sna/sna_display.c | 245 +++++++++++++++++++++++++++++++++++-------
> >  1 file changed, 207 insertions(+), 38 deletions(-)
> >
> > diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
> > index 41edfec12839..6d671dce8c14 100644
> > --- a/src/sna/sna_display.c
> > +++ b/src/sna/sna_display.c
> > @@ -127,6 +127,7 @@ struct local_mode_obj_get_properties {
> >         uint32_t obj_type;
> >         uint32_t pad;
> >  };
> > +#define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
> >  #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
> >
> >  struct local_mode_set_plane {
> > @@ -229,6 +230,11 @@ struct sna_crtc {
> >         } primary;
> >         struct list sprites;
> >
> > +       struct drm_color_lut *gamma_lut;
> > +       uint64_t gamma_lut_prop;
> > +       uint64_t gamma_lut_blob;
> > +       uint32_t gamma_lut_size;
> > +
> >         uint32_t mode_serial, flip_serial;
> >
> >         uint32_t last_seq, wrap_seq;
> > @@ -317,6 +323,9 @@ static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
> >  static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
> >  static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
> >                           struct kgem_bo *bo, int x, int y);
> > +static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
> > +                              CARD16 *red, CARD16 *green,
> > +                              CARD16 *blue, int size);
> >
> >  static bool is_zaphod(ScrnInfoPtr scrn)
> >  {
> > @@ -3150,11 +3159,9 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
> >                mode->VDisplay <= sna->mode.max_crtc_height);
> >
> >  #if HAS_GAMMA
> > -       drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc),
> > -                           crtc->gamma_size,
> > -                           crtc->gamma_red,
> > -                           crtc->gamma_green,
> > -                           crtc->gamma_blue);
> > +       sna_crtc_gamma_set(crtc,
> > +                          crtc->gamma_red, crtc->gamma_green,
> > +                          crtc->gamma_blue, crtc->gamma_size);
> >  #endif
> >
> >         saved_kmode = sna_crtc->kmode;
> > @@ -3212,12 +3219,44 @@ void sna_mode_adjust_frame(struct sna *sna, int x, int y)
> >
> >  static void
> >  sna_crtc_gamma_set(xf86CrtcPtr crtc,
> > -                      CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> > +                  CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> >  {
> > -       assert(to_sna_crtc(crtc));
> > -       drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
> > -                           sna_crtc_id(crtc),
> > -                           size, red, green, blue);
> > +       struct sna *sna = to_sna(crtc->scrn);
> > +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> > +       struct drm_color_lut *lut = sna_crtc->gamma_lut;
> > +       uint32_t blob_size = size * sizeof(lut[0]);
> > +       uint32_t blob_id;
> > +       int ret, i;
> > +
> > +       DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
> > +
> > +       if (!lut) {
> > +               assert(size == 256);
> > +
> > +               drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
> > +                                   sna_crtc_id(crtc),
> > +                                   size, red, green, blue);
> > +               return;
> > +       }
> > +
> > +       assert(size == sna_crtc->gamma_lut_size);
> > +
> > +       for (i = 0; i < size; i++) {
> > +               lut[i].red = red[i];
> > +               lut[i].green = green[i];
> > +               lut[i].blue = blue[i];
> > +       }
> > +
> > +       ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
> > +       if (ret)
> > +               return;
> > +
> > +       ret = drmModeObjectSetProperty(sna->kgem.fd,
> > +                                      sna_crtc->id, DRM_MODE_OBJECT_CRTC,
> > +                                      sna_crtc->gamma_lut_prop,
> > +                                      blob_id);
> > +
> > +       drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
> >  }
> >
> >  static void
> > @@ -3229,6 +3268,8 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
> >         if (sna_crtc == NULL)
> >                 return;
> >
> > +       free(sna_crtc->gamma_lut);
> > +
> >         list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
> >                 free(sprite);
> >
> > @@ -3663,6 +3704,55 @@ bool sna_has_sprite_format(struct sna *sna, uint32_t format)
> >         return false;
> >  }
> >
> > +inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
> > +{
> > +       return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
> > +}
> > +
> > +inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
> > +{
> > +       return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
> > +}
> > +
> > +static void sna_crtc_parse_prop(struct sna *sna,
> > +                               struct drm_mode_get_property *prop,
> > +                               uint64_t value, void *data)
> > +{
> > +       struct sna_crtc *crtc = data;
> > +
> > +       if (prop_is_gamma_lut(prop)) {
> > +               crtc->gamma_lut_prop = prop->prop_id;
> > +               crtc->gamma_lut_blob = value;
> > +       } else if (prop_is_gamma_lut_size(prop)) {
> > +               crtc->gamma_lut_size = value;
> > +       }
> > +}
> > +
> > +static void
> > +sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
> > +{
> > +       ScrnInfoPtr scrn = sna->scrn;
> > +
> > +       parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
> > +                   sna_crtc_parse_prop, crtc);
> > +
> > +       /* use high precision gamma LUT for > 8bpc */
> > +       /* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
> > +       if (scrn->rgbBits <= 8 ||
> > +           XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
> > +               crtc->gamma_lut_size = 0;
> > +
> 
> One suggestion: Might make sense to print some xf86DrivMsg() info or
> warning message
> to the startup output of the driver [sna_driver.c - sna_pre_init()]
> iff one tries to select a
> X-Screen depth >= 30 aka scrn->rgbBits > 8 on a pre-1.20.0 server, so
> users get some
> hint that they need a 1.20+ server to actually get any extra precision
> out of a depth 30
> screen beyond the 8 bpc of the legacy gamma lut's?

Perhaps. Not sure how many people still on older xservers
would update their ddx though.

> 
> Of course this could also be done in a followup up patch, not to stop
> this from getting merged.

I supoose I can post a followup.

> 
> > +       if (crtc->gamma_lut_size) {
> > +               crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
> > +                                        sizeof(crtc->gamma_lut[0]));
> > +               if (!crtc->gamma_lut)
> > +                       crtc->gamma_lut_size = 0;
> > +       }
> > +
> > +       DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
> > +            __sna_crtc_id(crtc), crtc->gamma_lut_size));
> > +}
> > +
> >  static void
> >  sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
> >  {
> > @@ -3723,6 +3813,9 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
> >
> >         list_init(&sna_crtc->sprites);
> >         sna_crtc_init__rotation(sna, sna_crtc);
> > +
> > +       sna_crtc_init__props(sna, sna_crtc);
> > +
> >         sna_crtc_find_planes(sna, sna_crtc);
> >
> >         DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
> > @@ -7274,36 +7367,110 @@ static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
> >                           mon->mon_gamma_blue);
> >  }
> >
> > +static bool
> > +crtc_get_gamma_lut(xf86CrtcPtr crtc,
> > +                  CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> > +{
> > +
> > +       struct sna *sna = to_sna(crtc->scrn);
> > +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> > +       struct drm_color_lut *lut = sna_crtc->gamma_lut;
> > +       struct drm_mode_get_blob blob;
> > +       int lut_size, i;
> > +
> > +       DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
> > +
> > +       memset(&blob, 0, sizeof(blob));
> > +       blob.blob_id = sna_crtc->gamma_lut_blob;
> > +
> > +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
> > +               return false;
> > +
> > +       lut_size = blob.length / sizeof(lut[0]);
> > +
> > +       if (lut_size == 0 ||
> > +           lut_size > max(sna_crtc->gamma_lut_size, 256))
> > +               return false;
> > +
> > +       blob.data = (uintptr_t)lut;
> > +
> > +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
> > +               return false;
> > +
> > +       for (i = 0; i < size; i++) {
> > +               struct drm_color_lut *entry =
> > +                       &lut[i * (lut_size - 1) / (size - 1)];
> > +
> > +               red[i] = entry->red;
> > +               green[i] = entry->green;
> > +               blue[i] = entry->blue;
> > +       }
> > +
> > +       return red[size - 1] &&
> > +               green[size - 1] &&
> > +               blue[size - 1];
> > +}
> > +
> > +static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
> > +                                 CARD16 *red,
> > +                                 CARD16 *green,
> > +                                 CARD16 *blue,
> > +                                 int size)
> > +{
> > +       struct sna *sna = to_sna(crtc->scrn);
> > +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> > +       struct drm_mode_crtc_lut lut = {
> > +               .crtc_id = __sna_crtc_id(sna_crtc),
> > +               .gamma_size = size,
> > +               .red = (uintptr_t)red,
> > +               .green = (uintptr_t)green,
> > +               .blue = (uintptr_t)blue,
> > +       };
> > +
> > +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
> > +               return false;
> > +
> > +       VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
> > +       VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
> > +       VG(VALGRIND_MAKE_MEM_DEFINED(bluered, size*sizeof(blue[0])));
> 
> Typo in last VALGRIND_MAKE... macro: bluered -> blue

Doh. I guess I didn't actually build this with valgrind enabled.

> 
> Other than that this looks fine and testing on an Ironlake and
> Baytrail gpu under X-Server 1.20 with depth 24 and depth 30 confirms
> it working.

Cool. Thanks for the review and testing.

> 
> With that fix, this patch is
> 
> Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
> 
> Thanks a lot for adding the 10 bpc gamma lut support to the driver and
> also i915-kms for Linux 5.2!
> -mario
> 
> > +
> > +       return red[size - 1] &&
> > +               green[size - 1] &&
> > +               blue[size - 1];
> > +}
> > +
> >  static void crtc_init_gamma(xf86CrtcPtr crtc)
> >  {
> > +       struct sna *sna = to_sna(crtc->scrn);
> > +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> >         uint16_t *gamma;
> > +       int size;
> > +
> > +       assert(sna_crtc);
> > +
> > +       size = sna_crtc->gamma_lut_size;
> > +       if (!size)
> > +               size = 256;
> >
> >         /* Initialize the gamma ramps */
> >         gamma = NULL;
> > -       if (crtc->gamma_size == 256)
> > +       if (crtc->gamma_size == size)
> >                 gamma = crtc->gamma_red;
> >         if (gamma == NULL)
> > -               gamma = malloc(3 * 256 * sizeof(uint16_t));
> > +               gamma = malloc(3 * size * sizeof(uint16_t));
> >         if (gamma) {
> > -               struct sna *sna = to_sna(crtc->scrn);
> > -               struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> >                 struct drm_mode_crtc_lut lut;
> > -               bool gamma_set = false;
> > +               bool gamma_set;
> > +               uint16_t *red = gamma;
> > +               uint16_t *green = gamma + size;
> > +               uint16_t *blue = gamma + 2 * size;
> >
> > -               assert(sna_crtc);
> > -
> > -               lut.crtc_id = __sna_crtc_id(sna_crtc);
> > -               lut.gamma_size = 256;
> > -               lut.red = (uintptr_t)(gamma);
> > -               lut.green = (uintptr_t)(gamma + 256);
> > -               lut.blue = (uintptr_t)(gamma + 2 * 256);
> > -               if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) {
> > -                       VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0])));
> > -                       gamma_set =
> > -                               gamma[256 - 1] &&
> > -                               gamma[2*256 - 1] &&
> > -                               gamma[3*256 - 1];
> > -               }
> > +               if (sna_crtc->gamma_lut_size)
> > +                       gamma_set = crtc_get_gamma_lut(crtc, red,
> > +                                                      green, blue, size);
> > +               else
> > +                       gamma_set = crtc_get_gamma_legacy(crtc, red,
> > +                                                         green, blue, size);
> >
> >                 DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
> >                      __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
> > @@ -7311,19 +7478,21 @@ static void crtc_init_gamma(xf86CrtcPtr crtc)
> >                 if (!gamma_set) {
> >                         int i;
> >
> > -                       for (i = 0; i < 256; i++) {
> > -                               gamma[i] = i << 8;
> > -                               gamma[256 + i] = i << 8;
> > -                               gamma[2*256 + i] = i << 8;
> > +                       for (i = 0; i < size; i++) {
> > +                               uint16_t val = i * 0xffff / (size - 1);
> > +
> > +                               red[i] = val;
> > +                               green[i] = val;
> > +                               blue[i] = val;
> >                         }
> >                 }
> >
> > -               if (gamma != crtc->gamma_red) {
> > +               if (red != crtc->gamma_red) {
> >                         free(crtc->gamma_red);
> > -                       crtc->gamma_red = gamma;
> > -                       crtc->gamma_green = gamma + 256;
> > -                       crtc->gamma_blue = gamma + 2*256;
> > -                       crtc->gamma_size = 256;
> > +                       crtc->gamma_red = red;
> > +                       crtc->gamma_green = green;
> > +                       crtc->gamma_blue = blue;
> > +                       crtc->gamma_size = size;
> >                 }
> >         }
> >  }
> > --
> > 2.21.0
> >

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH xf86-video-intel v3 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-02-18 19:50 ` [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property Ville Syrjala
  2019-03-01 13:13   ` Chris Wilson
  2019-04-26 16:32   ` [PATCH xf86-video-intel v2 " Ville Syrjala
@ 2019-05-17 13:51   ` Ville Syrjala
  2019-07-09 18:34     ` Mario Kleiner
  2 siblings, 1 reply; 11+ messages in thread
From: Ville Syrjala @ 2019-05-17 13:51 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Probe the GAMMA_LUT/GAMMA_LUT_SIZE props and utilize them when
the running with > 8bpc.

v2: s/sna_crtc_id/__sna_crtc_id/ in DBG since we have a sna_crtc
v3: Fix the vg "bluered" typo (Mario)
    This time I even build tested with vg support

Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
---
 src/sna/sna_display.c | 247 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 208 insertions(+), 39 deletions(-)

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 41edfec12839..d6210cc7bbc8 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -127,6 +127,7 @@ struct local_mode_obj_get_properties {
 	uint32_t obj_type;
 	uint32_t pad;
 };
+#define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
 #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
 
 struct local_mode_set_plane {
@@ -229,6 +230,11 @@ struct sna_crtc {
 	} primary;
 	struct list sprites;
 
+	struct drm_color_lut *gamma_lut;
+	uint64_t gamma_lut_prop;
+	uint64_t gamma_lut_blob;
+	uint32_t gamma_lut_size;
+
 	uint32_t mode_serial, flip_serial;
 
 	uint32_t last_seq, wrap_seq;
@@ -317,6 +323,9 @@ static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
 static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
 static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
 			  struct kgem_bo *bo, int x, int y);
+static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
+			       CARD16 *red, CARD16 *green,
+			       CARD16 *blue, int size);
 
 static bool is_zaphod(ScrnInfoPtr scrn)
 {
@@ -3150,11 +3159,9 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	       mode->VDisplay <= sna->mode.max_crtc_height);
 
 #if HAS_GAMMA
-	drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc),
-			    crtc->gamma_size,
-			    crtc->gamma_red,
-			    crtc->gamma_green,
-			    crtc->gamma_blue);
+	sna_crtc_gamma_set(crtc,
+			   crtc->gamma_red, crtc->gamma_green,
+			   crtc->gamma_blue, crtc->gamma_size);
 #endif
 
 	saved_kmode = sna_crtc->kmode;
@@ -3212,12 +3219,44 @@ void sna_mode_adjust_frame(struct sna *sna, int x, int y)
 
 static void
 sna_crtc_gamma_set(xf86CrtcPtr crtc,
-		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
 {
-	assert(to_sna_crtc(crtc));
-	drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
-			    sna_crtc_id(crtc),
-			    size, red, green, blue);
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_color_lut *lut = sna_crtc->gamma_lut;
+	uint32_t blob_size = size * sizeof(lut[0]);
+	uint32_t blob_id;
+	int ret, i;
+
+	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
+
+	if (!lut) {
+		assert(size == 256);
+
+		drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
+				    sna_crtc_id(crtc),
+				    size, red, green, blue);
+		return;
+	}
+
+	assert(size == sna_crtc->gamma_lut_size);
+
+	for (i = 0; i < size; i++) {
+		lut[i].red = red[i];
+		lut[i].green = green[i];
+		lut[i].blue = blue[i];
+	}
+
+	ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
+	if (ret)
+		return;
+
+	ret = drmModeObjectSetProperty(sna->kgem.fd,
+				       sna_crtc->id, DRM_MODE_OBJECT_CRTC,
+				       sna_crtc->gamma_lut_prop,
+				       blob_id);
+
+	drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
 }
 
 static void
@@ -3229,6 +3268,8 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
 	if (sna_crtc == NULL)
 		return;
 
+	free(sna_crtc->gamma_lut);
+
 	list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
 		free(sprite);
 
@@ -3663,6 +3704,55 @@ bool sna_has_sprite_format(struct sna *sna, uint32_t format)
 	return false;
 }
 
+inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
+}
+
+inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
+{
+	return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
+}
+
+static void sna_crtc_parse_prop(struct sna *sna,
+				struct drm_mode_get_property *prop,
+				uint64_t value, void *data)
+{
+	struct sna_crtc *crtc = data;
+
+	if (prop_is_gamma_lut(prop)) {
+		crtc->gamma_lut_prop = prop->prop_id;
+		crtc->gamma_lut_blob = value;
+	} else if (prop_is_gamma_lut_size(prop)) {
+		crtc->gamma_lut_size = value;
+	}
+}
+
+static void
+sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+
+	parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
+		    sna_crtc_parse_prop, crtc);
+
+	/* use high precision gamma LUT for > 8bpc */
+	/* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
+	if (scrn->rgbBits <= 8 ||
+	    XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
+		crtc->gamma_lut_size = 0;
+
+	if (crtc->gamma_lut_size) {
+		crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
+					 sizeof(crtc->gamma_lut[0]));
+		if (!crtc->gamma_lut)
+			crtc->gamma_lut_size = 0;
+	}
+
+	DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
+	     __sna_crtc_id(crtc), crtc->gamma_lut_size));
+}
+
 static void
 sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
 {
@@ -3723,6 +3813,9 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
 
 	list_init(&sna_crtc->sprites);
 	sna_crtc_init__rotation(sna, sna_crtc);
+
+	sna_crtc_init__props(sna, sna_crtc);
+
 	sna_crtc_find_planes(sna, sna_crtc);
 
 	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
@@ -7274,36 +7367,110 @@ static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
 			  mon->mon_gamma_blue);
 }
 
+static bool
+crtc_get_gamma_lut(xf86CrtcPtr crtc,
+		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+{
+
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_color_lut *lut = sna_crtc->gamma_lut;
+	struct drm_mode_get_blob blob;
+	int lut_size, i;
+
+	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
+
+	memset(&blob, 0, sizeof(blob));
+	blob.blob_id = sna_crtc->gamma_lut_blob;
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
+		return false;
+
+	lut_size = blob.length / sizeof(lut[0]);
+
+	if (lut_size == 0 ||
+	    lut_size > max(sna_crtc->gamma_lut_size, 256))
+		return false;
+
+	blob.data = (uintptr_t)lut;
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
+		return false;
+
+	for (i = 0; i < size; i++) {
+		struct drm_color_lut *entry =
+			&lut[i * (lut_size - 1) / (size - 1)];
+
+		red[i] = entry->red;
+		green[i] = entry->green;
+		blue[i] = entry->blue;
+	}
+
+	return red[size - 1] &&
+		green[size - 1] &&
+		blue[size - 1];
+}
+
+static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
+				  CARD16 *red,
+				  CARD16 *green,
+				  CARD16 *blue,
+				  int size)
+{
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct drm_mode_crtc_lut lut = {
+		.crtc_id = __sna_crtc_id(sna_crtc),
+		.gamma_size = size,
+		.red = (uintptr_t)red,
+		.green = (uintptr_t)green,
+		.blue = (uintptr_t)blue,
+	};
+
+	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
+		return false;
+
+	VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
+	VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
+	VG(VALGRIND_MAKE_MEM_DEFINED(blue, size*sizeof(blue[0])));
+
+	return red[size - 1] &&
+		green[size - 1] &&
+		blue[size - 1];
+}
+
 static void crtc_init_gamma(xf86CrtcPtr crtc)
 {
+	struct sna *sna = to_sna(crtc->scrn);
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 	uint16_t *gamma;
+	int size;
+
+	assert(sna_crtc);
+
+	size = sna_crtc->gamma_lut_size;
+	if (!size)
+		size = 256;
 
 	/* Initialize the gamma ramps */
 	gamma = NULL;
-	if (crtc->gamma_size == 256)
+	if (crtc->gamma_size == size)
 		gamma = crtc->gamma_red;
 	if (gamma == NULL)
-		gamma = malloc(3 * 256 * sizeof(uint16_t));
+		gamma = malloc(3 * size * sizeof(uint16_t));
 	if (gamma) {
-		struct sna *sna = to_sna(crtc->scrn);
-		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 		struct drm_mode_crtc_lut lut;
-		bool gamma_set = false;
-
-		assert(sna_crtc);
-
-		lut.crtc_id = __sna_crtc_id(sna_crtc);
-		lut.gamma_size = 256;
-		lut.red = (uintptr_t)(gamma);
-		lut.green = (uintptr_t)(gamma + 256);
-		lut.blue = (uintptr_t)(gamma + 2 * 256);
-		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) {
-			VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0])));
-			gamma_set =
-				gamma[256 - 1] &&
-				gamma[2*256 - 1] &&
-				gamma[3*256 - 1];
-		}
+		bool gamma_set;
+		uint16_t *red = gamma;
+		uint16_t *green = gamma + size;
+		uint16_t *blue = gamma + 2 * size;
+
+		if (sna_crtc->gamma_lut_size)
+			gamma_set = crtc_get_gamma_lut(crtc, red,
+						       green, blue, size);
+		else
+			gamma_set = crtc_get_gamma_legacy(crtc, red,
+							  green, blue, size);
 
 		DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
 		     __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
@@ -7311,19 +7478,21 @@ static void crtc_init_gamma(xf86CrtcPtr crtc)
 		if (!gamma_set) {
 			int i;
 
-			for (i = 0; i < 256; i++) {
-				gamma[i] = i << 8;
-				gamma[256 + i] = i << 8;
-				gamma[2*256 + i] = i << 8;
+			for (i = 0; i < size; i++) {
+				uint16_t val = i * 0xffff / (size - 1);
+
+				red[i] = val;
+				green[i] = val;
+				blue[i] = val;
 			}
 		}
 
-		if (gamma != crtc->gamma_red) {
+		if (red != crtc->gamma_red) {
 			free(crtc->gamma_red);
-			crtc->gamma_red = gamma;
-			crtc->gamma_green = gamma + 256;
-			crtc->gamma_blue = gamma + 2*256;
-			crtc->gamma_size = 256;
+			crtc->gamma_red = red;
+			crtc->gamma_green = green;
+			crtc->gamma_blue = blue;
+			crtc->gamma_size = size;
 		}
 	}
 }
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH xf86-video-intel v3 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-05-17 13:51   ` [PATCH xf86-video-intel v3 " Ville Syrjala
@ 2019-07-09 18:34     ` Mario Kleiner
  2019-07-10 11:59       ` Chris Wilson
  0 siblings, 1 reply; 11+ messages in thread
From: Mario Kleiner @ 2019-07-09 18:34 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

Hi Ville,

now somebody just needs to merge these two 10 bit gamma lut patches
into intel-ddx?

thanks,
-mario

On Fri, May 17, 2019 at 3:51 PM Ville Syrjala
<ville.syrjala@linux.intel.com> wrote:
>
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Probe the GAMMA_LUT/GAMMA_LUT_SIZE props and utilize them when
> the running with > 8bpc.
>
> v2: s/sna_crtc_id/__sna_crtc_id/ in DBG since we have a sna_crtc
> v3: Fix the vg "bluered" typo (Mario)
>     This time I even build tested with vg support
>
> Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
> ---
>  src/sna/sna_display.c | 247 +++++++++++++++++++++++++++++++++++-------
>  1 file changed, 208 insertions(+), 39 deletions(-)
>
> diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
> index 41edfec12839..d6210cc7bbc8 100644
> --- a/src/sna/sna_display.c
> +++ b/src/sna/sna_display.c
> @@ -127,6 +127,7 @@ struct local_mode_obj_get_properties {
>         uint32_t obj_type;
>         uint32_t pad;
>  };
> +#define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
>  #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
>
>  struct local_mode_set_plane {
> @@ -229,6 +230,11 @@ struct sna_crtc {
>         } primary;
>         struct list sprites;
>
> +       struct drm_color_lut *gamma_lut;
> +       uint64_t gamma_lut_prop;
> +       uint64_t gamma_lut_blob;
> +       uint32_t gamma_lut_size;
> +
>         uint32_t mode_serial, flip_serial;
>
>         uint32_t last_seq, wrap_seq;
> @@ -317,6 +323,9 @@ static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
>  static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
>  static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
>                           struct kgem_bo *bo, int x, int y);
> +static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
> +                              CARD16 *red, CARD16 *green,
> +                              CARD16 *blue, int size);
>
>  static bool is_zaphod(ScrnInfoPtr scrn)
>  {
> @@ -3150,11 +3159,9 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
>                mode->VDisplay <= sna->mode.max_crtc_height);
>
>  #if HAS_GAMMA
> -       drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc),
> -                           crtc->gamma_size,
> -                           crtc->gamma_red,
> -                           crtc->gamma_green,
> -                           crtc->gamma_blue);
> +       sna_crtc_gamma_set(crtc,
> +                          crtc->gamma_red, crtc->gamma_green,
> +                          crtc->gamma_blue, crtc->gamma_size);
>  #endif
>
>         saved_kmode = sna_crtc->kmode;
> @@ -3212,12 +3219,44 @@ void sna_mode_adjust_frame(struct sna *sna, int x, int y)
>
>  static void
>  sna_crtc_gamma_set(xf86CrtcPtr crtc,
> -                      CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> +                  CARD16 *red, CARD16 *green, CARD16 *blue, int size)
>  {
> -       assert(to_sna_crtc(crtc));
> -       drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
> -                           sna_crtc_id(crtc),
> -                           size, red, green, blue);
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> +       struct drm_color_lut *lut = sna_crtc->gamma_lut;
> +       uint32_t blob_size = size * sizeof(lut[0]);
> +       uint32_t blob_id;
> +       int ret, i;
> +
> +       DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
> +
> +       if (!lut) {
> +               assert(size == 256);
> +
> +               drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
> +                                   sna_crtc_id(crtc),
> +                                   size, red, green, blue);
> +               return;
> +       }
> +
> +       assert(size == sna_crtc->gamma_lut_size);
> +
> +       for (i = 0; i < size; i++) {
> +               lut[i].red = red[i];
> +               lut[i].green = green[i];
> +               lut[i].blue = blue[i];
> +       }
> +
> +       ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
> +       if (ret)
> +               return;
> +
> +       ret = drmModeObjectSetProperty(sna->kgem.fd,
> +                                      sna_crtc->id, DRM_MODE_OBJECT_CRTC,
> +                                      sna_crtc->gamma_lut_prop,
> +                                      blob_id);
> +
> +       drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
>  }
>
>  static void
> @@ -3229,6 +3268,8 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
>         if (sna_crtc == NULL)
>                 return;
>
> +       free(sna_crtc->gamma_lut);
> +
>         list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
>                 free(sprite);
>
> @@ -3663,6 +3704,55 @@ bool sna_has_sprite_format(struct sna *sna, uint32_t format)
>         return false;
>  }
>
> +inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
> +{
> +       return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
> +}
> +
> +inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
> +{
> +       return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
> +}
> +
> +static void sna_crtc_parse_prop(struct sna *sna,
> +                               struct drm_mode_get_property *prop,
> +                               uint64_t value, void *data)
> +{
> +       struct sna_crtc *crtc = data;
> +
> +       if (prop_is_gamma_lut(prop)) {
> +               crtc->gamma_lut_prop = prop->prop_id;
> +               crtc->gamma_lut_blob = value;
> +       } else if (prop_is_gamma_lut_size(prop)) {
> +               crtc->gamma_lut_size = value;
> +       }
> +}
> +
> +static void
> +sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
> +{
> +       ScrnInfoPtr scrn = sna->scrn;
> +
> +       parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
> +                   sna_crtc_parse_prop, crtc);
> +
> +       /* use high precision gamma LUT for > 8bpc */
> +       /* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
> +       if (scrn->rgbBits <= 8 ||
> +           XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
> +               crtc->gamma_lut_size = 0;
> +
> +       if (crtc->gamma_lut_size) {
> +               crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
> +                                        sizeof(crtc->gamma_lut[0]));
> +               if (!crtc->gamma_lut)
> +                       crtc->gamma_lut_size = 0;
> +       }
> +
> +       DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
> +            __sna_crtc_id(crtc), crtc->gamma_lut_size));
> +}
> +
>  static void
>  sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
>  {
> @@ -3723,6 +3813,9 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
>
>         list_init(&sna_crtc->sprites);
>         sna_crtc_init__rotation(sna, sna_crtc);
> +
> +       sna_crtc_init__props(sna, sna_crtc);
> +
>         sna_crtc_find_planes(sna, sna_crtc);
>
>         DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
> @@ -7274,36 +7367,110 @@ static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
>                           mon->mon_gamma_blue);
>  }
>
> +static bool
> +crtc_get_gamma_lut(xf86CrtcPtr crtc,
> +                  CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> +{
> +
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> +       struct drm_color_lut *lut = sna_crtc->gamma_lut;
> +       struct drm_mode_get_blob blob;
> +       int lut_size, i;
> +
> +       DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
> +
> +       memset(&blob, 0, sizeof(blob));
> +       blob.blob_id = sna_crtc->gamma_lut_blob;
> +
> +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
> +               return false;
> +
> +       lut_size = blob.length / sizeof(lut[0]);
> +
> +       if (lut_size == 0 ||
> +           lut_size > max(sna_crtc->gamma_lut_size, 256))
> +               return false;
> +
> +       blob.data = (uintptr_t)lut;
> +
> +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
> +               return false;
> +
> +       for (i = 0; i < size; i++) {
> +               struct drm_color_lut *entry =
> +                       &lut[i * (lut_size - 1) / (size - 1)];
> +
> +               red[i] = entry->red;
> +               green[i] = entry->green;
> +               blue[i] = entry->blue;
> +       }
> +
> +       return red[size - 1] &&
> +               green[size - 1] &&
> +               blue[size - 1];
> +}
> +
> +static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
> +                                 CARD16 *red,
> +                                 CARD16 *green,
> +                                 CARD16 *blue,
> +                                 int size)
> +{
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
> +       struct drm_mode_crtc_lut lut = {
> +               .crtc_id = __sna_crtc_id(sna_crtc),
> +               .gamma_size = size,
> +               .red = (uintptr_t)red,
> +               .green = (uintptr_t)green,
> +               .blue = (uintptr_t)blue,
> +       };
> +
> +       if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
> +               return false;
> +
> +       VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
> +       VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
> +       VG(VALGRIND_MAKE_MEM_DEFINED(blue, size*sizeof(blue[0])));
> +
> +       return red[size - 1] &&
> +               green[size - 1] &&
> +               blue[size - 1];
> +}
> +
>  static void crtc_init_gamma(xf86CrtcPtr crtc)
>  {
> +       struct sna *sna = to_sna(crtc->scrn);
> +       struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
>         uint16_t *gamma;
> +       int size;
> +
> +       assert(sna_crtc);
> +
> +       size = sna_crtc->gamma_lut_size;
> +       if (!size)
> +               size = 256;
>
>         /* Initialize the gamma ramps */
>         gamma = NULL;
> -       if (crtc->gamma_size == 256)
> +       if (crtc->gamma_size == size)
>                 gamma = crtc->gamma_red;
>         if (gamma == NULL)
> -               gamma = malloc(3 * 256 * sizeof(uint16_t));
> +               gamma = malloc(3 * size * sizeof(uint16_t));
>         if (gamma) {
> -               struct sna *sna = to_sna(crtc->scrn);
> -               struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
>                 struct drm_mode_crtc_lut lut;
> -               bool gamma_set = false;
> -
> -               assert(sna_crtc);
> -
> -               lut.crtc_id = __sna_crtc_id(sna_crtc);
> -               lut.gamma_size = 256;
> -               lut.red = (uintptr_t)(gamma);
> -               lut.green = (uintptr_t)(gamma + 256);
> -               lut.blue = (uintptr_t)(gamma + 2 * 256);
> -               if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) {
> -                       VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0])));
> -                       gamma_set =
> -                               gamma[256 - 1] &&
> -                               gamma[2*256 - 1] &&
> -                               gamma[3*256 - 1];
> -               }
> +               bool gamma_set;
> +               uint16_t *red = gamma;
> +               uint16_t *green = gamma + size;
> +               uint16_t *blue = gamma + 2 * size;
> +
> +               if (sna_crtc->gamma_lut_size)
> +                       gamma_set = crtc_get_gamma_lut(crtc, red,
> +                                                      green, blue, size);
> +               else
> +                       gamma_set = crtc_get_gamma_legacy(crtc, red,
> +                                                         green, blue, size);
>
>                 DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
>                      __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
> @@ -7311,19 +7478,21 @@ static void crtc_init_gamma(xf86CrtcPtr crtc)
>                 if (!gamma_set) {
>                         int i;
>
> -                       for (i = 0; i < 256; i++) {
> -                               gamma[i] = i << 8;
> -                               gamma[256 + i] = i << 8;
> -                               gamma[2*256 + i] = i << 8;
> +                       for (i = 0; i < size; i++) {
> +                               uint16_t val = i * 0xffff / (size - 1);
> +
> +                               red[i] = val;
> +                               green[i] = val;
> +                               blue[i] = val;
>                         }
>                 }
>
> -               if (gamma != crtc->gamma_red) {
> +               if (red != crtc->gamma_red) {
>                         free(crtc->gamma_red);
> -                       crtc->gamma_red = gamma;
> -                       crtc->gamma_green = gamma + 256;
> -                       crtc->gamma_blue = gamma + 2*256;
> -                       crtc->gamma_size = 256;
> +                       crtc->gamma_red = red;
> +                       crtc->gamma_green = green;
> +                       crtc->gamma_blue = blue;
> +                       crtc->gamma_size = size;
>                 }
>         }
>  }
> --
> 2.21.0
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH xf86-video-intel v3 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
  2019-07-09 18:34     ` Mario Kleiner
@ 2019-07-10 11:59       ` Chris Wilson
  0 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2019-07-10 11:59 UTC (permalink / raw)
  To: Mario Kleiner, Ville Syrjala; +Cc: intel-gfx

Quoting Mario Kleiner (2019-07-09 19:34:54)
> Hi Ville,
> 
> now somebody just needs to merge these two 10 bit gamma lut patches
> into intel-ddx?

And so it is done. Thank you,
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-07-10 11:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-18 19:50 [PATCH xf86-video-intel 1/2] sna: Refactor property parsing Ville Syrjala
2019-02-18 19:50 ` [PATCH xf86-video-intel 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property Ville Syrjala
2019-03-01 13:13   ` Chris Wilson
2019-04-26 16:32   ` [PATCH xf86-video-intel v2 " Ville Syrjala
2019-05-16 19:54     ` Mario Kleiner
2019-05-17 13:49       ` Ville Syrjälä
2019-05-17 13:51   ` [PATCH xf86-video-intel v3 " Ville Syrjala
2019-07-09 18:34     ` Mario Kleiner
2019-07-10 11:59       ` Chris Wilson
2019-04-26 16:32 ` [PATCH xf86-video-intel v2 1/2] sna: Refactor property parsing Ville Syrjala
2019-05-16 19:39   ` Mario Kleiner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.