[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

vulkan: Changes to 'upstream-unstable'



 external_revisions/glslang_revision       |    2 
 external_revisions/spirv-headers_revision |    2 
 external_revisions/spirv-tools_revision   |    2 
 layers/core_validation.cpp                |  168 ++++++++++++++++++++++++++++-
 layers/core_validation_types.h            |    9 +
 layers/unique_objects.cpp                 |  173 ++++++++++++++++++++++++++++++
 layers/unique_objects.h                   |   10 +
 scripts/helper_file_generator.py          |   11 +
 scripts/loader_extension_generator.py     |   25 +---
 scripts/unique_objects_generator.py       |    4 
 10 files changed, 383 insertions(+), 23 deletions(-)

New commits:
commit ee3e734713237d812847e52978629ef760e591e7
Author: Mark Young <marky@lunarg.com>
Date:   Wed Mar 29 14:48:12 2017 -0600

    externals: Update to glslang fix commit

diff --git a/external_revisions/glslang_revision b/external_revisions/glslang_revision
index 962e447..08470fa 100644
--- a/external_revisions/glslang_revision
+++ b/external_revisions/glslang_revision
@@ -1 +1 @@
-9fb31ce8ecdac1e0c029729177144545186c509f
\ No newline at end of file
+714e58b2fc5a45714596e6aa2f6ac8f64260365c
\ No newline at end of file

commit fd27f52f4a2b0cac6bfe3dd75aa48a3750cb1bd4
Author: Mark Young <marky@lunarg.com>
Date:   Mon Mar 27 18:13:38 2017 -0600

    externals: Update to latest as of this morning

diff --git a/external_revisions/glslang_revision b/external_revisions/glslang_revision
index c88cf78..962e447 100644
--- a/external_revisions/glslang_revision
+++ b/external_revisions/glslang_revision
@@ -1 +1 @@
-e751bca75c059f18d16952ae73cde29a29b85cec
+9fb31ce8ecdac1e0c029729177144545186c509f
\ No newline at end of file
diff --git a/external_revisions/spirv-headers_revision b/external_revisions/spirv-headers_revision
index 6506006..5de12fb 100644
--- a/external_revisions/spirv-headers_revision
+++ b/external_revisions/spirv-headers_revision
@@ -1 +1 @@
-f61848a1151856f98ebc0ee66c39b8b7745a2a22
+6c08995e6e7b94129e6086c78198c77111f2f262
\ No newline at end of file
diff --git a/external_revisions/spirv-tools_revision b/external_revisions/spirv-tools_revision
index dc8bc68..05d0448 100644
--- a/external_revisions/spirv-tools_revision
+++ b/external_revisions/spirv-tools_revision
@@ -1 +1 @@
-c804c125c568914aabf4d734cf85923611bdfd21
+7fe8a57a5bd72094e91f9f93e51dac2f2461dcb4
\ No newline at end of file

commit 92469cdb064ad77096f933bb49dfe1389756766f
Author: Mark Young <marky@lunarg.com>
Date:   Fri Mar 24 07:51:14 2017 -0600

    externals: Fix bad Glsang/Spirv generation
    
    The version of Glslang/Spirv we were grabbing apparently included
    a bug which always inserted Nvidia code into anyone's generated
    Spirv.  This caused issues on AMD and Intel.
    
    Update to a newer version verified by AMD.

diff --git a/external_revisions/glslang_revision b/external_revisions/glslang_revision
index 2127105..c88cf78 100644
--- a/external_revisions/glslang_revision
+++ b/external_revisions/glslang_revision
@@ -1 +1 @@
-322cb1922e512b0e5f9804e7012a9b9b7f5b8df5
\ No newline at end of file
+e751bca75c059f18d16952ae73cde29a29b85cec
diff --git a/external_revisions/spirv-headers_revision b/external_revisions/spirv-headers_revision
index 329350d..6506006 100644
--- a/external_revisions/spirv-headers_revision
+++ b/external_revisions/spirv-headers_revision
@@ -1 +1 @@
-b6dca2397d512e4db62f051a47bb5334d5d44360
+f61848a1151856f98ebc0ee66c39b8b7745a2a22
diff --git a/external_revisions/spirv-tools_revision b/external_revisions/spirv-tools_revision
index 7c10d5a..dc8bc68 100644
--- a/external_revisions/spirv-tools_revision
+++ b/external_revisions/spirv-tools_revision
@@ -1 +1 @@
-c0949703b1264c33df45584efba50a8444b53022
+c804c125c568914aabf4d734cf85923611bdfd21

commit 3a93ad918f38940e5855297bfe940be91965881b
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Wed Mar 8 11:50:51 2017 -0700

    layers: Fix template_update errors in CV
    
    Tied UpdateDescriptorSetWithTemplate into UpdateDescriptorSet
    validation.
    
    Change-Id: I00fdd9b90f99b34bb7119eb9c8dd433571f22f1d

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 42c8737..ef20ce0 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -11496,11 +11496,88 @@ VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device,
     dev_data->dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
 }
 
+void PostCallRecordUpdateDescriptorSetWithTemplateKHR(layer_data *device_data, VkDescriptorSet descriptorSet,
+                                                      VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, const void *pData) {
+    auto const template_map_entry = device_data->desc_template_map.find(descriptorUpdateTemplate);
+    if (template_map_entry == device_data->desc_template_map.end()) {
+        assert(0);
+    }
+
+    auto const &create_info = template_map_entry->second->create_info;
+
+    // Create a vector of write structs
+    std::vector<VkWriteDescriptorSet> desc_writes;
+    auto layout_obj = GetDescriptorSetLayout(device_data, create_info.descriptorSetLayout);
+
+    // Create a WriteDescriptorSet struct for each template update entry
+    for (uint32_t i = 0; i < create_info.descriptorUpdateEntryCount; i++) {
+        auto binding_count = layout_obj->GetDescriptorCountFromBinding(create_info.pDescriptorUpdateEntries[i].dstBinding);
+        auto binding_being_updated = create_info.pDescriptorUpdateEntries[i].dstBinding;
+        auto dst_array_element = create_info.pDescriptorUpdateEntries[i].dstArrayElement;
+
+        for (uint32_t j = 0; j < create_info.pDescriptorUpdateEntries[i].descriptorCount; j++) {
+            desc_writes.emplace_back();
+            auto &write_entry = desc_writes.back();
+
+            size_t offset = create_info.pDescriptorUpdateEntries[i].offset + j * create_info.pDescriptorUpdateEntries[i].stride;
+            char *update_entry = (char *)(pData) + offset;
+
+            if (dst_array_element >= binding_count) {
+                dst_array_element = 0;
+                // Move to next binding having a non-zero binding count
+                do {
+                    binding_being_updated++;
+                    binding_count = layout_obj->GetDescriptorCountFromBinding(binding_being_updated);
+                } while (binding_count == 0);
+            }
+
+            write_entry.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+            write_entry.pNext = NULL;
+            write_entry.dstSet = descriptorSet;
+            write_entry.dstBinding = binding_being_updated;
+            write_entry.dstArrayElement = dst_array_element;
+            write_entry.descriptorCount = 1;
+            write_entry.descriptorType = create_info.pDescriptorUpdateEntries[i].descriptorType;
+
+            switch (create_info.pDescriptorUpdateEntries[i].descriptorType) {
+                case VK_DESCRIPTOR_TYPE_SAMPLER:
+                case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+                case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+                    write_entry.pImageInfo = reinterpret_cast<VkDescriptorImageInfo *>(update_entry);
+                    break;
+
+                case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+                case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+                case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+                case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+                    write_entry.pBufferInfo = reinterpret_cast<VkDescriptorBufferInfo *>(update_entry);
+                    break;
+
+                case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+                case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+                    write_entry.pTexelBufferView = reinterpret_cast<VkBufferView *>(update_entry);
+                    break;
+                default:
+                    assert(0);
+                    break;
+            }
+            dst_array_element++;
+        }
+    }
+    cvdescriptorset::PerformUpdateDescriptorSets(device_data, static_cast<uint32_t>(desc_writes.size()), desc_writes.data(), 0,
+                                                 NULL);
+}
+
 VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
                                                               VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
                                                               const void *pData) {
-    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
-    dev_data->dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
+    layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    device_data->dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
+
+    PostCallRecordUpdateDescriptorSetWithTemplateKHR(device_data, descriptorSet, descriptorUpdateTemplate, pData);
+
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,

commit 21aba97855f6b2504161697fd72e83081e9976d3
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Tue Mar 7 16:37:16 2017 -0700

    layers: Add UpdateTemplate Ext APIs to CV
    
    Added GPA hooks stub functions, and enables for four new extension
    APIs for VK_KHR_descriptor_update_template.
    
    Change-Id: Ifb8b3104030d3ff3da3af85039e85bb84f828872

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 4366704..42c8737 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -106,6 +106,7 @@ struct devExts {
     bool wsi_enabled;
     bool wsi_display_swapchain_enabled;
     bool nv_glsl_shader_enabled;
+    bool khr_descriptor_update_template_enabled;
     unordered_map<VkSwapchainKHR, unique_ptr<SWAPCHAIN_NODE>> swapchainMap;
     unordered_map<VkImage, VkSwapchainKHR> imageToSwapchainMap;
 };
@@ -171,6 +172,7 @@ struct layer_data {
     unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap;
     unordered_map<VkRenderPass, unique_ptr<RENDER_PASS_STATE>> renderPassMap;
     unordered_map<VkShaderModule, unique_ptr<shader_module>> shaderModuleMap;
+    unordered_map<VkDescriptorUpdateTemplateKHR, unique_ptr<TEMPLATE_STATE>> desc_template_map;
 
     VkDevice device = VK_NULL_HANDLE;
     VkPhysicalDevice physical_device = VK_NULL_HANDLE;
@@ -3827,6 +3829,7 @@ static void checkDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo,
     dev_data->device_extensions.wsi_enabled = false;
     dev_data->device_extensions.wsi_display_swapchain_enabled = false;
     dev_data->device_extensions.nv_glsl_shader_enabled = false;
+    dev_data->device_extensions.khr_descriptor_update_template_enabled = false;
 
     for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
@@ -3838,6 +3841,9 @@ static void checkDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo,
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NV_GLSL_SHADER_EXTENSION_NAME) == 0) {
             dev_data->device_extensions.nv_glsl_shader_enabled = true;
         }
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME) == 0) {
+            dev_data->device_extensions.khr_descriptor_update_template_enabled = true;
+        }
     }
 }
 
@@ -11457,10 +11463,59 @@ VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHX(
     return VK_ERROR_VALIDATION_FAILED_EXT;
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device,
+                                                                 const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
+                                                                 const VkAllocationCallbacks *pAllocator,
+                                                                 VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    safe_VkDescriptorUpdateTemplateCreateInfoKHR *local_create_info = NULL;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (pCreateInfo) {
+            local_create_info = new safe_VkDescriptorUpdateTemplateCreateInfoKHR(pCreateInfo);
+        }
+    }
+    VkResult result = dev_data->dispatch_table.CreateDescriptorUpdateTemplateKHR(
+        device, (const VkDescriptorUpdateTemplateCreateInfoKHR *)local_create_info, pAllocator, pDescriptorUpdateTemplate);
+    if (VK_SUCCESS == result) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        // Shadow template createInfo for later updates
+        std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_create_info));
+        dev_data->desc_template_map[*pDescriptorUpdateTemplate] = std::move(template_state);
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device,
+                                                              VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+                                                              const VkAllocationCallbacks *pAllocator) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    dev_data->desc_template_map.erase(descriptorUpdateTemplate);
+    lock.unlock();
+    dev_data->dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
+                                                              VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+                                                              const void *pData) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    dev_data->dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
+                                                               VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+                                                               VkPipelineLayout layout, uint32_t set, const void *pData) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+    dev_data->dispatch_table.CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData);
+}
+
 static PFN_vkVoidFunction intercept_core_instance_command(const char *name);
 
 static PFN_vkVoidFunction intercept_core_device_command(const char *name);
 
+static PFN_vkVoidFunction intercept_device_extension_command(const char *name, VkDevice device);
+
 static PFN_vkVoidFunction intercept_khr_swapchain_command(const char *name, VkDevice dev);
 
 static PFN_vkVoidFunction intercept_khr_surface_command(const char *name, VkInstance instance);
@@ -11469,16 +11524,14 @@ static PFN_vkVoidFunction
 intercept_extension_instance_commands(const char *name, VkInstance instance);
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice dev, const char *funcName) {
-    PFN_vkVoidFunction proc = intercept_core_device_command(funcName);
-    if (proc) return proc;
-
     assert(dev);
 
-    proc = intercept_khr_swapchain_command(funcName, dev);
+    PFN_vkVoidFunction proc = intercept_core_device_command(funcName);
+    if (!proc) proc = intercept_device_extension_command(funcName, dev);
+    if (!proc) proc = intercept_khr_swapchain_command(funcName, dev);
     if (proc) return proc;
 
     layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(dev), layer_data_map);
-
     auto &table = dev_data->dispatch_table;
     if (!table.GetDeviceProcAddr) return nullptr;
     return table.GetDeviceProcAddr(dev, funcName);
@@ -11672,6 +11725,34 @@ static PFN_vkVoidFunction intercept_core_device_command(const char *name) {
     return nullptr;
 }
 
+static PFN_vkVoidFunction intercept_device_extension_command(const char *name, VkDevice device) {
+    layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+
+    const struct {
+        const char *name;
+        PFN_vkVoidFunction proc;
+        bool enabled;
+    } device_extension_commands[] = {
+        {"vkCreateDescriptorUpdateTemplateKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateDescriptorUpdateTemplateKHR),
+         device_data->device_extensions.khr_descriptor_update_template_enabled},
+        {"vkDestroyDescriptorUpdateTemplateKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroyDescriptorUpdateTemplateKHR),
+         device_data->device_extensions.khr_descriptor_update_template_enabled},
+        {"vkUpdateDescriptorSetWithTemplateKHR", reinterpret_cast<PFN_vkVoidFunction>(UpdateDescriptorSetWithTemplateKHR),
+         device_data->device_extensions.khr_descriptor_update_template_enabled},
+        {"vkCmdPushDescriptorSetWithTemplateKHR", reinterpret_cast<PFN_vkVoidFunction>(CmdPushDescriptorSetWithTemplateKHR),
+         device_data->device_extensions.khr_descriptor_update_template_enabled},
+    };
+
+    if (!device_data || !device_data->device_extensions.khr_descriptor_update_template_enabled) return nullptr;
+
+    for (size_t i = 0; i < ARRAY_SIZE(device_extension_commands); i++) {
+        if (!strcmp(device_extension_commands[i].name, name) && device_extension_commands[i].enabled)
+            return device_extension_commands[i].proc;
+    }
+
+    return nullptr;
+}
+
 static PFN_vkVoidFunction intercept_khr_swapchain_command(const char *name, VkDevice dev) {
     static const struct {
         const char *name;
diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h
index 9f27acc..132a5cc 100644
--- a/layers/core_validation_types.h
+++ b/layers/core_validation_types.h
@@ -444,6 +444,15 @@ enum CBStatusFlagBits {
     // clang-format on
 };
 
+struct TEMPLATE_STATE {
+    VkDescriptorUpdateTemplateKHR desc_update_template;
+    safe_VkDescriptorUpdateTemplateCreateInfoKHR create_info;
+
+    TEMPLATE_STATE(VkDescriptorUpdateTemplateKHR update_template, safe_VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo)
+        : desc_update_template(update_template), create_info(*pCreateInfo) {}
+};
+
+
 struct QueryObject {
     VkQueryPool pool;
     uint32_t index;

commit b94a23bc6edaafbab92d9449749394936fe20510
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Mar 6 16:18:19 2017 -0700

    layers: Improve UpdateTemplate variable names
    
    Change-Id: I8e0d26b795fc9f2a2634f4de823967d3f16b15d9

diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp
index fd6c9d2..c94144f 100644
--- a/layers/unique_objects.cpp
+++ b/layers/unique_objects.cpp
@@ -613,24 +613,24 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device
                                                                  const VkAllocationCallbacks *pAllocator,
                                                                  VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate) {
     layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
-    safe_VkDescriptorUpdateTemplateCreateInfoKHR *local_pCreateInfo = NULL;
+    safe_VkDescriptorUpdateTemplateCreateInfoKHR *local_create_info = NULL;
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (pCreateInfo) {
-            local_pCreateInfo = new safe_VkDescriptorUpdateTemplateCreateInfoKHR(pCreateInfo);
+            local_create_info = new safe_VkDescriptorUpdateTemplateCreateInfoKHR(pCreateInfo);
             if (pCreateInfo->descriptorSetLayout) {
-                local_pCreateInfo->descriptorSetLayout =
+                local_create_info->descriptorSetLayout =
                     (VkDescriptorSetLayout)
                         dev_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->descriptorSetLayout)];
             }
             if (pCreateInfo->pipelineLayout) {
-                local_pCreateInfo->pipelineLayout =
+                local_create_info->pipelineLayout =
                     (VkPipelineLayout)dev_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->pipelineLayout)];
             }
         }
     }
     VkResult result = dev_data->device_dispatch_table->CreateDescriptorUpdateTemplateKHR(
-        device, (const VkDescriptorUpdateTemplateCreateInfoKHR *)local_pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
+        device, (const VkDescriptorUpdateTemplateCreateInfoKHR *)local_create_info, pAllocator, pDescriptorUpdateTemplate);
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         uint64_t unique_id = global_unique_id++;
@@ -638,7 +638,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device
         *pDescriptorUpdateTemplate = reinterpret_cast<VkDescriptorUpdateTemplateKHR &>(unique_id);
 
         // Shadow template createInfo for later updates
-        std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_pCreateInfo));
+        std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_create_info));
         dev_data->desc_template_map[unique_id] = std::move(template_state);
     }
     return result;
@@ -649,10 +649,10 @@ VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device,
                                                               const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    uint64_t descriptorUpdateTemplate_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
-    dev_data->desc_template_map.erase(descriptorUpdateTemplate_id);
-    descriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[descriptorUpdateTemplate_id];
-    dev_data->unique_id_mapping.erase(descriptorUpdateTemplate_id);
+    uint64_t descriptor_update_template_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
+    dev_data->desc_template_map.erase(descriptor_update_template_id);
+    descriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[descriptor_update_template_id];
+    dev_data->unique_id_mapping.erase(descriptor_update_template_id);
     lock.unlock();
     dev_data->device_dispatch_table->DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
 }
@@ -751,14 +751,14 @@ VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, V
                                                               VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
                                                               const void *pData) {
     layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
-    uint64_t handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
+    uint64_t template_handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
     {
         std::lock_guard<std::mutex> lock(global_lock);
         descriptorSet = (VkDescriptorSet)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(descriptorSet)];
-        descriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[handle];
+        descriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[template_handle];
     }
     void *unwrapped_buffer = nullptr;
-    unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(dev_data, handle, pData);
+    unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(dev_data, template_handle, pData);
     dev_data->device_dispatch_table->UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate,
                                                                         unwrapped_buffer);
     free(unwrapped_buffer);

commit b9c82a90689e9e9c776118fb99a8647915c68852
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Mar 6 09:00:21 2017 -0700

    layers: Parse extension buffer to unwrap handles
    
    The UpdateDescriptorSetWithTemplate extension API contains a
    parameter which is a buffer containing Vulkan objects. To get this
    through to the driver using the UniqueObjects layer, these handles
    must get unwrapped.
    
    Change-Id: I91f573f696eafc00957cbff502aaa8ce96c4e1ba

diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp
index eb5680c..fd6c9d2 100644
--- a/layers/unique_objects.cpp
+++ b/layers/unique_objects.cpp
@@ -20,6 +20,8 @@
  * Author: Mark Lobodzinski <mark@lunarg.com>
  */
 
+#define NOMINMAX
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,6 +29,7 @@
 #include <vector>
 #include <list>
 #include <memory>
+#include <algorithm>
 
 // For Windows, this #include must come before other Vk headers.
 #include "vk_loader_platform.h"
@@ -654,17 +657,111 @@ VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device,
     dev_data->device_dispatch_table->DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
 }
 
+void *BuildUnwrappedUpdateTemplateBuffer(layer_data *dev_data, uint64_t descriptorUpdateTemplate, const void *pData) {
+    auto const template_map_entry = dev_data->desc_template_map.find(descriptorUpdateTemplate);
+    if (template_map_entry == dev_data->desc_template_map.end()) {
+        assert(0);
+    }
+    auto const &create_info = template_map_entry->second->create_info;
+    size_t allocation_size = 0;
+    std::vector<std::tuple<size_t, VkDebugReportObjectTypeEXT, void *>> template_entries;
+
+    for (uint32_t i = 0; i < create_info.descriptorUpdateEntryCount; i++) {
+        for (uint32_t j = 0; j < create_info.pDescriptorUpdateEntries[i].descriptorCount; j++) {
+            size_t offset = create_info.pDescriptorUpdateEntries[i].offset + j * create_info.pDescriptorUpdateEntries[i].stride;
+            char *update_entry = (char *)(pData) + offset;
+
+            switch (create_info.pDescriptorUpdateEntries[i].descriptorType) {
+                case VK_DESCRIPTOR_TYPE_SAMPLER:
+                case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+                case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
+                    auto image_entry = reinterpret_cast<VkDescriptorImageInfo *>(update_entry);
+                    allocation_size = std::max(allocation_size, offset + sizeof(VkDescriptorImageInfo));
+
+                    VkDescriptorImageInfo *wrapped_entry = new VkDescriptorImageInfo(*image_entry);
+                    wrapped_entry->sampler = reinterpret_cast<VkSampler &>(
+                        dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(image_entry->sampler)]);
+                    wrapped_entry->imageView = reinterpret_cast<VkImageView &>(
+                        dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(image_entry->imageView)]);
+                    template_entries.emplace_back(offset, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                                                  reinterpret_cast<void *>(wrapped_entry));
+                } break;
+
+                case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+                case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+                case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+                case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
+                    auto buffer_entry = reinterpret_cast<VkDescriptorBufferInfo *>(update_entry);
+                    allocation_size = std::max(allocation_size, offset + sizeof(VkDescriptorBufferInfo));
+
+                    VkDescriptorBufferInfo *wrapped_entry = new VkDescriptorBufferInfo(*buffer_entry);
+                    wrapped_entry->buffer =
+                        reinterpret_cast<VkBuffer &>(dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(buffer_entry->buffer)]);
+                    template_entries.emplace_back(offset, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+                                                  reinterpret_cast<void *>(wrapped_entry));
+                } break;
+
+                case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+                case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
+                    allocation_size = std::max(allocation_size, offset + sizeof(VkBufferView));
+
+                    VkBufferView *wrapped_entry = new VkBufferView;
+                    *wrapped_entry =
+                        reinterpret_cast<VkBufferView &>(dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(update_entry)]);
+                    template_entries.emplace_back(offset, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT,
+                                                  reinterpret_cast<void *>(wrapped_entry));
+                } break;
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+    }
+    // Allocate required buffer size and populate with source/unwrapped data
+    void *unwrapped_data = malloc(allocation_size);
+    for (auto &this_entry : template_entries) {
+        VkDebugReportObjectTypeEXT type = std::get<1>(this_entry);
+        void *destination = (char *)unwrapped_data + std::get<0>(this_entry);
+        void *source = (char *)std::get<2>(this_entry);
+
+        switch (type) {
+            case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
+                *(reinterpret_cast<VkDescriptorImageInfo *>(destination)) = *(reinterpret_cast<VkDescriptorImageInfo *>(source));
+                delete reinterpret_cast<VkDescriptorImageInfo *>(source);
+                break;
+            case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
+                *(reinterpret_cast<VkDescriptorBufferInfo *>(destination)) = *(reinterpret_cast<VkDescriptorBufferInfo *>(source));
+                delete reinterpret_cast<VkDescriptorBufferInfo *>(source);
+                break;
+            case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT:
+                *(reinterpret_cast<VkBufferView *>(destination)) = *(reinterpret_cast<VkBufferView *>(source));
+                delete reinterpret_cast<VkBufferView *>(source);
+                break;
+            default:
+                assert(0);
+                break;
+        }
+    }
+    return (void *)unwrapped_data;
+}
+
 VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
                                                               VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
                                                               const void *pData) {
     layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    uint64_t handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
     {
         std::lock_guard<std::mutex> lock(global_lock);
         descriptorSet = (VkDescriptorSet)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(descriptorSet)];
-        descriptorUpdateTemplate =
-            (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(descriptorUpdateTemplate)];
+        descriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[handle];
     }
-    dev_data->device_dispatch_table->UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
+    void *unwrapped_buffer = nullptr;
+    unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(dev_data, handle, pData);
+    dev_data->device_dispatch_table->UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate,
+                                                                        unwrapped_buffer);
+    free(unwrapped_buffer);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,

commit b68032cf4a87fc1e943d65ab00e229cd6b43f7df
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Fri Mar 3 10:28:21 2017 -0700

    layers: Create desc_update_template map for new objs
    
    Store unique_objects DescriptorUpdateTemplate data in a map
    for parsing UpdateTempate buffers.
    
    Change-Id: Iab0d95a1aa2f309a3d33c8859b16543f98ca549c

diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp
index cf7891a..eb5680c 100644
--- a/layers/unique_objects.cpp
+++ b/layers/unique_objects.cpp
@@ -628,12 +628,15 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device
     }
     VkResult result = dev_data->device_dispatch_table->CreateDescriptorUpdateTemplateKHR(
         device, (const VkDescriptorUpdateTemplateCreateInfoKHR *)local_pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
-    if (local_pCreateInfo) delete local_pCreateInfo;
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         uint64_t unique_id = global_unique_id++;
         dev_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pDescriptorUpdateTemplate);
         *pDescriptorUpdateTemplate = reinterpret_cast<VkDescriptorUpdateTemplateKHR &>(unique_id);
+
+        // Shadow template createInfo for later updates
+        std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_pCreateInfo));
+        dev_data->desc_template_map[unique_id] = std::move(template_state);
     }
     return result;
 }
@@ -644,6 +647,7 @@ VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device,
     layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     uint64_t descriptorUpdateTemplate_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
+    dev_data->desc_template_map.erase(descriptorUpdateTemplate_id);
     descriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[descriptorUpdateTemplate_id];
     dev_data->unique_id_mapping.erase(descriptorUpdateTemplate_id);
     lock.unlock();
diff --git a/layers/unique_objects.h b/layers/unique_objects.h
index fb46b77..eebb01e 100644
--- a/layers/unique_objects.h
+++ b/layers/unique_objects.h
@@ -33,6 +33,14 @@ namespace unique_objects {
 // All increments must be guarded by global_lock
 static uint64_t global_unique_id = 1;
 
+struct TEMPLATE_STATE {
+    VkDescriptorUpdateTemplateKHR desc_update_template;
+    safe_VkDescriptorUpdateTemplateCreateInfoKHR create_info;
+
+    TEMPLATE_STATE(VkDescriptorUpdateTemplateKHR update_template, safe_VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo)
+        : desc_update_template(update_template), create_info(*pCreateInfo) {}
+};
+
 struct layer_data {
     VkInstance instance;
 
@@ -47,6 +55,8 @@ struct layer_data {
     VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
     VkDebugReportCallbackEXT *tmp_callbacks;
 
+    std::unordered_map<uint64_t, std::unique_ptr<TEMPLATE_STATE>> desc_template_map;
+
     bool wsi_enabled;
     std::unordered_map<uint64_t, uint64_t> unique_id_mapping;  // Map uniqueID to actual object handle
     VkPhysicalDevice gpu;

commit 7af70862baf5a0fa397f5548e98c08f7d7cb8754
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Fri Mar 3 08:40:16 2017 -0700

    layers: Move DescriptorUpdateTemplate functions
    
    In unique_objects, moved these functions from being auto-generated to
    being manually written.
    
    Change-Id: Iae7ccac0ad51d57826104bd0532742a098c673ce

diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp
index ea02869..cf7891a 100644
--- a/layers/unique_objects.cpp
+++ b/layers/unique_objects.cpp
@@ -605,6 +605,78 @@ VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchai
     return result;
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device,
+                                                                 const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
+                                                                 const VkAllocationCallbacks *pAllocator,
+                                                                 VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    safe_VkDescriptorUpdateTemplateCreateInfoKHR *local_pCreateInfo = NULL;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (pCreateInfo) {
+            local_pCreateInfo = new safe_VkDescriptorUpdateTemplateCreateInfoKHR(pCreateInfo);
+            if (pCreateInfo->descriptorSetLayout) {
+                local_pCreateInfo->descriptorSetLayout =
+                    (VkDescriptorSetLayout)
+                        dev_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->descriptorSetLayout)];
+            }
+            if (pCreateInfo->pipelineLayout) {
+                local_pCreateInfo->pipelineLayout =
+                    (VkPipelineLayout)dev_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->pipelineLayout)];
+            }
+        }
+    }
+    VkResult result = dev_data->device_dispatch_table->CreateDescriptorUpdateTemplateKHR(
+        device, (const VkDescriptorUpdateTemplateCreateInfoKHR *)local_pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
+    if (local_pCreateInfo) delete local_pCreateInfo;
+    if (VK_SUCCESS == result) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        uint64_t unique_id = global_unique_id++;
+        dev_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pDescriptorUpdateTemplate);
+        *pDescriptorUpdateTemplate = reinterpret_cast<VkDescriptorUpdateTemplateKHR &>(unique_id);
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device,
+                                                              VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+                                                              const VkAllocationCallbacks *pAllocator) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    uint64_t descriptorUpdateTemplate_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
+    descriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[descriptorUpdateTemplate_id];
+    dev_data->unique_id_mapping.erase(descriptorUpdateTemplate_id);
+    lock.unlock();
+    dev_data->device_dispatch_table->DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet,
+                                                              VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+                                                              const void *pData) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        descriptorSet = (VkDescriptorSet)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(descriptorSet)];
+        descriptorUpdateTemplate =
+            (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(descriptorUpdateTemplate)];
+    }
+    dev_data->device_dispatch_table->UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
+                                                               VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+                                                               VkPipelineLayout layout, uint32_t set, const void *pData) {
+    layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        descriptorUpdateTemplate =
+            (VkDescriptorUpdateTemplateKHR)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(descriptorUpdateTemplate)];
+        layout = (VkPipelineLayout)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(layout)];
+    }
+    dev_data->device_dispatch_table->CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set,
+                                                                         pData);
+}
+
 #ifndef __ANDROID__
 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
                                                                      VkDisplayPropertiesKHR *pProperties) {
diff --git a/scripts/unique_objects_generator.py b/scripts/unique_objects_generator.py
index fdf4c38..bafb7ae 100644
--- a/scripts/unique_objects_generator.py
+++ b/scripts/unique_objects_generator.py
@@ -140,6 +140,10 @@ class UniqueObjectsOutputGenerator(OutputGenerator):
             'vkEnumerateInstanceLayerProperties',
             'vkEnumerateDeviceLayerProperties',
             'vkEnumerateInstanceExtensionProperties',
+            'vkCreateDescriptorUpdateTemplateKHR',
+            'vkDestroyDescriptorUpdateTemplateKHR',
+            'vkUpdateDescriptorSetWithTemplateKHR',
+            'vkCmdPushDescriptorSetWithTemplateKHR',
             ]
         # Commands shadowed by interface functions and are not implemented
         self.interface_functions = [

commit 3ec9a0c95f1f29c40e1f1f18afea8c3be441a674
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Mar 6 08:59:14 2017 -0700

    scripts: Allow safe_structs to handle KHR extensions
    
    Deep copies are needed for some of the new extensions.
    
    Change-Id: I7e77fe30a87129aa720225ae16eb87cdba8e626e

diff --git a/scripts/helper_file_generator.py b/scripts/helper_file_generator.py
index 97fde4b..2e7c7b2 100644
--- a/scripts/helper_file_generator.py
+++ b/scripts/helper_file_generator.py
@@ -525,9 +525,18 @@ class HelperFileOutputGenerator(OutputGenerator):
     # safe_struct source -- create bodies of safe struct helper functions
     def GenerateSafeStructSource(self):
         safe_struct_body = []
+        wsi_structs = ['VkXlibSurfaceCreateInfoKHR',
+                       'VkXcbSurfaceCreateInfoKHR',
+                       'VkWaylandSurfaceCreateInfoKHR',
+                       'VkMirSurfaceCreateInfoKHR',
+                       'VkAndroidSurfaceCreateInfoKHR',
+                       'VkWin32SurfaceCreateInfoKHR'
+                       ]
         for item in self.structMembers:
             if self.NeedSafeStruct(item) == False:
                 continue
+            if item.name in wsi_structs:
+                continue
             if item.ifdef_protect != None:
                 safe_struct_body.append("#ifdef %s\n" % item.ifdef_protect)
             ss_name = "safe_%s" % item.name
@@ -583,7 +592,7 @@ class HelperFileOutputGenerator(OutputGenerator):
                         m_type = 'safe_%s' % member.type
                 if member.ispointer and 'safe_' not in m_type and self.TypeContainsObjectHandle(member.type, False) == False:
                     # Ptr types w/o a safe_struct, for non-null case need to allocate new ptr and copy data in
-                    if 'KHR' in ss_name or m_type in ['void', 'char']:
+                    if m_type in ['void', 'char']:
                         # For these exceptions just copy initial value over for now
                         init_list += '\n    %s(in_struct->%s),' % (member.name, member.name)
                         init_func_txt += '    %s = in_struct->%s;\n' % (member.name, member.name)

commit cc143ca154d63350c4136dcde8de774033e81be8
Author: Mark Young <marky@lunarg.com>
Date:   Mon Mar 6 15:27:03 2017 -0700

    externals: Update glslang revision
    
    Update the glslang revision to use the latest with changes for
    recent extensions made by Daniel Koch.
    
    Change-Id: Ib76330deefda46b5f76609ed2f15f589563077ee

diff --git a/external_revisions/glslang_revision b/external_revisions/glslang_revision
index 64e3226..2127105 100644
--- a/external_revisions/glslang_revision
+++ b/external_revisions/glslang_revision
@@ -1 +1 @@
-8f674e821e1e5f628474b21d7fe21af2e86b5fb4
+322cb1922e512b0e5f9804e7012a9b9b7f5b8df5
\ No newline at end of file

commit d3c567074016b64c763d43319148a2533e6dd128
Author: Mark Young <marky@lunarg.com>
Date:   Wed Mar 1 16:22:23 2017 -0700

    scripts: Update loader automation
    
    Merge a few if's together to make the code easier to follow.
    
    Change-Id: I2453c8217da81befb4f44af19241c13c4aaef8af

diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py
index 1d2d984..1aafd84 100644
--- a/scripts/loader_extension_generator.py
+++ b/scripts/loader_extension_generator.py
@@ -1095,9 +1095,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
                     if has_surface == 1:
                         funcs += '    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);\n'
                         funcs += '    uint8_t icd_index = phys_dev_term->icd_index;\n'
-                        funcs += '    if (NULL != icd_surface->real_icd_surfaces) {\n'
-                        funcs += '        if (NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {\n'
-                        funcs += '        ' + return_prefix + 'icd_term->dispatch.'
+                        funcs += '    if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {\n'
+                        funcs += '    ' + return_prefix + 'icd_term->dispatch.'
                         funcs += base_name
                         funcs += '('
                         count = 0
@@ -1115,8 +1114,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
                             count += 1
                         funcs += ');\n'
                         if not has_return_type:
-                            funcs += '            return;\n'
-                        funcs += '        }\n'
+                            funcs += '        return;\n'
                         funcs += '    }\n'
 
                     funcs += return_prefix
@@ -1142,9 +1140,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
                     funcs += '    struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);\n'
                     funcs += '    if (NULL != icd_term && NULL != icd_term->dispatch.%s) {\n' % base_name
                     funcs += '        VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)%s;\n' % (surface_var_name)
-                    funcs += '        if (NULL != icd_surface->real_icd_surfaces) {\n'
-                    funcs += '            if ((VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {\n'
-                    funcs += '            %sicd_term->dispatch.%s(' % (return_prefix, base_name)
+                    funcs += '        if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {\n'
+                    funcs += '        %sicd_term->dispatch.%s(' % (return_prefix, base_name)
                     count = 0
                     for param in ext_cmd.params:
                         if count != 0:
@@ -1159,9 +1156,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
                     funcs += ');\n'
                     if not has_return_type:
                         funcs += '                return;\n'
-                    funcs += '            }\n'
                     funcs += '        }\n'
-                    funcs += '        %sicd_term->dispatch.%s(' % (return_prefix, base_name)
+                    funcs += '    %sicd_term->dispatch.%s(' % (return_prefix, base_name)
                     count = 0
                     for param in ext_cmd.params:
                         if count != 0:

commit 44a0b8322696241524a5b41e3b5cfd2913720a9d
Author: James Jones <jajones@nvidia.com>
Date:   Tue Feb 28 17:26:09 2017 -0800

    loader: Fix handling of surface parameters
    
    The loader code generation scripts had a bug that
    caused all the surface->ICD surface translation C
    code to be placed inside a block that only ran if
    the ICD didn't support the extension function,
    making it effectively a no-op.  ICDs that
    supported the extension were instead called with
    the un-translated surface handle, which could
    cause a crash if they were expecting their local
    surface handle.
    
    Also, speculatively fix up return handling in this
    same class of functions by handling the void
    return type.

diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py
index 105073d..1d2d984 100644
--- a/scripts/loader_extension_generator.py
+++ b/scripts/loader_extension_generator.py
@@ -1090,13 +1090,14 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
                     funcs += '                   "ICD associated with VkPhysicalDevice does not support '
                     funcs += base_name
                     funcs += '");\n'
+                    funcs += '    }\n'
 
                     if has_surface == 1:
-                        funcs += '        VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);\n'
-                        funcs += '        uint8_t icd_index = phys_dev_term->icd_index;\n'
-                        funcs += '        if (NULL != icd_surface->real_icd_surfaces) {\n'
-                        funcs += '            if (NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {\n'
-                        funcs += '                return icd_term->dispatch.'
+                        funcs += '    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);\n'
+                        funcs += '    uint8_t icd_index = phys_dev_term->icd_index;\n'
+                        funcs += '    if (NULL != icd_surface->real_icd_surfaces) {\n'
+                        funcs += '        if (NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {\n'
+                        funcs += '        ' + return_prefix + 'icd_term->dispatch.'
                         funcs += base_name
                         funcs += '('
                         count = 0
@@ -1113,10 +1114,10 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
 
                             count += 1
                         funcs += ');\n'
-                        funcs += '            }\n'
+                        if not has_return_type:
+                            funcs += '            return;\n'
                         funcs += '        }\n'
-
-                    funcs += '    }\n'
+                        funcs += '    }\n'
 
                     funcs += return_prefix
                     funcs += 'icd_term->dispatch.'
@@ -1160,7 +1161,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
                         funcs += '                return;\n'
                     funcs += '            }\n'
                     funcs += '        }\n'
-                    funcs += '    %sicd_term->dispatch.%s(' % (return_prefix, base_name)
+                    funcs += '        %sicd_term->dispatch.%s(' % (return_prefix, base_name)
                     count = 0
                     for param in ext_cmd.params:
                         if count != 0:
@@ -1168,7 +1169,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
                         funcs += param.name
                         count += 1
                     funcs += ');\n'
-                    funcs += '     }\n'
+                    funcs += '    }\n'
                     if has_return_type:
                         funcs += '    return VK_SUCCESS;\n'
 


Reply to: