Mesa (master): zink: support using lavapipe

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Feb 5 16:53:11 UTC 2021


Module: Mesa
Branch: master
Commit: 3824c06aff27f9aae05c82c85a1a7779b27df980
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3824c06aff27f9aae05c82c85a1a7779b27df980

Author: Erik Faye-Lund <erik.faye-lund at collabora.com>
Date:   Wed Dec  2 17:26:26 2020 +0100

zink: support using lavapipe

This is really nasty, and shouldn't really be needed, but we have a
problem where both Zink and Lavapipe checks $GALLIUM_DRIVER, meaning that
Zink tries to use Lavapipe, and Lavapipe tries to use Zink.

This patch side-steps that by temporarily setting $GALLIUM_DRIVER to
"llvmpipe", giving Lavapipe a chance to succeed.

This is not great at all. The most obvious problem is that this is super
thread-unsafe, effectively modifying global state without any care. In
reality, we'd only want the pipe-loader in the *same thread* to ignore
Zink, but it's not so obvious how to do that without introducing lots of
ugly zink-specific cruft.

People shouldn't be using Zink if they don't have a GPU, it's going to
be much better to use LLVMpipe in that case. So let's not worry too much
about this case, and instead guard this dangerous logic with an
ZINK_USE_LAVAPIPE environment variable. This means this behavior only
happens if people opt in to it.

With this in place, we can start using Zink + Lavapipe on CI.

In the longer run, it might be better to use Adam Jackson's copper
loader instead, and drop exposing Zink as a software rasterizer
entirely. But that's something for the great future where we have flying
cars and all.

Reviewed-by: Adam Jackson <ajax at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7881>

---

 src/gallium/drivers/zink/meson.build   |  6 ++++++
 src/gallium/drivers/zink/zink_screen.c | 33 ++++++++++++++++++++++++++++++++-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/zink/meson.build b/src/gallium/drivers/zink/meson.build
index 293d2aacc7b..9cc0b1ddfad 100644
--- a/src/gallium/drivers/zink/meson.build
+++ b/src/gallium/drivers/zink/meson.build
@@ -71,12 +71,18 @@ zink_nir_algebraic_c = custom_target(
   depend_files : nir_algebraic_py,
 )
 
+zink_c_args = []
+if with_swrast_vk
+  zink_c_args += '-DZINK_WITH_SWRAST_VK'
+endif
+
 libzink = static_library(
   'zink',
   [files_libzink, zink_device_info, zink_instance, zink_nir_algebraic_c],
   gnu_symbol_visibility : 'hidden',
   include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_vulkan_wsi, inc_vulkan_util],
   dependencies: [dep_vulkan, idep_nir_headers, idep_mesautil],
+  c_args: zink_c_args,
 )
 
 driver_zink = declare_dependency(
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index 1693b830d30..11772b8242c 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -724,6 +724,17 @@ choose_pdev(const VkInstance instance)
    for (i = 0; i < pdev_count; ++i) {
       VkPhysicalDeviceProperties props;
       vkGetPhysicalDeviceProperties(pdevs[i], &props);
+
+#ifdef ZINK_WITH_SWRAST_VK
+      char *use_lavapipe = getenv("ZINK_USE_LAVAPIPE");
+      if (use_lavapipe) {
+         if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
+            pdev = pdevs[i];
+            break;
+         } else
+            continue;
+      }
+#endif
       if (props.deviceType != VK_PHYSICAL_DEVICE_TYPE_CPU) {
          pdev = pdevs[i];
          break;
@@ -1156,11 +1167,31 @@ fail:
 struct pipe_screen *
 zink_create_screen(struct sw_winsys *winsys)
 {
-   struct zink_screen *ret = zink_internal_create_screen(NULL);
+#ifdef ZINK_WITH_SWRAST_VK
+   char *use_lavapipe = getenv("ZINK_USE_LAVAPIPE"), *gallium_driver = NULL;
+   if (use_lavapipe) {
+      /**
+      * HACK: Temorarily unset $GALLIUM_DRIVER to prevent Lavapipe from
+      * recursively trying to use zink as the gallium driver.
+      *
+      * This is not thread-safe, so if an application creates another
+      * context in another thread at the same time, well, we're out of
+      * luck!
+      */
+      gallium_driver = getenv("GALLIUM_DRIVER");
+      setenv("GALLIUM_DRIVER", "llvmpipe", 1);
+   }
+#endif
 
+   struct zink_screen *ret = zink_internal_create_screen(NULL);
    if (ret)
       ret->winsys = winsys;
 
+#ifdef ZINK_WITH_SWRAST_VK
+   if (gallium_driver)
+      setenv("GALLIUM_DRIVER", gallium_driver, 1);
+#endif
+
    return &ret->base;
 }
 



More information about the mesa-commit mailing list