loader: More changes for gh181
authorMark Young <marky@lunarg.com>
Fri, 16 Sep 2016 16:18:42 +0000 (10:18 -0600)
committerMark Young <marky@lunarg.com>
Tue, 20 Sep 2016 17:46:39 +0000 (11:46 -0600)
With Piers' fix, another path was broke because we still needed
to intercept the call before it went to the ICD.  Now, with his
change and this change, all paths work.

Also, clean up some code based on comments from Ian and Courtney
reviews.

Finally, update docs to indicate behavior of new loader 3
interface with ICDs.

Change-Id: I2d3f962baffb21c1edeb93b132ffad40f298c8e7

loader/LoaderAndLayerInterface.md
loader/loader.c
loader/loader.h
loader/table_ops.h
loader/trampoline.c
loader/wsi.c

index 22d5520..95c11f1 100644 (file)
@@ -592,7 +592,7 @@ from the most recent interface version.
 
 ##### Version Negotiation Between Loader and ICDs
 
-All ICDs  (supporting interface version 2 or higher) must export the following
+All ICDs (supporting interface version 2 or higher) must export the following
 function that is used for determination of the interface version that will be used.
 This entry point is not a part of the Vulkan API itself, only a private interface
 between the loader and ICDs.
@@ -633,11 +633,31 @@ instead of VK_SUCCESS then the loader will treat the ICD as incompatible
 and will not load it for use.  In this case the application will not see the ICDs vkPhysicalDevice
 during enumeration.
 
+##### Loader Version 3 Interface Changes
+
+The primary change occuring in version 3 of the loader/ICD interface is to allow an ICD to
+handle Creation/Destruction of their own KHR_surfaces.  Up until this point, the loader created
+a surface object that was used by all ICDs.  However, some ICDs may want to provide their
+own surface handles.  If an ICD chooses to enable this support, they must export support for
+version 3 of the Loader/ICD interface as well as any Vulkan command that uses a KHR_surface handle,
+such as:
+- vkCreateXXXSurfaceKHR (where XXX is the platform specific identifier [i.e.CreateWin32SurfaceKHR for Windows])
+- vkDestroySurfaceKHR
+- vkCreateSwapchainKHR
+- vkGetPhysicalDeviceSurfaceSupportKHR
+- vkGetPhysicalDeviceSurfaceCapabilitiesKHR
+- vkGetPhysicalDeviceSurfaceFormatsKHR
+- vkGetPhysicalDeviceSurfacePresentModesKHR
+
+An ICD can still choose to not take advantage of this functionality by simply not exposing the
+above the vkCreateXXXSurfaceKHR and vkDestroySurfaceKHR commands.
+
 ##### Loader Version 2 Interface Requirements
 
-Version 2 interface has requirements in three areas: 1) ICD Vulkan entry point discovery,
-2) KHR_surface related requirements in the WSI extensions, 3) Vulkan dispatchable object
-creation requirements.
+Version 2 interface has requirements in three areas:
+ 1. ICD Vulkan entry point discovery,
+ 2. KHR_surface related requirements in the WSI extensions,
+ 3. Vulkan dispatchable object creation requirements.
 
 ######  ICD Vulkan entry point discovery
 All ICDs must export the following function that is used for discovery of ICD Vulkan entry points.
index 641be74..74ffcd9 100644 (file)
@@ -1653,6 +1653,10 @@ static bool loader_icd_init_entrys(struct loader_icd *icd, VkInstance inst,
     LOOKUP_GIPA(CreateXlibSurfaceKHR, false);
     LOOKUP_GIPA(GetPhysicalDeviceXlibPresentationSupportKHR, false);
 #endif
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    LOOKUP_GIPA(CreateMirSurfaceKHR, false);
+    LOOKUP_GIPA(GetPhysicalDeviceMirPresentationSupportKHR, false);
+#endif
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
     LOOKUP_GIPA(CreateWaylandSurfaceKHR, false);
     LOOKUP_GIPA(GetPhysicalDeviceWaylandPresentationSupportKHR, false);
@@ -3243,6 +3247,22 @@ loader_gpa_instance_internal(VkInstance inst, const char *pName) {
     return NULL;
 }
 
+void loader_override_terminating_device_proc(
+    VkDevice device, struct loader_dev_dispatch_table *disp_table) {
+    struct loader_device *dev;
+    struct loader_icd *icd = loader_get_icd_and_device(device, &dev, NULL);
+
+    // Certain device entry-points still need to go through a terminator before
+    // hitting the ICD.  This could be for several reasons, but the main one
+    // is currently unwrapping an object before passing the appropriate info
+    // along to the ICD.
+    if ((PFN_vkVoidFunction)disp_table->core_dispatch.CreateSwapchainKHR ==
+        (PFN_vkVoidFunction)icd->GetDeviceProcAddr(device,
+                                                   "vkCreateSwapchainKHR")) {
+        disp_table->core_dispatch.CreateSwapchainKHR =
+            terminator_vkCreateSwapchainKHR;
+    }
+}
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
 loader_gpa_device_internal(VkDevice device, const char *pName) {
index 060e02e..5eb56d9 100644 (file)
@@ -511,9 +511,9 @@ struct loader_icd *loader_get_icd_and_device(const VkDevice device,
                                              uint32_t *icd_index);
 void loader_init_dispatch_dev_ext(struct loader_instance *inst,
                                   struct loader_device *dev);
-VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_device_internal(VkDevice device, const char *pName);
 void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
 void *loader_get_dev_ext_trampoline(uint32_t index);
+void loader_override_terminating_device_proc(VkDevice device, struct loader_dev_dispatch_table *disp_table);
 struct loader_instance *loader_get_instance(const VkInstance instance);
 void loader_deactivate_layers(const struct loader_instance *instance,
                               struct loader_device *device,
index 427a7f6..546273f 100644 (file)
@@ -541,7 +541,7 @@ loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table,
         return (void *)table->CmdExecuteCommands;
 
     if (!strcmp(name, "CreateSwapchainKHR")) {
-        // For CreateSwapChainKHR we need to use the entry and terminator
+        // For CreateSwapChainKHR we need to use trampoline and terminator
         // functions to properly unwrap the SurfaceKHR object.
         return (void *)vkCreateSwapchainKHR;
     }
index a26847d..81513f9 100644 (file)
@@ -713,15 +713,20 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
 
     *pDevice = dev->device;
 
-    /* initialize any device extension dispatch entry's from the instance list*/
+    // Initialize any device extension dispatch entry's from the instance list
     loader_init_dispatch_dev_ext(inst, dev);
 
-    /* initialize WSI device extensions as part of core dispatch since loader
-     * has
-     * dedicated trampoline code for these*/
+    // Initialize WSI device extensions as part of core dispatch since loader
+    // has dedicated trampoline code for these*/
     loader_init_device_extension_dispatch_table(
         &dev->loader_dispatch,
-        loader_gpa_device_internal, *pDevice);
+        dev->loader_dispatch.core_dispatch.GetDeviceProcAddr, *pDevice);
+
+    // The loader needs to override some terminating device procs.  Usually,
+    // these are device procs which need to go through a loader terminator.
+    // This needs to occur if the loader needs to perform some work prior
+    // to passing the work along to the ICD.
+    loader_override_terminating_device_proc(*pDevice, &dev->loader_dispatch);
 
 out:
 
index 123a7f8..acea82d 100644 (file)
@@ -211,8 +211,6 @@ terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
                              const VkAllocationCallbacks *pAllocator) {
     struct loader_instance *ptr_instance = loader_get_instance(instance);
 
-// Android doesn't have to worry about multiple ICD scenario, but the rest do.
-#ifndef VK_USE_PLATFORM_ANDROID_KHR
     VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
     if (NULL != icd_surface->real_icd_surfaces) {
         for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
@@ -230,12 +228,11 @@ terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
                 // The real_icd_surface for any ICD not supporting the proper
                 // interface version should be NULL.  If not, then we have a
                 // problem.
-                assert(NULL == icd_surface->real_icd_surfaces[i]);
+                assert(NULL == (void*)icd_surface->real_icd_surfaces[i]);
             }
         }
         loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
     }
-#endif // !VK_USE_PLATFORM_XLIB_KHR
 
     loader_instance_heap_free(ptr_instance, (void *)surface);
 }
@@ -282,8 +279,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(
     assert(icd->GetPhysicalDeviceSurfaceSupportKHR &&
            "loader: null GetPhysicalDeviceSurfaceSupportKHR ICD pointer");
 
-// Android doesn't have to worry about multiple ICD scenario, but the rest do.
-#ifndef VK_USE_PLATFORM_ANDROID_KHR
     VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
     if (NULL != icd_surface->real_icd_surfaces &&
         NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
@@ -291,7 +286,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(
             phys_dev->phys_dev, queueFamilyIndex,
             icd_surface->real_icd_surfaces[phys_dev->icd_index], pSupported);
     }
-#endif
 
     return icd->GetPhysicalDeviceSurfaceSupportKHR(
         phys_dev->phys_dev, queueFamilyIndex, surface, pSupported);
@@ -339,8 +333,6 @@ terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(
     assert(icd->GetPhysicalDeviceSurfaceCapabilitiesKHR &&
            "loader: null GetPhysicalDeviceSurfaceCapabilitiesKHR ICD pointer");
 
-// Android doesn't have to worry about multiple ICD scenario, but the rest do.
-#ifndef VK_USE_PLATFORM_ANDROID_KHR
     VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
     if (NULL != icd_surface->real_icd_surfaces &&
         NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
@@ -349,7 +341,6 @@ terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(
             icd_surface->real_icd_surfaces[phys_dev->icd_index],
             pSurfaceCapabilities);
     }
-#endif
 
     return icd->GetPhysicalDeviceSurfaceCapabilitiesKHR(
         phys_dev->phys_dev, surface, pSurfaceCapabilities);
@@ -398,8 +389,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(
     assert(icd->GetPhysicalDeviceSurfaceFormatsKHR &&
            "loader: null GetPhysicalDeviceSurfaceFormatsKHR ICD pointer");
 
-// Android doesn't have to worry about multiple ICD scenario, but the rest do.
-#ifndef VK_USE_PLATFORM_ANDROID_KHR
     VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
     if (NULL != icd_surface->real_icd_surfaces &&
         NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
@@ -408,7 +397,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(
             icd_surface->real_icd_surfaces[phys_dev->icd_index],
             pSurfaceFormatCount, pSurfaceFormats);
     }
-#endif
 
     return icd->GetPhysicalDeviceSurfaceFormatsKHR(
         phys_dev->phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
@@ -456,8 +444,6 @@ terminator_GetPhysicalDeviceSurfacePresentModesKHR(
     assert(icd->GetPhysicalDeviceSurfacePresentModesKHR &&
            "loader: null GetPhysicalDeviceSurfacePresentModesKHR ICD pointer");
 
-// Android doesn't have to worry about multiple ICD scenario, but the rest do.
-#ifndef VK_USE_PLATFORM_ANDROID_KHR
     VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
     if (NULL != icd_surface->real_icd_surfaces &&
         NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
@@ -466,7 +452,6 @@ terminator_GetPhysicalDeviceSurfacePresentModesKHR(
             icd_surface->real_icd_surfaces[phys_dev->icd_index],
             pPresentModeCount, pPresentModes);
     }
-#endif
 
     return icd->GetPhysicalDeviceSurfacePresentModesKHR(
         phys_dev->phys_dev, surface, pPresentModeCount, pPresentModes);
@@ -492,8 +477,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_vkCreateSwapchainKHR(
     struct loader_icd *icd = loader_get_icd_and_device(device, &dev, &icd_index);
     if (NULL != icd &&
         NULL != icd->CreateSwapchainKHR) {
-        // Android doesn't have to worry about multiple ICD scenario, but the rest do.
-#ifndef VK_USE_PLATFORM_ANDROID_KHR
         VkIcdSurface *icd_surface = (VkIcdSurface *)(pCreateInfo->surface);
         if (NULL != icd_surface->real_icd_surfaces) {
             if (NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {
@@ -511,7 +494,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_vkCreateSwapchainKHR(
                 return icd->CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain);
             }
         }
-#endif
         return icd->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
     }
     return VK_SUCCESS;
@@ -560,6 +542,40 @@ vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
     return disp->QueuePresentKHR(queue, pPresentInfo);
 }
 
+static VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance,
+                                              size_t base_size,
+                                              size_t platform_size,
+                                              bool create_icd_surfs) {
+    // Next, if so, proceed with the implementation of this function:
+    VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
+        instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    if (pIcdSurface != NULL) {
+        // Setup the new sizes and offsets so we can grow the structures in the
+        // future without having problems
+        pIcdSurface->base_size = (uint32_t)base_size;
+        pIcdSurface->platform_size = (uint32_t)platform_size;
+        pIcdSurface->non_platform_offset = (uint32_t)(
+            (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+        pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+        if (create_icd_surfs) {
+            pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+                instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
+                VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+            if (pIcdSurface->real_icd_surfaces == NULL) {
+                loader_instance_heap_free(instance, pIcdSurface);
+                pIcdSurface = NULL;
+            } else {
+                memset(pIcdSurface->real_icd_surfaces, 0,
+                       sizeof(VkSurfaceKHR) * instance->total_icd_count);
+            }
+        } else {
+            pIcdSurface->real_icd_surfaces = NULL;
+        }
+    }
+    return pIcdSurface;
+}
+
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 
 
@@ -583,6 +599,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(
     VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     VkResult vkRes = VK_SUCCESS;
+    // Initialize pSurface to NULL just to be safe.
+    *pSurface = VK_NULL_HANDLE;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_win32_surface_enabled) {
@@ -594,8 +612,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    VkIcdSurface *pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->win_surf.base),
+        sizeof(pIcdSurface->win_surf), true);
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -605,24 +624,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(
     pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance;
     pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd;
 
-    // Setup the new sizes and offsets so we can grow the structures in the
-    // future withouth having problems
-    pIcdSurface->base_size = sizeof(pIcdSurface->win_surf.base);
-    pIcdSurface->platform_size = sizeof(pIcdSurface->win_surf);
-    pIcdSurface->non_platform_offset = (uint32_t)(
-        (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
-    pIcdSurface->entire_size = sizeof(VkIcdSurface);
-
-    pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
-        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-    if (pIcdSurface == NULL) {
-        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
-        goto out;
-    }
-    memset(pIcdSurface->real_icd_surfaces, 0,
-           sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
-
     // Loop through each ICD and determine if they need to create a surface
     for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
         if (ptr_instance->icd_libs.list[i].interface_version >=
@@ -647,7 +648,7 @@ out:
         if (NULL != pIcdSurface->real_icd_surfaces) {
             for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
                 struct loader_icd *icd = &ptr_instance->icds[i];
-                if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+                if (NULL != (void*)pIcdSurface->real_icd_surfaces[i] &&
                     NULL != icd->DestroySurfaceKHR) {
                     icd->DestroySurfaceKHR(
                         icd->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
@@ -738,8 +739,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    VkIcdSurface *pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->mir_surf.base),
+        sizeof(pIcdSurface->mir_surf), true);
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -749,24 +751,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(
     pIcdSurface->mir_surf.connection = pCreateInfo->connection;
     pIcdSurface->mir_surf.mirSurface = pCreateInfo->mirSurface;
 
-    // Setup the new sizes and offsets so we can grow the structures in the
-    // future withouth having problems
-    pIcdSurface->base_size = sizeof(pIcdSurface->mir_surf.base);
-    pIcdSurface->platform_size = sizeof(pIcdSurface->mir_surf);
-    pIcdSurface->non_platform_offset = (uint32_t)(
-        (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
-    pIcdSurface->entire_size = sizeof(VkIcdSurface);
-
-    pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
-        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-    if (pIcdSurface == NULL) {
-        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
-        goto out;
-    }
-    memset(pIcdSurface->real_icd_surfaces, 0,
-           sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
-
     // Loop through each ICD and determine if they need to create a surface
     for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
         if (ptr_instance->icd_libs.list[i].interface_version >=
@@ -885,8 +869,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    VkIcdSurface *pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->wayland_surf.base),
+        sizeof(pIcdSurface->wayland_surf), true);
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -896,24 +881,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(
     pIcdSurface->wayland_surf.display = pCreateInfo->display;
     pIcdSurface->wayland_surf.surface = pCreateInfo->surface;
 
-    // Setup the new sizes and offsets so we can grow the structures in the
-    // future withouth having problems
-    pIcdSurface->base_size = sizeof(pIcdSurface->wayland_surf.base);
-    pIcdSurface->platform_size = sizeof(pIcdSurface->wayland_surf);
-    pIcdSurface->non_platform_offset = (uint32_t)(
-        (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
-    pIcdSurface->entire_size = sizeof(VkIcdSurface);
-
-    pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
-        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-    if (pIcdSurface == NULL) {
-        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
-        goto out;
-    }
-    memset(pIcdSurface->real_icd_surfaces, 0,
-           sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
-
     // Loop through each ICD and determine if they need to create a surface
     for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
         if (ptr_instance->icd_libs.list[i].interface_version >=
@@ -1033,8 +1000,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    VkIcdSurface *pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->xcb_surf.base),
+        sizeof(pIcdSurface->xcb_surf), true);
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -1044,24 +1012,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(
     pIcdSurface->xcb_surf.connection = pCreateInfo->connection;
     pIcdSurface->xcb_surf.window = pCreateInfo->window;
 
-    // Setup the new sizes and offsets so we can grow the structures in the
-    // future withouth having problems
-    pIcdSurface->base_size = sizeof(pIcdSurface->xcb_surf.base);
-    pIcdSurface->platform_size = sizeof(pIcdSurface->xcb_surf);
-    pIcdSurface->non_platform_offset = (uint32_t)(
-        (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
-    pIcdSurface->entire_size = sizeof(VkIcdSurface);
-
-    pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
-        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-    if (pIcdSurface == NULL) {
-        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
-        goto out;
-    }
-    memset(pIcdSurface->real_icd_surfaces, 0,
-           sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
-
     // Loop through each ICD and determine if they need to create a surface
     for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
         if (ptr_instance->icd_libs.list[i].interface_version >=
@@ -1180,8 +1130,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    VkIcdSurface *pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->xlib_surf.base),
+        sizeof(pIcdSurface->xlib_surf), true);
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -1191,24 +1142,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(
     pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy;
     pIcdSurface->xlib_surf.window = pCreateInfo->window;
 
-    // Setup the new sizes and offsets so we can grow the structures in the
-    // future withouth having problems
-    pIcdSurface->base_size = sizeof(pIcdSurface->xlib_surf.base);
-    pIcdSurface->platform_size = sizeof(pIcdSurface->xlib_surf);
-    pIcdSurface->non_platform_offset = (uint32_t)(
-        (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
-    pIcdSurface->entire_size = sizeof(VkIcdSurface);
-
-    pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
-        ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
-        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-    if (pIcdSurface == NULL) {
-        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
-        goto out;
-    }
-    memset(pIcdSurface->real_icd_surfaces, 0,
-           sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
-
     // Loop through each ICD and determine if they need to create a surface
     for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
         if (ptr_instance->icd_libs.list[i].interface_version >=
@@ -1599,8 +1532,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(
         return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
-    pIcdSurface = loader_instance_heap_alloc(inst, sizeof(VkIcdSurface),
-                                             VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    // The VK_KHR_display path will continue to use the old path (hence the
+    // false as the last parameter).
+    pIcdSurface =
+        AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base),
+                                 sizeof(pIcdSurface->display_surf), false);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -1614,15 +1550,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(
     pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
     pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
 
-    // Setup the new sizes and offsets so we can grow the structures in the
-    // future withouth having problems
-    pIcdSurface->real_icd_surfaces = NULL;
-    pIcdSurface->base_size = sizeof(pIcdSurface->display_surf.base);
-    pIcdSurface->platform_size = sizeof(pIcdSurface->display_surf);
-    pIcdSurface->non_platform_offset = (uint32_t)(
-        (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
-    pIcdSurface->entire_size = sizeof(VkIcdSurface);
-
     *pSurface = (VkSurfaceKHR)pIcdSurface;
 
     return VK_SUCCESS;