Add GGP WSI platform support to Vulkan-Loader
authorJ.D. Rouan <jdrouan@google.com>
Mon, 16 Nov 2020 23:36:42 +0000 (15:36 -0800)
committerLenny Komow <lenny@lunarg.com>
Mon, 23 Nov 2020 16:12:55 +0000 (09:12 -0700)
Add GGP WSI platform support to Vulkan-Loader. GGP is Google Games
Platform, the platform for Stadia.

loader/loader.h
loader/wsi.c
loader/wsi.h
scripts/loader_extension_generator.py

index 4779f8e..ea0c976 100644 (file)
@@ -338,6 +338,9 @@ struct loader_instance {
 #ifdef VK_USE_PLATFORM_IOS_MVK
     bool wsi_ios_surface_enabled;
 #endif
+#ifdef VK_USE_PLATFORM_GGP
+    bool wsi_ggp_surface_enabled;
+#endif
     bool wsi_headless_surface_enabled;
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     bool wsi_metal_surface_enabled;
index 0d687b2..523f16a 100644 (file)
@@ -64,6 +64,9 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC
 #ifdef VK_USE_PLATFORM_IOS_MVK
     ptr_instance->wsi_ios_surface_enabled = false;
 #endif  // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_GGP
+    ptr_instance->wsi_ggp_surface_enabled = false;
+#endif  // VK_USE_PLATFORM_GGP
 #ifdef VK_USE_PLATFORM_FUCHSIA
     ptr_instance->wsi_imagepipe_surface_enabled = false;
 #endif  // VK_USE_PLATFORM_FUCHSIA
@@ -126,6 +129,12 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC
             continue;
         }
 #endif  // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_GGP
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME) == 0) {
+            ptr_instance->wsi_ggp_surface_enabled = true;
+            continue;
+        }
+#endif  // VK_USE_PLATFORM_GGP
 #ifdef VK_USE_PLATFORM_FUCHSIA
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME) == 0) {
             ptr_instance->wsi_imagepipe_surface_enabled = true;
@@ -1317,6 +1326,83 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instanc
 
 #endif  // VK_USE_PLATFORM_IOS_MVK
 
+#ifdef VK_USE_PLATFORM_GGP
+
+// Functions for the VK_GGP_stream_descriptor_surface extension:
+
+// This is the trampoline entrypoint for CreateStreamDescriptorSurfaceGGP
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
+vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
+                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    const VkLayerInstanceDispatchTable *disp;
+    disp = loader_get_instance_layer_dispatch(instance);
+    VkResult res;
+
+    res = disp->CreateStreamDescriptorSurfaceGGP(instance, pCreateInfo, pAllocator, pSurface);
+    return res;
+}
+
+// This is the instance chain terminator function for CreateStreamDescriptorSurfaceGGP
+VKAPI_ATTR VkResult VKAPI_CALL
+terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
+                                            const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult vkRes = VK_SUCCESS;
+    VkIcdSurface *pIcdSurface = NULL;
+    uint32_t i = 0;
+
+    // First, check to ensure the appropriate extension was enabled:
+    struct loader_instance *ptr_instance = loader_get_instance(instance);
+    if (!ptr_instance->wsi_ggp_surface_enabled) {
+        loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "VK_GGP_stream_descriptor_surface extension not enabled.  vkCreateStreamDescriptorSurfaceGGP not executed!\n");
+        vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+        goto out;
+    }
+
+    // Next, if so, proceed with the implementation of this function:
+    pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->ggp_surf.base), sizeof(pIcdSurface->ggp_surf));
+    if (pIcdSurface == NULL) {
+        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
+    }
+
+    pIcdSurface->ggp_surf.base.platform = VK_ICD_WSI_PLATFORM_GGP;
+    pIcdSurface->ggp_surf.streamDescriptor = pCreateInfo->streamDescriptor;
+
+    // Loop through each ICD and determine if they need to create a surface
+    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 (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) {
+                vkRes = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(icd_term->instance, pCreateInfo, pAllocator,
+                                                                            &pIcdSurface->real_icd_surfaces[i]);
+                if (VK_SUCCESS != vkRes) {
+                    goto out;
+                }
+            }
+        }
+    }
+
+    *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+out:
+
+    if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+        if (NULL != pIcdSurface->real_icd_surfaces) {
+            i = 0;
+            for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+                if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+                    icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, pIcdSurface);
+    }
+    return vkRes;
+}
+
+#endif  // VK_USE_PLATFORM_GGP
+
 #if defined(VK_USE_PLATFORM_METAL_EXT)
 
 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance,
@@ -2350,6 +2436,14 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char
         return true;
     }
 #endif  // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_GGP
+
+    // Functions for the VK_GGP_stream_descriptor_surface extension:
+    if (!strcmp("vkCreateStreamDescriptorSurfaceGGP", name)) {
+        *addr = ptr_instance->wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL;
+        return true;
+    }
+#endif  // VK_USE_PLATFORM_GGP
 #ifdef VK_USE_PLATFORM_FUCHSIA
 
     // Functions for the VK_FUCHSIA_imagepipe_surface extension:
index a5a6835..c9f4654 100644 (file)
@@ -45,6 +45,9 @@ typedef struct {
 #ifdef VK_USE_PLATFORM_MACOS_MVK
         VkIcdSurfaceMacOS macos_surf;
 #endif  // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_GGP
+        VkIcdSurfaceGgp ggp_surf;
+#endif  // VK_USE_PLATFORM_GGP
 #ifdef VK_USE_PLATFORM_FUCHSIA
         VkIcdSurfaceImagePipe imagepipe_surf;
 #endif  // VK_USE_PLATFORM_FUCHSIA
@@ -143,6 +146,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance insta
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
                                                               const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
 #endif
+#ifdef VK_USE_PLATFORM_GGP
+VKAPI_ATTR VkResult VKAPI_CALL
+terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *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);
index 4985793..e8c4ac6 100644 (file)
@@ -35,6 +35,7 @@ WSI_EXT_NAMES = ['VK_KHR_surface',
                  'VK_EXT_directfb_surface',
                  'VK_KHR_win32_surface',
                  'VK_KHR_android_surface',
+                 'VK_GGP_stream_descriptor_surface',
                  'VK_MVK_macos_surface',
                  'VK_MVK_ios_surface',
                  'VK_EXT_headless_surface',