X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fdrivers%2Fdri2%2Fplatform_x11_dri3.c;h=c1efa93015921e673dd7c7a49f418b991be022ad;hb=069fdd5f9facbd72fb6a289696c7b74e3237e70f;hp=6ead4d0a22209e48cbda5e2b4e72dcb54ef743d9;hpb=aad14cf15ac3b9d2d42e9db24cc7b4fd53ed25b4;p=mesa.git diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index 6ead4d0a222..c1efa930159 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -39,6 +39,23 @@ #include "loader.h" #include "loader_dri3_helper.h" +static uint32_t +dri3_format_for_depth(uint32_t depth) +{ + switch (depth) { + case 16: + return __DRI_IMAGE_FORMAT_RGB565; + case 24: + return __DRI_IMAGE_FORMAT_XRGB8888; + case 30: + return __DRI_IMAGE_FORMAT_XRGB2101010; + case 32: + return __DRI_IMAGE_FORMAT_ARGB8888; + default: + return __DRI_IMAGE_FORMAT_NONE; + } +} + static struct dri3_egl_surface * loader_drawable_to_egl_surface(struct loader_dri3_drawable *draw) { size_t offset = offsetof(struct dri3_egl_surface, loader_drawable); @@ -75,6 +92,17 @@ egl_dri3_get_dri_context(struct loader_dri3_drawable *draw) return dri2_ctx->dri_context; } +static __DRIscreen * +egl_dri3_get_dri_screen(void) +{ + _EGLContext *ctx = _eglGetCurrentContext(); + struct dri2_egl_context *dri2_ctx; + if (!ctx) + return NULL; + dri2_ctx = dri2_egl_context(ctx); + return dri2_egl_display(dri2_ctx->base.Resource.Display)->dri_screen; +} + static void egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags) { @@ -88,6 +116,7 @@ static const struct loader_dri3_vtable egl_dri3_vtable = { .set_drawable_size = egl_dri3_set_drawable_size, .in_current_context = egl_dri3_in_current_context, .get_dri_context = egl_dri3_get_dri_context, + .get_dri_screen = egl_dri3_get_dri_screen, .flush_drawable = egl_dri3_flush_drawable, .show_fps = NULL, }; @@ -156,7 +185,9 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, if (loader_dri3_drawable_init(dri2_dpy->conn, drawable, dri2_dpy->dri_screen, - dri2_dpy->is_different_gpu, dri_config, + dri2_dpy->is_different_gpu, + dri2_dpy->multibuffers_available, + dri_config, &dri2_dpy->loader_dri3_ext, &egl_dri3_vtable, &dri3_surf->loader_drawable)) { @@ -262,20 +293,8 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, return NULL; } - switch (bp_reply->depth) { - case 16: - format = __DRI_IMAGE_FORMAT_RGB565; - break; - case 24: - format = __DRI_IMAGE_FORMAT_XRGB8888; - break; - case 30: - format = __DRI_IMAGE_FORMAT_XRGB2101010; - break; - case 32: - format = __DRI_IMAGE_FORMAT_ARGB8888; - break; - default: + format = dri3_format_for_depth(bp_reply->depth); + if (format == __DRI_IMAGE_FORMAT_NONE) { _eglError(EGL_BAD_PARAMETER, "dri3_create_image_khr: unsupported pixmap depth"); free(bp_reply); @@ -303,13 +322,74 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, return &dri2_img->base; } +static _EGLImage * +dri3_create_image_khr_pixmap_from_buffers(_EGLDisplay *disp, _EGLContext *ctx, + EGLClientBuffer buffer, + const EGLint *attr_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_image *dri2_img; + xcb_dri3_buffers_from_pixmap_cookie_t bp_cookie; + xcb_dri3_buffers_from_pixmap_reply_t *bp_reply; + xcb_drawable_t drawable; + unsigned int format; + + drawable = (xcb_drawable_t) (uintptr_t) buffer; + bp_cookie = xcb_dri3_buffers_from_pixmap(dri2_dpy->conn, drawable); + bp_reply = xcb_dri3_buffers_from_pixmap_reply(dri2_dpy->conn, + bp_cookie, NULL); + + if (!bp_reply) { + _eglError(EGL_BAD_ATTRIBUTE, "dri3_create_image_khr"); + return EGL_NO_IMAGE_KHR; + } + + format = dri3_format_for_depth(bp_reply->depth); + if (format == __DRI_IMAGE_FORMAT_NONE) { + _eglError(EGL_BAD_PARAMETER, + "dri3_create_image_khr: unsupported pixmap depth"); + free(bp_reply); + return EGL_NO_IMAGE_KHR; + } + + dri2_img = malloc(sizeof *dri2_img); + if (!dri2_img) { + _eglError(EGL_BAD_ALLOC, "dri3_create_image_khr"); + free(bp_reply); + return EGL_NO_IMAGE_KHR; + } + + _eglInitImage(&dri2_img->base, disp); + + dri2_img->dri_image = loader_dri3_create_image_from_buffers(dri2_dpy->conn, + bp_reply, + format, + dri2_dpy->dri_screen, + dri2_dpy->image, + dri2_img); + free(bp_reply); + + if (!dri2_img->dri_image) { + _eglError(EGL_BAD_ATTRIBUTE, "dri3_create_image_khr"); + free(dri2_img); + return EGL_NO_IMAGE_KHR; + } + + return &dri2_img->base; +} + static _EGLImage * dri3_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) { + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + switch (target) { case EGL_NATIVE_PIXMAP_KHR: + if (dri2_dpy->multibuffers_available) + return dri3_create_image_khr_pixmap_from_buffers(disp, ctx, buffer, + attr_list); return dri3_create_image_khr_pixmap(disp, ctx, buffer, attr_list); default: return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list); @@ -471,6 +551,9 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy) free(error); return EGL_FALSE; } + + dri2_dpy->dri3_major_version = dri3_query->major_version; + dri2_dpy->dri3_minor_version = dri3_query->minor_version; free(dri3_query); present_query =