* [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.