[Mesa-dev] [PATCH v2] st/dri: add 32-bit RGBX/RGBA formats

Marek Olšák maraeo at gmail.com
Fri Jul 28 14:59:15 UTC 2017


Hi,

I've sent a request to revert this commit in 17.2. I'll keep it in
master, but I'll add a fix not to expose the new formats for GLX.

Marek

On Tue, Jul 11, 2017 at 10:34 PM, Rob Herring <robh at kernel.org> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Add support for 32-bit RGBX/RGBA formats which are required for Android.
>
> The original patch (commit ccdcf91104a5) was reverted (commit
> c0c6ca40a25e) in mesa as it broke GLX resulting in swapped colors. Based
> on further investigation by Chad Versace, moving the RGBX/RGBA configs
> to the end is enough to prevent breaking GLX.
>
> The handling of RGBA/RGBX in dri_fill_st_visual is a fix from Marek
> Olšák.
>
> Cc: Eric Anholt <eric at anholt.net>
> Cc: Chad Versace <chadversary at chromium.org>
> Cc: Mauro Rossi <issor.oruam at gmail.com>
> Reviewed-by: Marek Olšák <marek.olsak at amd.com>
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
> v2:
> - Incorporated dri_fill_st_visual RGBA/X handling from Marek
> - Handle RGBA/X in dri2_drawable_get_buffers for completeness
>
>  src/gallium/state_trackers/dri/dri2.c       |  8 ++++
>  src/gallium/state_trackers/dri/dri_screen.c | 69 ++++++++++++++++++++++++-----
>  2 files changed, 65 insertions(+), 12 deletions(-)
>
> diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
> index 60ec38d8e445..e20b2c075361 100644
> --- a/src/gallium/state_trackers/dri/dri2.c
> +++ b/src/gallium/state_trackers/dri/dri2.c
> @@ -186,6 +186,9 @@ static enum pipe_format dri2_format_to_pipe_format (int format)
>     case __DRI_IMAGE_FORMAT_ARGB8888:
>        pf = PIPE_FORMAT_BGRA8888_UNORM;
>        break;
> +   case __DRI_IMAGE_FORMAT_XBGR8888:
> +      pf = PIPE_FORMAT_RGBX8888_UNORM;
> +      break;
>     case __DRI_IMAGE_FORMAT_ABGR8888:
>        pf = PIPE_FORMAT_RGBA8888_UNORM;
>        break;
> @@ -356,9 +359,11 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
>         */
>        switch(format) {
>        case PIPE_FORMAT_BGRA8888_UNORM:
> +      case PIPE_FORMAT_RGBA8888_UNORM:
>          depth = 32;
>          break;
>        case PIPE_FORMAT_BGRX8888_UNORM:
> +      case PIPE_FORMAT_RGBX8888_UNORM:
>          depth = 24;
>          break;
>        case PIPE_FORMAT_B5G6R5_UNORM:
> @@ -434,6 +439,9 @@ dri_image_drawable_get_buffers(struct dri_drawable *drawable,
>        case PIPE_FORMAT_BGRA8888_UNORM:
>           image_format = __DRI_IMAGE_FORMAT_ARGB8888;
>           break;
> +      case PIPE_FORMAT_RGBX8888_UNORM:
> +         image_format = __DRI_IMAGE_FORMAT_XBGR8888;
> +         break;
>        case PIPE_FORMAT_RGBA8888_UNORM:
>           image_format = __DRI_IMAGE_FORMAT_ABGR8888;
>           break;
> diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
> index 6b58830e0b42..a0d9b34d667b 100644
> --- a/src/gallium/state_trackers/dri/dri_screen.c
> +++ b/src/gallium/state_trackers/dri/dri_screen.c
> @@ -132,6 +132,27 @@ dri_fill_in_modes(struct dri_screen *screen)
>        MESA_FORMAT_B8G8R8A8_SRGB,
>        MESA_FORMAT_B8G8R8X8_SRGB,
>        MESA_FORMAT_B5G6R5_UNORM,
> +
> +      /* The 32-bit RGBA format must not precede the 32-bit BGRA format.
> +       * Likewise for RGBX and BGRX.  Otherwise, the GLX client and the GLX
> +       * server may disagree on which format the GLXFBConfig represents,
> +       * resulting in swapped color channels.
> +       *
> +       * The problem, as of 2017-05-30:
> +       * When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel
> +       * order and chooses the first __DRIconfig with the expected channel
> +       * sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's
> +       * __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK.
> +       *
> +       * EGL does not suffer from this problem. It correctly compares the
> +       * channel masks when matching EGLConfig to __DRIconfig.
> +       */
> +
> +      /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */
> +      MESA_FORMAT_R8G8B8A8_UNORM,
> +
> +      /* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */
> +      MESA_FORMAT_R8G8B8X8_UNORM,
>     };
>     static const enum pipe_format pipe_formats[] = {
>        PIPE_FORMAT_BGRA8888_UNORM,
> @@ -139,6 +160,8 @@ dri_fill_in_modes(struct dri_screen *screen)
>        PIPE_FORMAT_BGRA8888_SRGB,
>        PIPE_FORMAT_BGRX8888_SRGB,
>        PIPE_FORMAT_B5G6R5_UNORM,
> +      PIPE_FORMAT_RGBA8888_UNORM,
> +      PIPE_FORMAT_RGBX8888_UNORM,
>     };
>     mesa_format format;
>     __DRIconfig **configs = NULL;
> @@ -275,19 +298,41 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
>     if (!mode)
>        return;
>
> -   if (mode->redBits == 8) {
> -      if (mode->alphaBits == 8)
> -         if (mode->sRGBCapable)
> -            stvis->color_format = PIPE_FORMAT_BGRA8888_SRGB;
> -         else
> -            stvis->color_format = PIPE_FORMAT_BGRA8888_UNORM;
> -      else
> -         if (mode->sRGBCapable)
> -            stvis->color_format = PIPE_FORMAT_BGRX8888_SRGB;
> -         else
> -            stvis->color_format = PIPE_FORMAT_BGRX8888_UNORM;
> -   } else {
> +   /* Deduce the color format. */
> +   switch (mode->redMask) {
> +   case 0x00FF0000:
> +      if (mode->alphaMask) {
> +         assert(mode->alphaMask == 0xFF000000);
> +         stvis->color_format = mode->sRGBCapable ?
> +                                  PIPE_FORMAT_BGRA8888_SRGB :
> +                                  PIPE_FORMAT_BGRA8888_UNORM;
> +      } else {
> +         stvis->color_format = mode->sRGBCapable ?
> +                                  PIPE_FORMAT_BGRX8888_SRGB :
> +                                  PIPE_FORMAT_BGRX8888_UNORM;
> +      }
> +      break;
> +
> +   case 0x000000FF:
> +      if (mode->alphaMask) {
> +         assert(mode->alphaMask == 0xFF000000);
> +         stvis->color_format = mode->sRGBCapable ?
> +                                  PIPE_FORMAT_RGBA8888_SRGB :
> +                                  PIPE_FORMAT_RGBA8888_UNORM;
> +      } else {
> +         stvis->color_format = mode->sRGBCapable ?
> +                                  PIPE_FORMAT_RGBX8888_SRGB :
> +                                  PIPE_FORMAT_RGBX8888_UNORM;
> +      }
> +      break;
> +
> +   case 0x0000F800:
>        stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;
> +      break;
> +
> +   default:
> +      assert(!"unsupported visual: invalid red mask");
> +      return;
>     }
>
>     if (mode->sampleBuffers) {
> --
> 2.11.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list