All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH xf86-video-intel v2 2/2] sna: Support 10bpc gamma via the GAMMA_LUT crtc property
Date: Fri, 17 May 2019 16:49:07 +0300	[thread overview]
Message-ID: <20190517134907.GQ24299@intel.com> (raw)
In-Reply-To: <CAEsyxyi-UmW7J9WDVFnY7kUua1DXizN7F5JR-AhCfQN-bOdmiQ@mail.gmail.com>

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

  reply	other threads:[~2019-05-17 13:49 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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ä [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190517134907.GQ24299@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=mario.kleiner.de@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.