Mesa (master): zink: Added support for MacOS MoltenVK APIs.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 3 16:39:55 UTC 2020


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

Author: Duncan Hopkins <duncan.hopkins at foundry.com>
Date:   Fri Oct 30 10:01:42 2020 +0000

zink: Added support for MacOS MoltenVK APIs.

Detects the MoltenVK layer and extension.
If present, get the ext function pointers and use to enable full swizzeling suport.
Fixes issues with Swizzling behaviour fro MoltenVk is disabled by default and needed to be enable via this API.

This also supplied the ground work to allow IOSurfaces to be used later for surface passing.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7383>

---

 src/gallium/drivers/zink/zink_screen.c | 75 ++++++++++++++++++++++++++++++++--
 src/gallium/drivers/zink/zink_screen.h | 19 +++++++++
 2 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index 15e7d5cb328..75f7698c1bd 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -644,6 +644,11 @@ create_instance(struct zink_screen *screen)
    const char *extensions[4] = { 0 };
    uint32_t num_extensions = 0;
 
+#if defined(MVK_VERSION)
+   bool have_moltenvk_layer = false;
+   bool have_moltenvk_layer_ext = false;
+#endif
+
    {
       // Build up the extensions from the reported ones but only for the unnamed layer
       uint32_t extension_count = 0;
@@ -660,6 +665,12 @@ create_instance(struct zink_screen *screen)
                   if (!strcmp(extension_props[i].extensionName, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
                      extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME;
                   }
+#if defined(MVK_VERSION)
+                  if (!strcmp(extension_props[i].extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME)) {
+                     have_moltenvk_layer_ext = true;
+                     extensions[num_extensions++] = VK_MVK_MOLTENVK_EXTENSION_NAME;
+                  }
+#endif
                }
             }
             free(extension_props);
@@ -677,6 +688,12 @@ create_instance(struct zink_screen *screen)
             err = vkEnumerateInstanceLayerProperties(&layer_count, layer_props);
             if (err == VK_SUCCESS) {
                for (uint32_t i = 0; i < layer_count; i++) {
+#if defined(MVK_VERSION)
+                  if (!strcmp(layer_props[i].layerName, "MoltenVK")) {
+                     have_moltenvk_layer = true;
+                     layers[num_layers++] = "MoltenVK";
+                  }
+#endif
                }
             }
             free(layer_props);
@@ -684,6 +701,12 @@ create_instance(struct zink_screen *screen)
       }
    }
 
+#if defined(MVK_VERSION)
+   if (have_moltenvk_layer_ext && have_moltenvk_layer) {
+      screen->have_moltenvk = true;
+   }
+#endif
+
    VkApplicationInfo ai = {};
    ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
 
@@ -801,9 +824,6 @@ zink_flush_frontbuffer(struct pipe_screen *pscreen,
       winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
 }
 
-static bool
-load_device_extensions(struct zink_screen *screen)
-{
 #define GET_PROC_ADDR(x) do {                                               \
       screen->vk_##x = (PFN_vk##x)vkGetDeviceProcAddr(screen->dev, "vk"#x); \
       if (!screen->vk_##x) {                                                \
@@ -819,6 +839,10 @@ load_device_extensions(struct zink_screen *screen)
          return false;                                                      \
       } \
    } while (0)
+
+static bool
+load_device_extensions(struct zink_screen *screen)
+{
    if (screen->info.have_EXT_transform_feedback) {
       GET_PROC_ADDR(CmdBindTransformFeedbackBuffersEXT);
       GET_PROC_ADDR(CmdBeginTransformFeedbackEXT);
@@ -862,10 +886,49 @@ load_device_extensions(struct zink_screen *screen)
       GET_PROC_ADDR(CmdSetScissorWithCountEXT);
    }
 
-#undef GET_PROC_ADDR
+   return true;
+}
+
+#if defined(MVK_VERSION)
+static bool
+zink_internal_setup_moltenvk(struct zink_screen *screen)
+{
+   if (!screen->have_moltenvk)
+      return true;
+
+   GET_PROC_ADDR_INSTANCE(GetMoltenVKConfigurationMVK);
+   GET_PROC_ADDR_INSTANCE(SetMoltenVKConfigurationMVK);
+
+   GET_PROC_ADDR_INSTANCE(GetPhysicalDeviceMetalFeaturesMVK);
+   GET_PROC_ADDR_INSTANCE(GetVersionStringsMVK);
+   GET_PROC_ADDR_INSTANCE(UseIOSurfaceMVK);
+   GET_PROC_ADDR_INSTANCE(GetIOSurfaceMVK);
+
+   if (screen->vk_GetVersionStringsMVK) {
+      char molten_version[64] = {0};
+      char vulkan_version[64] = {0};
+
+      (*screen->vk_GetVersionStringsMVK)(molten_version, sizeof(molten_version) - 1, vulkan_version, sizeof(vulkan_version) - 1);
+
+      printf("zink: MoltenVK %s Vulkan %s \n", molten_version, vulkan_version);
+   }
+
+   if (screen->vk_GetMoltenVKConfigurationMVK && screen->vk_SetMoltenVKConfigurationMVK) {
+      MVKConfiguration molten_config = {0};
+      size_t molten_config_size = sizeof(molten_config);
+
+      VkResult res = (*screen->vk_GetMoltenVKConfigurationMVK)(screen->instance, &molten_config, &molten_config_size);
+      if (res == VK_SUCCESS || res == VK_INCOMPLETE) {
+         // Needed to allow MoltenVK to accept VkImageView swizzles.
+         // Encounted when using VK_FORMAT_R8G8_UNORM
+         molten_config.fullImageViewSwizzle = VK_TRUE;
+         (*screen->vk_SetMoltenVKConfigurationMVK)(screen->instance, &molten_config, &molten_config_size);
+      }
+   }
 
    return true;
 }
+#endif // MVK_VERSION
 
 static struct pipe_screen *
 zink_internal_create_screen(struct sw_winsys *winsys, int fd, const struct pipe_screen_config *config)
@@ -890,6 +953,10 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd, const struct pipe_
       goto fail;
    }
 
+#if defined(MVK_VERSION)
+   zink_internal_setup_moltenvk(screen);
+#endif
+
    if (fd >= 0 && !screen->info.have_KHR_external_memory_fd) {
       debug_printf("ZINK: KHR_external_memory_fd required!\n");
       goto fail;
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index 135b3248782..2e00a204d3f 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -31,6 +31,11 @@
 
 #include <vulkan/vulkan.h>
 
+#if defined(__APPLE__)
+// Source of MVK_VERSION
+#include "MoltenVK/vk_mvk_moltenvk.h"
+#endif
+
 extern uint32_t zink_debug;
 
 #define ZINK_DEBUG_NIR 0x1
@@ -56,6 +61,10 @@ struct zink_screen {
    uint32_t timestamp_valid_bits;
    VkDevice dev;
 
+#if defined(MVK_VERSION)
+   bool have_moltenvk;
+#endif
+
    PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR;
    PFN_vkCmdBeginConditionalRenderingEXT vk_CmdBeginConditionalRenderingEXT;
    PFN_vkCmdEndConditionalRenderingEXT vk_CmdEndConditionalRenderingEXT;
@@ -72,6 +81,16 @@ struct zink_screen {
 
    PFN_vkCmdSetViewportWithCountEXT vk_CmdSetViewportWithCountEXT;
    PFN_vkCmdSetScissorWithCountEXT vk_CmdSetScissorWithCountEXT;
+
+#if defined(MVK_VERSION)
+   PFN_vkGetMoltenVKConfigurationMVK vk_GetMoltenVKConfigurationMVK;
+   PFN_vkSetMoltenVKConfigurationMVK vk_SetMoltenVKConfigurationMVK;
+
+   PFN_vkGetPhysicalDeviceMetalFeaturesMVK vk_GetPhysicalDeviceMetalFeaturesMVK;
+   PFN_vkGetVersionStringsMVK vk_GetVersionStringsMVK;
+   PFN_vkUseIOSurfaceMVK vk_UseIOSurfaceMVK;
+   PFN_vkGetIOSurfaceMVK vk_GetIOSurfaceMVK;
+#endif
 };
 
 static inline struct zink_screen *



More information about the mesa-commit mailing list