[Mesa-dev] [PATCH 3/5] egl/x11: Handle both depth 30 formats for eglCreateImage(). (v3)

Eric Engestrom eric.engestrom at intel.com
Mon May 21 14:19:59 UTC 2018


On Saturday, 2018-05-19 05:32:40 +0200, Mario Kleiner wrote:
> We need to distinguish if the backing storage of a pixmap
> is XRGB2101010 or XBGR2101010, as different gpu hw supports
> different formats. NVidia hw prefers XBGR, whereas AMD and
> Intel are happy with XRGB.
> 
> Use the red channel mask of the first depth 30 visual of
> the x-screen to distinguish which hw format to choose.
> 
> This fixes desktop composition of color depth 30 windows
> when the X11 compositor uses EGL.
> 
> v2: Switch from using the visual of the root window to simply
>     using the first depth 30 visual for the x-screen, as testing
>     shows that each driver only exports either xrgb ordering or
>     xbgr ordering for the channel masks of its depth 30 visuals,
>     so this should be unambiguous and avoid trouble if X ever
>     supports depth 30 pixmaps on screens with a non-depth 30 root
>     window visual. This per Michels suggestion.
> 
> v3: No change to v2, but spent some time testing this more on
>     AMD hw, with my software hacked up to intentionally choose
>     pixel formats/visual with the non-preferred xBGR2101010
>     ordering on the ati-ddx, also with a standard non-OpenGL
>     X-Window with depth 30 visual, to make sure that things show
>     up properly with the right colors on the screen when going
>     through EGL+OpenGL based compositing on KDE-5. Iow. to confirm
>     that my explanation to the v2 patch on the mailing list of why
>     it should work and the actual practice agree (or possibly that
>     i am good at fooling myself during testing ;).
> 
> Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
> Cc: Michel Dänzer <michel.daenzer at amd.com>
> ---
>  src/egl/drivers/dri2/egl_dri2.h          |  7 +++++++
>  src/egl/drivers/dri2/platform_x11.c      | 36 +++++++++++++++++++++++++++++++-
>  src/egl/drivers/dri2/platform_x11_dri3.c | 12 +++++++----
>  3 files changed, 50 insertions(+), 5 deletions(-)
> 
> diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
> index adabc527f8..7e7032d989 100644
> --- a/src/egl/drivers/dri2/egl_dri2.h
> +++ b/src/egl/drivers/dri2/egl_dri2.h
> @@ -413,6 +413,8 @@ EGLBoolean
>  dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp);
>  void
>  dri2_teardown_x11(struct dri2_egl_display *dri2_dpy);
> +unsigned int
> +dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth);
>  #else
>  static inline EGLBoolean
>  dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
> @@ -421,6 +423,11 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
>  }
>  static inline void
>  dri2_teardown_x11(struct dri2_egl_display *dri2_dpy) {}
> +static inline unsigned int
> +dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth)
> +{
> +   return 0;
> +}
>  #endif
>  
>  #ifdef HAVE_DRM_PLATFORM
> diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
> index 7aca0a9020..aabae02adb 100644
> --- a/src/egl/drivers/dri2/platform_x11.c
> +++ b/src/egl/drivers/dri2/platform_x11.c
> @@ -209,6 +209,36 @@ get_xcb_screen(xcb_screen_iterator_t iter, int screen)
>      return NULL;
>  }
>  
> +static xcb_visualtype_t *
> +get_xcb_visualtype_for_depth(struct dri2_egl_display *dri2_dpy, int depth)
> +{
> +   xcb_visualtype_iterator_t visual_iter;
> +   xcb_screen_t *screen = dri2_dpy->screen;
> +   xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen);
> +
> +   for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
> +      if (depth_iter.data->depth != depth)
> +         continue;
> +
> +      visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
> +      if (visual_iter.rem)
> +         return visual_iter.data;
> +   }
> +
> +   return NULL;
> +}
> +
> +/* Get red channel mask for given depth. */
> +unsigned int
> +dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth)
> +{
> +   unsigned int red_mask = 0;
> +   xcb_visualtype_t *visual = get_xcb_visualtype_for_depth(dri2_dpy, depth);
> +   if (visual)
> +      red_mask = visual->red_mask;
> +
> +   return red_mask;

Nit: drop the local `red_mask` and just `return visual->red_mask`/`return 0`

Reviewed-by: Eric Engestrom <eric.engestrom at intel.com>

> +}
>  
>  /**
>   * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
> @@ -1058,7 +1088,11 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
>        format = __DRI_IMAGE_FORMAT_XRGB8888;
>        break;
>     case 30:
> -      format = __DRI_IMAGE_FORMAT_XRGB2101010;
> +      /* Different preferred formats for different hw */
> +      if (dri2_x11_get_red_mask_for_depth(dri2_dpy, 30) == 0x3ff)
> +         format = __DRI_IMAGE_FORMAT_XBGR2101010;
> +      else
> +         format = __DRI_IMAGE_FORMAT_XRGB2101010;
>        break;
>     case 32:
>        format = __DRI_IMAGE_FORMAT_ARGB8888;
> diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
> index 5cb6d65c0a..9525b20158 100644
> --- a/src/egl/drivers/dri2/platform_x11_dri3.c
> +++ b/src/egl/drivers/dri2/platform_x11_dri3.c
> @@ -40,7 +40,7 @@
>  #include "loader_dri3_helper.h"
>  
>  static uint32_t
> -dri3_format_for_depth(uint32_t depth)
> +dri3_format_for_depth(struct dri2_egl_display *dri2_dpy, uint32_t depth)
>  {
>     switch (depth) {
>     case 16:
> @@ -48,7 +48,11 @@ dri3_format_for_depth(uint32_t depth)
>     case 24:
>        return __DRI_IMAGE_FORMAT_XRGB8888;
>     case 30:
> -      return __DRI_IMAGE_FORMAT_XRGB2101010;
> +      /* Different preferred formats for different hw */
> +      if (dri2_x11_get_red_mask_for_depth(dri2_dpy, 30) == 0x3ff)
> +         return __DRI_IMAGE_FORMAT_XBGR2101010;
> +      else
> +         return __DRI_IMAGE_FORMAT_XRGB2101010;
>     case 32:
>        return __DRI_IMAGE_FORMAT_ARGB8888;
>     default:
> @@ -298,7 +302,7 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
>        return NULL;
>     }
>  
> -   format = dri3_format_for_depth(bp_reply->depth);
> +   format = dri3_format_for_depth(dri2_dpy, bp_reply->depth);
>     if (format == __DRI_IMAGE_FORMAT_NONE) {
>        _eglError(EGL_BAD_PARAMETER,
>                  "dri3_create_image_khr: unsupported pixmap depth");
> @@ -350,7 +354,7 @@ dri3_create_image_khr_pixmap_from_buffers(_EGLDisplay *disp, _EGLContext *ctx,
>        return EGL_NO_IMAGE_KHR;
>     }
>  
> -   format = dri3_format_for_depth(bp_reply->depth);
> +   format = dri3_format_for_depth(dri2_dpy, bp_reply->depth);
>     if (format == __DRI_IMAGE_FORMAT_NONE) {
>        _eglError(EGL_BAD_PARAMETER,
>                  "dri3_create_image_khr: unsupported pixmap depth");
> -- 
> 2.13.0.rc1.294.g07d810a77f
> 
> _______________________________________________
> 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