egl: Learn about kopper
authorAdam Jackson <ajax@redhat.com>
Tue, 15 Mar 2022 19:35:48 +0000 (15:35 -0400)
committerMarge Bot <emma+marge@anholt.net>
Thu, 7 Apr 2022 00:17:40 +0000 (00:17 +0000)
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14541>

src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h
src/egl/drivers/dri2/platform_device.c
src/egl/drivers/dri2/platform_drm.c
src/egl/drivers/dri2/platform_surfaceless.c
src/egl/drivers/dri2/platform_wayland.c
src/egl/drivers/dri2/platform_x11.c
src/egl/main/eglapi.c
src/egl/main/egldisplay.h
src/gbm/backends/dri/gbm_dri.c
src/gbm/backends/dri/gbm_driint.h

index 1353dfc..3682d05 100644 (file)
@@ -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->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->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");
 
-   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");
 
index e7d3de0..8915899 100644 (file)
@@ -58,6 +58,7 @@ struct zwp_linux_dmabuf_feedback_v1;
 
 #include <GL/gl.h>
 #include <GL/internal/dri_interface.h>
+#include "kopper_interface.h"
 
 #ifdef HAVE_DRM_PLATFORM
 #include <gbm_driint.h>
@@ -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;
index 30f6f7e..66b2eee 100644 (file)
@@ -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;
 
index 6aada72..45895a8 100644 (file)
@@ -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;
index a420eb0..df88c54 100644 (file)
@@ -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;
 
index 42bdb3b..e9ecf6d 100644 (file)
@@ -45,6 +45,7 @@
 #include "util/u_vector.h"
 #include "util/anon_file.h"
 #include "eglglobals.h"
+#include "kopper_interface.h"
 
 #include <wayland-egl-backend.h>
 #include <wayland-client.h>
@@ -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;
 
index 5ffdf13..576d47e 100644 (file)
@@ -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[] = {
index 76b296f..0284931 100644 (file)
@@ -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.
index 0ee06a4..25b4ea7 100644 (file)
@@ -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 */
index 560b97f..b8f2e6f 100644 (file)
@@ -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
index ec4ec7f..31f6b67 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <GL/gl.h> /* 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;