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@xxxxxxxxxxxxxxx> wrote: > > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > 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@xxxxxxxxx> > Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@xxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx