layers: Normalize CreateDevice for GPU param change

GPU Validation needs to change the createinfo parameter.

Change-Id: Ibe5b4bf21143c4969473686d95aba0a5428fcffa
diff --git a/layers/core_dispatch.cpp b/layers/core_dispatch.cpp
index dba6105..b07cc9c 100644
--- a/layers/core_dispatch.cpp
+++ b/layers/core_dispatch.cpp
@@ -147,18 +147,12 @@
 
     // Advance the link info for the next element on the chain
     chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+    std::unique_ptr<safe_VkDeviceCreateInfo> modified_create_info(new safe_VkDeviceCreateInfo(pCreateInfo));
+    PreCallRecordCreateDevice(gpu, pCreateInfo, pAllocator, pDevice, modified_create_info);
 
-    // GPU Validation can possibly turn on device features, so give it a chance to change the create info.
-    std::unique_ptr<safe_VkDeviceCreateInfo> gpu_create_info;
-    if (instance_data->enabled.gpu_validation) {
-        VkPhysicalDeviceFeatures supported_features;
-        instance_data->dispatch_table.GetPhysicalDeviceFeatures(gpu, &supported_features);
-        gpu_create_info = GpuPreCallRecordCreateDevice(gpu, pCreateInfo, &supported_features);
-        pCreateInfo = reinterpret_cast<VkDeviceCreateInfo *>(gpu_create_info.get());
-    }
     lock.unlock();
 
-    VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+    VkResult result = fpCreateDevice(gpu, reinterpret_cast<VkDeviceCreateInfo *>(modified_create_info.get()), pAllocator, pDevice);
     if (result != VK_SUCCESS) {
         return result;
     }
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index abec27f..8ea1efc 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -2441,6 +2441,17 @@
     return skip;
 }
 
+void PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
+    VkDevice* pDevice, std::unique_ptr<safe_VkDeviceCreateInfo> &modified_create_info) {
+    instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map);
+    // GPU Validation can possibly turn on device features, so give it a chance to change the create info.
+    if (instance_data->enabled.gpu_validation) {
+        VkPhysicalDeviceFeatures supported_features;
+        instance_data->dispatch_table.GetPhysicalDeviceFeatures(gpu, &supported_features);
+        GpuPreCallRecordCreateDevice(gpu, modified_create_info, &supported_features);
+    }
+}
+
 void PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
                                 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
     instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map);
diff --git a/layers/core_validation.h b/layers/core_validation.h
index 3f476ff..39599a2 100644
--- a/layers/core_validation.h
+++ b/layers/core_validation.h
@@ -1435,6 +1435,8 @@
                                   VkInstance* pInstance, VkResult result);
 bool PreCallValidateCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
                                  const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
+void PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
+                               VkDevice* pDevice, std::unique_ptr<safe_VkDeviceCreateInfo> &modified_create_info);
 void PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo,
                                 const VkAllocationCallbacks* pAllocator, VkDevice* pDevice, VkResult result);
 bool PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
diff --git a/layers/gpu_validation.cpp b/layers/gpu_validation.cpp
index 4419a52..fe6851d 100644
--- a/layers/gpu_validation.cpp
+++ b/layers/gpu_validation.cpp
@@ -277,20 +277,18 @@
 }
 
 // Turn on necessary device features.
-std::unique_ptr<safe_VkDeviceCreateInfo> GpuPreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
+void GpuPreCallRecordCreateDevice(VkPhysicalDevice gpu, std::unique_ptr<safe_VkDeviceCreateInfo> &create_info,
                                                                       VkPhysicalDeviceFeatures *supported_features) {
-    std::unique_ptr<safe_VkDeviceCreateInfo> new_info(new safe_VkDeviceCreateInfo(create_info));
     if (supported_features->fragmentStoresAndAtomics || supported_features->vertexPipelineStoresAndAtomics) {
         VkPhysicalDeviceFeatures new_features = {};
-        if (new_info->pEnabledFeatures) {
-            new_features = *new_info->pEnabledFeatures;
+        if (create_info->pEnabledFeatures) {
+            new_features = *create_info->pEnabledFeatures;
         }
         new_features.fragmentStoresAndAtomics = supported_features->fragmentStoresAndAtomics;
         new_features.vertexPipelineStoresAndAtomics = supported_features->vertexPipelineStoresAndAtomics;
-        delete new_info->pEnabledFeatures;
-        new_info->pEnabledFeatures = new VkPhysicalDeviceFeatures(new_features);
+        delete create_info->pEnabledFeatures;
+        create_info->pEnabledFeatures = new VkPhysicalDeviceFeatures(new_features);
     }
-    return new_info;
 }
 
 // Perform initializations that can be done at Create Device time.
diff --git a/layers/gpu_validation.h b/layers/gpu_validation.h
index eb19ff9..3dad9e5 100644
--- a/layers/gpu_validation.h
+++ b/layers/gpu_validation.h
@@ -100,8 +100,8 @@
 using lock_guard_t = std::lock_guard<mutex_t>;
 using unique_lock_t = std::unique_lock<mutex_t>;
 
-std::unique_ptr<safe_VkDeviceCreateInfo> GpuPreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
-                                                                      VkPhysicalDeviceFeatures *supported_features);
+void GpuPreCallRecordCreateDevice(VkPhysicalDevice gpu, std::unique_ptr<safe_VkDeviceCreateInfo> &modified_create_info,
+                                  VkPhysicalDeviceFeatures *supported_features);
 void GpuPostCallRecordCreateDevice(layer_data *dev_data);
 void GpuPreCallRecordDestroyDevice(layer_data *dev_data);
 void GpuPreCallRecordFreeCommandBuffers(layer_data *dev_data, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);
diff --git a/scripts/layer_chassis_generator.py b/scripts/layer_chassis_generator.py
index 690442a..a7f3318 100644
--- a/scripts/layer_chassis_generator.py
+++ b/scripts/layer_chassis_generator.py
@@ -657,6 +657,8 @@
         item->device_extensions = device_extensions;
     }
 
+    std::unique_ptr<safe_VkDeviceCreateInfo> modified_create_info(new safe_VkDeviceCreateInfo(pCreateInfo));
+
     bool skip = false;
     for (auto intercept : instance_interceptor->object_dispatch) {
         auto lock = intercept->write_lock();
@@ -665,10 +667,10 @@
     }
     for (auto intercept : instance_interceptor->object_dispatch) {
         auto lock = intercept->write_lock();
-        intercept->PreCallRecordCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+        intercept->PreCallRecordCreateDevice(gpu, pCreateInfo, pAllocator, pDevice, modified_create_info);
     }
 
-    VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+    VkResult result = fpCreateDevice(gpu, reinterpret_cast<VkDeviceCreateInfo *>(modified_create_info.get()), pAllocator, pDevice);
     if (result != VK_SUCCESS) {
         return result;
     }
@@ -1087,6 +1089,11 @@
         virtual void PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets, VkResult result, void* ads_state)  {
             PostCallRecordAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets, result);
         };
+
+        // Modify a parameter to CreateDevice
+        virtual void PreCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice, std::unique_ptr<safe_VkDeviceCreateInfo> &modified_create_info) {
+            PreCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+        };
 """
 
     inline_custom_source_postamble = """