diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 1353dfcf56f..3682d05be95 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -750,6 +750,7 @@ static const struct dri2_extension_match optional_core_extensions[] = { { __DRI2_FLUSH_CONTROL, 1, offsetof(struct dri2_egl_display, flush_control) }, { __DRI2_BLOB, 1, offsetof(struct dri2_egl_display, blob) }, { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1, offsetof(struct dri2_egl_display, mutable_render_buffer) }, + { __DRI_KOPPER, 1, offsetof(struct dri2_egl_display, kopper) }, { NULL, 0, 0 } }; @@ -1743,19 +1744,25 @@ dri2_create_drawable(struct dri2_egl_display *dri2_dpy, struct dri2_egl_surface *dri2_surf, void *loaderPrivate) { - __DRIcreateNewDrawableFunc createNewDrawable; + if (dri2_dpy->kopper) { + dri2_surf->dri_drawable = + dri2_dpy->kopper->createNewDrawable(dri2_dpy->dri_screen, config, loaderPrivate, + dri2_surf->base.Type == EGL_PBUFFER_BIT || + dri2_surf->base.Type == EGL_PIXMAP_BIT); + } else { + __DRIcreateNewDrawableFunc createNewDrawable; + if (dri2_dpy->image_driver) + createNewDrawable = dri2_dpy->image_driver->createNewDrawable; + else if (dri2_dpy->dri2) + createNewDrawable = dri2_dpy->dri2->createNewDrawable; + else if (dri2_dpy->swrast) + createNewDrawable = dri2_dpy->swrast->createNewDrawable; + else + return _eglError(EGL_BAD_ALLOC, "no createNewDrawable"); - if (dri2_dpy->image_driver) - createNewDrawable = dri2_dpy->image_driver->createNewDrawable; - else if (dri2_dpy->dri2) - createNewDrawable = dri2_dpy->dri2->createNewDrawable; - else if (dri2_dpy->swrast) - createNewDrawable = dri2_dpy->swrast->createNewDrawable; - else - return _eglError(EGL_BAD_ALLOC, "no createNewDrawable"); - - dri2_surf->dri_drawable = createNewDrawable(dri2_dpy->dri_screen, - config, loaderPrivate); + dri2_surf->dri_drawable = createNewDrawable(dri2_dpy->dri_screen, + config, loaderPrivate); + } if (dri2_surf->dri_drawable == NULL) return _eglError(EGL_BAD_ALLOC, "createNewDrawable"); diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index e7d3de0b04d..89158993efd 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -58,6 +58,7 @@ struct zwp_linux_dmabuf_feedback_v1; #include #include +#include "kopper_interface.h" #ifdef HAVE_DRM_PLATFORM #include @@ -221,6 +222,7 @@ struct dri2_egl_display const __DRIimageDriverExtension *image_driver; const __DRIdri2Extension *dri2; const __DRIswrastExtension *swrast; + const __DRIkopperExtension *kopper; const __DRI2flushExtension *flush; const __DRI2flushControlExtension *flush_control; const __DRItexBufferExtension *tex_buffer; diff --git a/src/egl/drivers/dri2/platform_device.c b/src/egl/drivers/dri2/platform_device.c index 30f6f7e6b8b..66b2eee08ee 100644 --- a/src/egl/drivers/dri2/platform_device.c +++ b/src/egl/drivers/dri2/platform_device.c @@ -41,6 +41,7 @@ #include "egl_dri2.h" #include "loader.h" +#include "kopper_interface.h" #include "util/debug.h" static __DRIimage* @@ -212,10 +213,17 @@ static const __DRIimageLoaderExtension image_loader_extension = { .getCapability = device_get_capability, }; +static const __DRIkopperLoaderExtension kopper_loader_extension = { + .base = { __DRI_KOPPER_LOADER, 1 }, + + .SetSurfaceCreateInfo = NULL, +}; + static const __DRIextension *image_loader_extensions[] = { &image_loader_extension.base, &image_lookup_extension.base, &use_invalidate.base, + &kopper_loader_extension.base, NULL, }; @@ -223,6 +231,7 @@ static const __DRIextension *swrast_loader_extensions[] = { &swrast_pbuffer_loader_extension.base, &image_lookup_extension.base, &use_invalidate.base, + &kopper_loader_extension.base, NULL, }; @@ -313,7 +322,7 @@ device_probe_device_sw(_EGLDisplay *disp) struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); dri2_dpy->fd = -1; - dri2_dpy->driver_name = strdup("swrast"); + dri2_dpy->driver_name = strdup(disp->Options.Zink ? "zink" : "swrast"); if (!dri2_dpy->driver_name) return false; diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 6aada724a54..45895a88b6c 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -749,6 +749,7 @@ dri2_initialize_drm(_EGLDisplay *disp) dri2_dpy->core = dri2_dpy->gbm_dri->core; dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2; dri2_dpy->swrast = dri2_dpy->gbm_dri->swrast; + dri2_dpy->kopper = dri2_dpy->gbm_dri->kopper; dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs; dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image; diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c index a420eb09ff6..df88c54cf84 100644 --- a/src/egl/drivers/dri2/platform_surfaceless.c +++ b/src/egl/drivers/dri2/platform_surfaceless.c @@ -35,6 +35,7 @@ #include "egl_dri2.h" #include "loader.h" +#include "kopper_interface.h" static __DRIimage* surfaceless_alloc_image(struct dri2_egl_display *dri2_dpy, @@ -199,6 +200,12 @@ surfaceless_get_capability(void *loaderPrivate, enum dri_loader_cap cap) } } +static const __DRIkopperLoaderExtension kopper_loader_extension = { + .base = { __DRI_KOPPER_LOADER, 1 }, + + .SetSurfaceCreateInfo = NULL, +}; + static const __DRIimageLoaderExtension image_loader_extension = { .base = { __DRI_IMAGE_LOADER, 2 }, .getBuffers = surfaceless_image_get_buffers, @@ -211,6 +218,7 @@ static const __DRIextension *image_loader_extensions[] = { &image_lookup_extension.base, &use_invalidate.base, &background_callable_extension.base, + &kopper_loader_extension.base, NULL, }; @@ -219,6 +227,7 @@ static const __DRIextension *swrast_loader_extensions[] = { &image_loader_extension.base, &image_lookup_extension.base, &use_invalidate.base, + &kopper_loader_extension.base, NULL, }; @@ -299,7 +308,7 @@ surfaceless_probe_device_sw(_EGLDisplay *disp) disp->Device = _eglAddDevice(dri2_dpy->fd, true); assert(disp->Device); - dri2_dpy->driver_name = strdup("swrast"); + dri2_dpy->driver_name = strdup(disp->Options.Zink ? "zink" : "swrast"); if (!dri2_dpy->driver_name) return false; diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 42bdb3b4b15..e9ecf6d1e71 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -45,6 +45,7 @@ #include "util/u_vector.h" #include "util/anon_file.h" #include "eglglobals.h" +#include "kopper_interface.h" #include #include @@ -2589,9 +2590,29 @@ static const __DRIswrastLoaderExtension swrast_loader_extension = { .putImage2 = dri2_wl_swrast_put_image2, }; +static void +kopperSetSurfaceCreateInfo(void *_draw, struct kopper_loader_info *out) +{ + struct dri2_egl_surface *dri2_surf = _draw; + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + VkWaylandSurfaceCreateInfoKHR *wlsci = &out->wl; + + wlsci->sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + wlsci->pNext = NULL; + wlsci->flags = 0; + wlsci->display = dri2_dpy->wl_dpy; + wlsci->surface = dri2_surf->wl_surface_wrapper; +} + +static const __DRIkopperLoaderExtension kopper_loader_extension = { + .base = { __DRI_KOPPER_LOADER, 1 }, + + .SetSurfaceCreateInfo = kopperSetSurfaceCreateInfo, +}; static const __DRIextension *swrast_loader_extensions[] = { &swrast_loader_extension.base, &image_lookup_extension.base, + &kopper_loader_extension.base, NULL, }; @@ -2651,7 +2672,7 @@ dri2_initialize_wayland_swrast(_EGLDisplay *disp) 0, dri2_dpy->formats.num_formats)) goto cleanup; - dri2_dpy->driver_name = strdup("swrast"); + dri2_dpy->driver_name = strdup(disp->Options.Zink ? "zink" : "swrast"); if (!dri2_load_driver_swrast(disp)) goto cleanup; diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index 5ffdf132184..576d47e4350 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -46,6 +46,7 @@ #include "egl_dri2.h" #include "loader.h" +#include "kopper_interface.h" #ifdef HAVE_DRI3 #include "platform_x11_dri3.h" @@ -286,9 +287,6 @@ dri2_x11_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, goto cleanup_pixmap; } - if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf)) - goto cleanup_pixmap; - if (type != EGL_PBUFFER_BIT) { cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); @@ -313,6 +311,9 @@ dri2_x11_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, free(reply); } + if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf)) + goto cleanup_pixmap; + if (dri2_dpy->dri2) { xcb_void_cookie_t cookie; int conn_error; @@ -1200,9 +1201,32 @@ static const __DRIswrastLoaderExtension swrast_loader_extension = { .getImage = swrastGetImage, }; +static void +kopperSetSurfaceCreateInfo(void *_draw, struct kopper_loader_info *ci) +{ + struct dri2_egl_surface *dri2_surf = _draw; + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + + if (dri2_surf->base.Type != EGL_WINDOW_BIT) + return; + ci->xcb.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + ci->xcb.pNext = NULL; + ci->xcb.flags = 0; + ci->xcb.connection = dri2_dpy->conn; + ci->xcb.window = dri2_surf->drawable; + ci->has_alpha = dri2_surf->depth == 32; +} + +static const __DRIkopperLoaderExtension kopper_loader_extension = { + .base = { __DRI_KOPPER_LOADER, 1 }, + + .SetSurfaceCreateInfo = kopperSetSurfaceCreateInfo, +}; + static const __DRIextension *swrast_loader_extensions[] = { &swrast_loader_extension.base, &image_lookup_extension.base, + &kopper_loader_extension.base, NULL, }; @@ -1266,6 +1290,28 @@ disconnect: return _eglError(EGL_BAD_ALLOC, msg); } +static void +dri2_x11_setup_swap_interval(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + int arbitrary_max_interval = 1000; + + /* default behavior for no SwapBuffers support: no vblank syncing + * either. + */ + dri2_dpy->min_swap_interval = 0; + dri2_dpy->max_swap_interval = 0; + dri2_dpy->default_swap_interval = 0; + + if (!dri2_dpy->swap_available) + return; + + /* If we do have swapbuffers, then we can support pretty much any swap + * interval. + */ + dri2_setup_swap_interval(disp, arbitrary_max_interval); +} + static EGLBoolean dri2_initialize_x11_swrast(_EGLDisplay *disp) { @@ -1292,7 +1338,7 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp) * Every hardware driver_name is set using strdup. Doing the same in * here will allow is to simply free the memory at dri2_terminate(). */ - dri2_dpy->driver_name = strdup("swrast"); + dri2_dpy->driver_name = strdup(disp->Options.Zink ? "zink" : "swrast"); if (!dri2_load_driver_swrast(disp)) goto cleanup; @@ -1306,6 +1352,21 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp) dri2_setup_screen(disp); + if (disp->Options.Zink) { +#ifdef HAVE_WAYLAND_PLATFORM + dri2_dpy->device_name = strdup("zink"); +#endif + dri2_x11_setup_swap_interval(disp); + if (!dri2_dpy->is_different_gpu) + disp->Extensions.KHR_image_pixmap = EGL_TRUE; + disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; + disp->Extensions.CHROMIUM_sync_control = EGL_TRUE; + disp->Extensions.EXT_buffer_age = EGL_TRUE; + disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE; + + //dri2_set_WL_bind_wayland_display(disp); + } + if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true)) goto cleanup; @@ -1321,28 +1382,6 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp) return EGL_FALSE; } -static void -dri2_x11_setup_swap_interval(_EGLDisplay *disp) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - int arbitrary_max_interval = 1000; - - /* default behavior for no SwapBuffers support: no vblank syncing - * either. - */ - dri2_dpy->min_swap_interval = 0; - dri2_dpy->max_swap_interval = 0; - dri2_dpy->default_swap_interval = 0; - - if (!dri2_dpy->swap_available) - return; - - /* If we do have swapbuffers, then we can support pretty much any swap - * interval. - */ - dri2_setup_swap_interval(disp, arbitrary_max_interval); -} - #ifdef HAVE_DRI3 static const __DRIextension *dri3_image_loader_extensions[] = { diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 76b296f8d2c..0284931af02 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -628,6 +628,11 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false); if (disp->Options.ForceSoftware) _eglLog(_EGL_DEBUG, "Found 'LIBGL_ALWAYS_SOFTWARE' set, will use a CPU renderer"); + else { + const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE"); + disp->Options.Zink = env && !strcmp(env, "zink"); + disp->Options.ForceSoftware |= disp->Options.Zink; + } /** * Initialize the display using the driver's function. diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 0ee06a487c0..25b4ea79541 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -170,6 +170,7 @@ struct _egl_display /* options that affect how the driver initializes the display */ struct { + EGLBoolean Zink; /**< Use kopper only */ EGLBoolean ForceSoftware; /**< Use software path only */ EGLAttrib *Attribs; /**< Platform-specific options */ int fd; /**< plaform device specific, local fd */ diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index 560b97f2b70..b8f2e6f5230 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -299,6 +299,7 @@ static struct dri_extension_match gbm_dri_device_extensions[] = { static struct dri_extension_match gbm_swrast_device_extensions[] = { { __DRI_CORE, 1, offsetof(struct gbm_dri_device, core), false }, { __DRI_SWRAST, 1, offsetof(struct gbm_dri_device, swrast), false }, + { __DRI_KOPPER, 1, offsetof(struct gbm_dri_device, kopper), true }, }; static bool diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h index ec4ec7f45c1..31f6b67a40f 100644 --- a/src/gbm/backends/dri/gbm_driint.h +++ b/src/gbm/backends/dri/gbm_driint.h @@ -36,6 +36,7 @@ #include /* dri_interface needs GL types */ #include "GL/internal/dri_interface.h" +#include "kopper_interface.h" struct gbm_dri_surface; struct gbm_dri_bo; @@ -74,6 +75,7 @@ struct gbm_dri_device { const __DRI2fenceExtension *fence; const __DRIimageExtension *image; const __DRIswrastExtension *swrast; + const __DRIkopperExtension *kopper; const __DRI2flushExtension *flush; const __DRIconfig **driver_configs;