loader: Add support for metal surfaces
The adds support for the VK_EXT_metal_surface extension
Change-Id: Ibb1c21e19fb053fe332ea075c3d32de59f7f8881
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index ed78054..8c2cedb 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -38,6 +38,7 @@
add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR)
elseif(APPLE)
add_definitions(-DVK_USE_PLATFORM_MACOS_MVK)
+ add_definitions(-DVK_USE_PLATFORM_METAL_EXT)
elseif(UNIX AND NOT APPLE) # i.e.: Linux
if(BUILD_WSI_XCB_SUPPORT)
add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
diff --git a/loader/loader.h b/loader/loader.h
index 36f0414..8d6b4c4 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -333,6 +333,9 @@
bool wsi_ios_surface_enabled;
#endif
bool wsi_headless_surface_enabled;
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+ bool wsi_metal_surface_enabled;
+#endif
bool wsi_display_enabled;
bool wsi_display_props2_enabled;
};
diff --git a/loader/wsi.c b/loader/wsi.c
index e9f573f..f8d8e53 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
+ * Copyright (c) 2015-2016, 2019 The Khronos Group Inc.
+ * Copyright (c) 2015-2016, 2019 Valve Corporation
+ * Copyright (c) 2015-2016, 2019 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
* Author: Jon Ashburn <jon@lunarg.com>
* Author: Ian Elliott <ianelliott@google.com>
* Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
*/
#ifndef _GNU_SOURCE
@@ -60,9 +61,11 @@
#ifdef VK_USE_PLATFORM_IOS_MVK
ptr_instance->wsi_ios_surface_enabled = false;
#endif // VK_USE_PLATFORM_IOS_MVK
-
ptr_instance->wsi_display_enabled = false;
ptr_instance->wsi_display_props2_enabled = false;
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ ptr_instance->wsi_metal_surface_enabled = false;
+#endif // VK_USE_PLATFORM_METAL_EXT
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
@@ -115,6 +118,12 @@
ptr_instance->wsi_headless_surface_enabled = true;
continue;
}
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_metal_surface_enabled = true;
+ continue;
+ }
+#endif
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
ptr_instance->wsi_display_enabled = true;
continue;
@@ -1169,6 +1178,72 @@
#endif // VK_USE_PLATFORM_IOS_MVK
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance,
+ const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(instance);
+ return disp->CreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult result = VK_SUCCESS;
+ VkIcdSurface *icd_surface = NULL;
+ uint32_t i;
+
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_metal_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed.\n");
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ icd_surface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf));
+ if (icd_surface == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ icd_surface->metal_surf.base.platform = VK_ICD_WSI_PLATFORM_METAL;
+ icd_surface->metal_surf.pLayer = pCreateInfo->pLayer;
+
+ // Loop through each ICD and determine if they need to create a surface
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (icd_term->dispatch.CreateMetalSurfaceEXT != NULL) {
+ result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
+ &icd_surface->real_icd_surfaces[i]);
+ if (result != VK_SUCCESS) {
+ goto out;
+ }
+ }
+ }
+ }
+ *pSurface = (VkSurfaceKHR)icd_surface;
+
+out:
+ if (result != VK_SUCCESS && icd_surface != NULL) {
+ if (icd_surface->real_icd_surfaces != NULL) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
+ if (icd_surface->real_icd_surfaces[i] == VK_NULL_HANDLE && icd_term->dispatch.DestroySurfaceKHR != NULL) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, icd_surface);
+ }
+ return result;
+}
+
+#endif
+
// Functions for the VK_KHR_display instance extension:
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
@@ -1882,6 +1957,14 @@
return true;
}
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+ // Functions for the VK_MVK_macos_surface extension:
+ if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
+ *addr = ptr_instance->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_METAL_EXT
+
// Functions for VK_KHR_display extension:
if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
*addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
diff --git a/loader/wsi.h b/loader/wsi.h
index b09f168..3e44efa 100644
--- a/loader/wsi.h
+++ b/loader/wsi.h
@@ -42,6 +42,9 @@
#ifdef VK_USE_PLATFORM_MACOS_MVK
VkIcdSurfaceMacOS macos_surf;
#endif // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ VkIcdSurfaceMetal metal_surf;
+#endif // VK_USE_PLATFORM_METAL_EXT
VkIcdSurfaceDisplay display_surf;
VkIcdSurfaceHeadless headless_surf;
};
@@ -126,6 +129,10 @@
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
#endif
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+#endif
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
VkDisplayPropertiesKHR *pProperties);
diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py
index 49cf720..90ca158 100644
--- a/scripts/loader_extension_generator.py
+++ b/scripts/loader_extension_generator.py
@@ -37,6 +37,7 @@
'VK_MVK_macos_surface',
'VK_MVK_ios_surface',
'VK_EXT_headless_surface',
+ 'VK_EXT_metal_surface',
'VK_KHR_swapchain',
'VK_KHR_display_swapchain',
'VK_KHR_get_display_properties2']