diff options
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.h | 7 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_x11.c | 44 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_x11_dri3.c | 4 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_x11_dri3.h | 2 |
4 files changed, 48 insertions, 9 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 5d8fbfa2356..f8001ec4b66 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -411,6 +411,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) @@ -419,6 +421,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 ea9b0cc6d6f..cfa5c4aa2bf 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -56,7 +56,7 @@ dri2_x11_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval); uint32_t -dri2_format_for_depth(uint32_t depth); +dri2_format_for_depth(struct dri2_egl_display *dri2_dpy, uint32_t depth); static void swrastCreateDrawable(struct dri2_egl_display * dri2_dpy, @@ -212,6 +212,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) +{ + xcb_visualtype_t *visual = get_xcb_visualtype_for_depth(dri2_dpy, depth); + + if (visual) + return visual->red_mask; + + return 0; +} /** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). @@ -1010,7 +1040,7 @@ dri2_x11_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, } uint32_t -dri2_format_for_depth(uint32_t depth) +dri2_format_for_depth(struct dri2_egl_display *dri2_dpy, uint32_t depth) { switch (depth) { case 16: @@ -1018,7 +1048,11 @@ dri2_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: @@ -1026,7 +1060,6 @@ dri2_format_for_depth(uint32_t depth) } } - static _EGLImage * dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, EGLClientBuffer buffer, const EGLint *attr_list) @@ -1071,8 +1104,7 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, return NULL; } - format = dri2_format_for_depth(geometry_reply->depth); - + format = dri2_format_for_depth(dri2_dpy, geometry_reply->depth); if (format == __DRI_IMAGE_FORMAT_NONE) { _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr: unsupported pixmap depth"); diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index 0d5a9d037f5..c3c9c2dd45d 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -281,7 +281,7 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, return NULL; } - format = dri2_format_for_depth(bp_reply->depth); + format = dri2_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"); @@ -333,7 +333,7 @@ dri3_create_image_khr_pixmap_from_buffers(_EGLDisplay *disp, _EGLContext *ctx, return EGL_NO_IMAGE_KHR; } - format = dri2_format_for_depth(bp_reply->depth); + format = dri2_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"); diff --git a/src/egl/drivers/dri2/platform_x11_dri3.h b/src/egl/drivers/dri2/platform_x11_dri3.h index e6fd0136697..f60d1df641a 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.h +++ b/src/egl/drivers/dri2/platform_x11_dri3.h @@ -39,6 +39,6 @@ EGLBoolean dri3_x11_connect(struct dri2_egl_display *dri2_dpy); uint32_t -dri2_format_for_depth(uint32_t depth); +dri2_format_for_depth(struct dri2_egl_display *dri2_dpy, uint32_t depth); #endif |