loader: Restore pNext data in CreateDevice
authorJoey Bzdek <joey@lunarg.com>
Mon, 23 Oct 2017 23:13:33 +0000 (17:13 -0600)
committerLenny Komow <lenny@lunarg.com>
Fri, 19 Jan 2018 23:43:48 +0000 (16:43 -0700)
In the terminator for CreateDevice, the
VkDeviceGroupDeviceCreateInfoKHX struct in the pNext chain is
replaced by a copy that has VkPhysicalDevice handles remapped. At the
end of the terminator, restore the modified pNext pointer to
partially comply to the const argument and give consistent behavior
to the caller.

Change-Id: I83a60a0102a736d056729383733e62b38b0ace2c

loader/loader.c

index e65b3ba..5ac8632 100644 (file)
@@ -5178,6 +5178,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(VkPhysicalDevice physical
     PFN_vkCreateDevice fpCreateDevice = icd_term->dispatch.CreateDevice;
     struct loader_extension_list icd_exts;
 
+    struct VkStructureHeader *caller_dgci_container = NULL;
+    VkDeviceGroupDeviceCreateInfoKHX *caller_dgci = NULL;
+
     dev->phys_dev_term = phys_dev_term;
 
     icd_exts.list = NULL;
@@ -5271,6 +5274,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(VkPhysicalDevice physical
                     }
                     temp_struct->pPhysicalDevices = phys_dev_array;
 
+                    // Keep track of pointers to restore pNext chain before returning
+                    caller_dgci_container = pPrev;
+                    caller_dgci = cur_struct;
+
                     // Replace the old struct in the pNext chain with this one.
                     pPrev->pNext = (const void *)temp_struct;
                     pNext = (struct VkStructureHeader *)(temp_struct);
@@ -5362,6 +5369,12 @@ out:
         loader_destroy_generic_list(icd_term->this_instance, (struct loader_generic_list *)&icd_exts);
     }
 
+    // Restore pNext pointer to old VkDeviceGroupDeviceCreateInfoKHX
+    // in the chain to maintain consistency for the caller.
+    if (caller_dgci_container != NULL) {
+        caller_dgci_container->pNext = caller_dgci;
+    }
+
     return res;
 }