aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJeff Bolz <jbolz@nvidia.com>2019-08-20 08:58:51 -0500
committerMark Lobodzinski <mark@lunarg.com>2019-08-20 14:29:37 -0600
commit89b9a5030ae96c9a5e3df95833baf1fbf1ab7b8a (patch)
tree983fd7a1f2ba2489e9fd56c700f6499541d83472 /scripts
parent2711f53975317e8ec10e26ee3556722556b789ba (diff)
downloadvulkan-validation-layers-89b9a5030ae96c9a5e3df95833baf1fbf1ab7b8a.tar.gz
layers: Use concurrent_unordered_map in dispatcher
Use a concurrent_unordered_map for object tracking in dispatch. Add a vl_concurrent_unordered_map class that acts like an unordered_map but internally synchronizes concurrent accesses, and split the locks into 2^N buckets. Change-Id: If639feb0c53315888e057b1d91ad5da10a9d65c1
Diffstat (limited to 'scripts')
-rw-r--r--scripts/layer_chassis_dispatch_generator.py162
-rw-r--r--scripts/layer_chassis_generator.py36
2 files changed, 107 insertions, 91 deletions
diff --git a/scripts/layer_chassis_dispatch_generator.py b/scripts/layer_chassis_dispatch_generator.py
index b49f77e0b..977824b2d 100644
--- a/scripts/layer_chassis_dispatch_generator.py
+++ b/scripts/layer_chassis_dispatch_generator.py
@@ -148,7 +148,6 @@ VkResult DispatchCreateComputePipelines(VkDevice device, VkPipelineCache pipelin
pCreateInfos, pAllocator, pPipelines);
safe_VkComputePipelineCreateInfo *local_pCreateInfos = NULL;
if (pCreateInfos) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount];
for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
@@ -164,7 +163,6 @@ VkResult DispatchCreateComputePipelines(VkDevice device, VkPipelineCache pipelin
}
}
if (pipelineCache) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
pipelineCache = layer_data->Unwrap(pipelineCache);
}
@@ -172,7 +170,6 @@ VkResult DispatchCreateComputePipelines(VkDevice device, VkPipelineCache pipelin
local_pCreateInfos->ptr(), pAllocator, pPipelines);
delete[] local_pCreateInfos;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t i = 0; i < createInfoCount; ++i) {
if (pPipelines[i] != VK_NULL_HANDLE) {
pPipelines[i] = layer_data->WrapNew(pPipelines[i]);
@@ -191,7 +188,7 @@ VkResult DispatchCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipeli
safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = nullptr;
if (pCreateInfos) {
local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount];
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ read_dispatch_lock_guard_t lock(dispatch_lock);
for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
bool uses_color_attachment = false;
bool uses_depthstencil_attachment = false;
@@ -227,7 +224,6 @@ VkResult DispatchCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipeli
}
}
if (pipelineCache) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
pipelineCache = layer_data->Unwrap(pipelineCache);
}
@@ -235,7 +231,6 @@ VkResult DispatchCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipeli
local_pCreateInfos->ptr(), pAllocator, pPipelines);
delete[] local_pCreateInfos;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t i = 0; i < createInfoCount; ++i) {
if (pPipelines[i] != VK_NULL_HANDLE) {
pPipelines[i] = layer_data->WrapNew(pPipelines[i]);
@@ -270,7 +265,7 @@ VkResult DispatchCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo
VkResult result = layer_data->device_dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
if (!wrap_handles) return result;
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
UpdateCreateRenderPassState(layer_data, pCreateInfo, *pRenderPass);
*pRenderPass = layer_data->WrapNew(*pRenderPass);
}
@@ -283,7 +278,7 @@ VkResult DispatchCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateI
VkResult result = layer_data->device_dispatch_table.CreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass);
if (!wrap_handles) return result;
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
UpdateCreateRenderPassState(layer_data, pCreateInfo, *pRenderPass);
*pRenderPass = layer_data->WrapNew(*pRenderPass);
}
@@ -293,14 +288,18 @@ VkResult DispatchCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateI
void DispatchDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
if (!wrap_handles) return layer_data->device_dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);
- std::unique_lock<std::mutex> lock(dispatch_lock);
uint64_t renderPass_id = reinterpret_cast<uint64_t &>(renderPass);
- renderPass = (VkRenderPass)unique_id_mapping[renderPass_id];
- unique_id_mapping.erase(renderPass_id);
- lock.unlock();
+
+ auto iter = unique_id_mapping.pop(renderPass_id);
+ if (iter != unique_id_mapping.end()) {
+ renderPass = (VkRenderPass)iter->second;
+ } else {
+ renderPass = (VkRenderPass)0;
+ }
+
layer_data->device_dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);
- lock.lock();
+ write_dispatch_lock_guard_t lock(dispatch_lock);
layer_data->renderpasses_states.erase(renderPass);
}
@@ -310,7 +309,6 @@ VkResult DispatchCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfo
if (!wrap_handles) return layer_data->device_dispatch_table.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
safe_VkSwapchainCreateInfoKHR *local_pCreateInfo = NULL;
if (pCreateInfo) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
local_pCreateInfo = new safe_VkSwapchainCreateInfoKHR(pCreateInfo);
local_pCreateInfo->oldSwapchain = layer_data->Unwrap(pCreateInfo->oldSwapchain);
// Surface is instance-level object
@@ -321,7 +319,6 @@ VkResult DispatchCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfo
delete local_pCreateInfo;
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
*pSwapchain = layer_data->WrapNew(*pSwapchain);
}
return result;
@@ -335,7 +332,6 @@ VkResult DispatchCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCo
pSwapchains);
safe_VkSwapchainCreateInfoKHR *local_pCreateInfos = NULL;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
if (pCreateInfos) {
local_pCreateInfos = new safe_VkSwapchainCreateInfoKHR[swapchainCount];
for (uint32_t i = 0; i < swapchainCount; ++i) {
@@ -354,7 +350,6 @@ VkResult DispatchCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCo
pAllocator, pSwapchains);
delete[] local_pCreateInfos;
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t i = 0; i < swapchainCount; i++) {
pSwapchains[i] = layer_data->WrapNew(pSwapchains[i]);
}
@@ -369,14 +364,13 @@ VkResult DispatchGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain
return layer_data->device_dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
VkSwapchainKHR wrapped_swapchain_handle = swapchain;
if (VK_NULL_HANDLE != swapchain) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
swapchain = layer_data->Unwrap(swapchain);
}
VkResult result =
layer_data->device_dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
if ((VK_SUCCESS == result) || (VK_INCOMPLETE == result)) {
if ((*pSwapchainImageCount > 0) && pSwapchainImages) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
auto &wrapped_swapchain_image_handles = layer_data->swapchain_wrapped_image_handle_map[wrapped_swapchain_handle];
for (uint32_t i = static_cast<uint32_t>(wrapped_swapchain_image_handles.size()); i < *pSwapchainImageCount; i++) {
wrapped_swapchain_image_handles.emplace_back(layer_data->WrapNew(pSwapchainImages[i]));
@@ -392,18 +386,24 @@ VkResult DispatchGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain
void DispatchDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
if (!wrap_handles) return layer_data->device_dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator);
- std::unique_lock<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
auto &image_array = layer_data->swapchain_wrapped_image_handle_map[swapchain];
for (auto &image_handle : image_array) {
unique_id_mapping.erase(HandleToUint64(image_handle));
}
layer_data->swapchain_wrapped_image_handle_map.erase(swapchain);
+ lock.unlock();
uint64_t swapchain_id = HandleToUint64(swapchain);
- swapchain = (VkSwapchainKHR)unique_id_mapping[swapchain_id];
- unique_id_mapping.erase(swapchain_id);
- lock.unlock();
+
+ auto iter = unique_id_mapping.pop(swapchain_id);
+ if (iter != unique_id_mapping.end()) {
+ swapchain = (VkSwapchainKHR)iter->second;
+ } else {
+ swapchain = (VkSwapchainKHR)0;
+ }
+
layer_data->device_dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator);
}
@@ -412,7 +412,6 @@ VkResult DispatchQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresent
if (!wrap_handles) return layer_data->device_dispatch_table.QueuePresentKHR(queue, pPresentInfo);
safe_VkPresentInfoKHR *local_pPresentInfo = NULL;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
if (pPresentInfo) {
local_pPresentInfo = new safe_VkPresentInfoKHR(pPresentInfo);
if (local_pPresentInfo->pWaitSemaphores) {
@@ -443,18 +442,24 @@ VkResult DispatchQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresent
void DispatchDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
if (!wrap_handles) return layer_data->device_dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator);
- std::unique_lock<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
// remove references to implicitly freed descriptor sets
for(auto descriptor_set : layer_data->pool_descriptor_sets_map[descriptorPool]) {
unique_id_mapping.erase(reinterpret_cast<uint64_t &>(descriptor_set));
}
layer_data->pool_descriptor_sets_map.erase(descriptorPool);
+ lock.unlock();
uint64_t descriptorPool_id = reinterpret_cast<uint64_t &>(descriptorPool);
- descriptorPool = (VkDescriptorPool)unique_id_mapping[descriptorPool_id];
- unique_id_mapping.erase(descriptorPool_id);
- lock.unlock();
+
+ auto iter = unique_id_mapping.pop(descriptorPool_id);
+ if (iter != unique_id_mapping.end()) {
+ descriptorPool = (VkDescriptorPool)iter->second;
+ } else {
+ descriptorPool = (VkDescriptorPool)0;
+ }
+
layer_data->device_dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator);
}
@@ -463,12 +468,11 @@ VkResult DispatchResetDescriptorPool(VkDevice device, VkDescriptorPool descripto
if (!wrap_handles) return layer_data->device_dispatch_table.ResetDescriptorPool(device, descriptorPool, flags);
VkDescriptorPool local_descriptor_pool = VK_NULL_HANDLE;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
local_descriptor_pool = layer_data->Unwrap(descriptorPool);
}
VkResult result = layer_data->device_dispatch_table.ResetDescriptorPool(device, local_descriptor_pool, flags);
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
// remove references to implicitly freed descriptor sets
for(auto descriptor_set : layer_data->pool_descriptor_sets_map[descriptorPool]) {
unique_id_mapping.erase(reinterpret_cast<uint64_t &>(descriptor_set));
@@ -485,7 +489,6 @@ VkResult DispatchAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAl
if (!wrap_handles) return layer_data->device_dispatch_table.AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
safe_VkDescriptorSetAllocateInfo *local_pAllocateInfo = NULL;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
if (pAllocateInfo) {
local_pAllocateInfo = new safe_VkDescriptorSetAllocateInfo(pAllocateInfo);
if (pAllocateInfo->descriptorPool) {
@@ -504,7 +507,7 @@ VkResult DispatchAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAl
delete local_pAllocateInfo;
}
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
auto &pool_descriptor_sets = layer_data->pool_descriptor_sets_map[pAllocateInfo->descriptorPool];
for (uint32_t index0 = 0; index0 < pAllocateInfo->descriptorSetCount; index0++) {
pDescriptorSets[index0] = layer_data->WrapNew(pDescriptorSets[index0]);
@@ -522,7 +525,6 @@ VkResult DispatchFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptor
VkDescriptorSet *local_pDescriptorSets = NULL;
VkDescriptorPool local_descriptor_pool = VK_NULL_HANDLE;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
local_descriptor_pool = layer_data->Unwrap(descriptorPool);
if (pDescriptorSets) {
local_pDescriptorSets = new VkDescriptorSet[descriptorSetCount];
@@ -535,7 +537,7 @@ VkResult DispatchFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptor
(const VkDescriptorSet *)local_pDescriptorSets);
if (local_pDescriptorSets) delete[] local_pDescriptorSets;
if ((VK_SUCCESS == result) && (pDescriptorSets)) {
- std::unique_lock<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
auto &pool_descriptor_sets = layer_data->pool_descriptor_sets_map[descriptorPool];
for (uint32_t index0 = 0; index0 < descriptorSetCount; index0++) {
VkDescriptorSet handle = pDescriptorSets[index0];
@@ -557,7 +559,6 @@ VkResult DispatchCreateDescriptorUpdateTemplate(VkDevice device, const VkDescrip
pDescriptorUpdateTemplate);
safe_VkDescriptorUpdateTemplateCreateInfo *local_create_info = NULL;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
if (pCreateInfo) {
local_create_info = new safe_VkDescriptorUpdateTemplateCreateInfo(pCreateInfo);
if (pCreateInfo->descriptorSetLayout) {
@@ -571,7 +572,7 @@ VkResult DispatchCreateDescriptorUpdateTemplate(VkDevice device, const VkDescrip
VkResult result = layer_data->device_dispatch_table.CreateDescriptorUpdateTemplate(device, local_create_info->ptr(), pAllocator,
pDescriptorUpdateTemplate);
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
*pDescriptorUpdateTemplate = layer_data->WrapNew(*pDescriptorUpdateTemplate);
// Shadow template createInfo for later updates
@@ -591,7 +592,6 @@ VkResult DispatchCreateDescriptorUpdateTemplateKHR(VkDevice device, const VkDesc
pDescriptorUpdateTemplate);
safe_VkDescriptorUpdateTemplateCreateInfo *local_create_info = NULL;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
if (pCreateInfo) {
local_create_info = new safe_VkDescriptorUpdateTemplateCreateInfo(pCreateInfo);
if (pCreateInfo->descriptorSetLayout) {
@@ -605,7 +605,7 @@ VkResult DispatchCreateDescriptorUpdateTemplateKHR(VkDevice device, const VkDesc
VkResult result = layer_data->device_dispatch_table.CreateDescriptorUpdateTemplateKHR(device, local_create_info->ptr(), pAllocator,
pDescriptorUpdateTemplate);
if (VK_SUCCESS == result) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
*pDescriptorUpdateTemplate = layer_data->WrapNew(*pDescriptorUpdateTemplate);
// Shadow template createInfo for later updates
@@ -621,12 +621,18 @@ void DispatchDestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdate
auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
if (!wrap_handles)
return layer_data->device_dispatch_table.DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
- std::unique_lock<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
uint64_t descriptor_update_template_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
layer_data->desc_template_createinfo_map.erase(descriptor_update_template_id);
- descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[descriptor_update_template_id];
- unique_id_mapping.erase(descriptor_update_template_id);
lock.unlock();
+
+ auto iter = unique_id_mapping.pop(descriptor_update_template_id);
+ if (iter != unique_id_mapping.end()) {
+ descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)iter->second;
+ } else {
+ descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)0;
+ }
+
layer_data->device_dispatch_table.DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
}
@@ -636,12 +642,18 @@ void DispatchDestroyDescriptorUpdateTemplateKHR(VkDevice device, VkDescriptorUpd
auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
if (!wrap_handles)
return layer_data->device_dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
- std::unique_lock<std::mutex> lock(dispatch_lock);
+ write_dispatch_lock_guard_t lock(dispatch_lock);
uint64_t descriptor_update_template_id = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
layer_data->desc_template_createinfo_map.erase(descriptor_update_template_id);
- descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[descriptor_update_template_id];
- unique_id_mapping.erase(descriptor_update_template_id);
lock.unlock();
+
+ auto iter = unique_id_mapping.pop(descriptor_update_template_id);
+ if (iter != unique_id_mapping.end()) {
+ descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)iter->second;
+ } else {
+ descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)0;
+ }
+
layer_data->device_dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
}
@@ -751,12 +763,13 @@ void DispatchUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet de
return layer_data->device_dispatch_table.UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate,
pData);
uint64_t template_handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
+ void *unwrapped_buffer = nullptr;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ read_dispatch_lock_guard_t lock(dispatch_lock);
descriptorSet = layer_data->Unwrap(descriptorSet);
- descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[template_handle];
+ descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)layer_data->Unwrap(descriptorUpdateTemplate);
+ unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(layer_data, template_handle, pData);
}
- void *unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(layer_data, template_handle, pData);
layer_data->device_dispatch_table.UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, unwrapped_buffer);
free(unwrapped_buffer);
}
@@ -770,9 +783,9 @@ void DispatchUpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet
uint64_t template_handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
void *unwrapped_buffer = nullptr;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ read_dispatch_lock_guard_t lock(dispatch_lock);
descriptorSet = layer_data->Unwrap(descriptorSet);
- descriptorUpdateTemplate = (VkDescriptorUpdateTemplate)unique_id_mapping[template_handle];
+ descriptorUpdateTemplate = layer_data->Unwrap(descriptorUpdateTemplate);
unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(layer_data, template_handle, pData);
}
layer_data->device_dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, unwrapped_buffer);
@@ -789,7 +802,7 @@ void DispatchCmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,
uint64_t template_handle = reinterpret_cast<uint64_t &>(descriptorUpdateTemplate);
void *unwrapped_buffer = nullptr;
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
+ read_dispatch_lock_guard_t lock(dispatch_lock);
descriptorUpdateTemplate = layer_data->Unwrap(descriptorUpdateTemplate);
layout = layer_data->Unwrap(layout);
unwrapped_buffer = BuildUnwrappedUpdateTemplateBuffer(layer_data, template_handle, pData);
@@ -806,7 +819,6 @@ VkResult DispatchGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical
layer_data->instance_dispatch_table.GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
if (!wrap_handles) return result;
if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
pProperties[idx0].display = layer_data->MaybeWrapDisplay(pProperties[idx0].display, layer_data);
}
@@ -821,7 +833,6 @@ VkResult DispatchGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physica
layer_data->instance_dispatch_table.GetPhysicalDeviceDisplayProperties2KHR(physicalDevice, pPropertyCount, pProperties);
if (!wrap_handles) return result;
if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
pProperties[idx0].displayProperties.display =
layer_data->MaybeWrapDisplay(pProperties[idx0].displayProperties.display, layer_data);
@@ -837,7 +848,6 @@ VkResult DispatchGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice phy
layer_data->instance_dispatch_table.GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
if (!wrap_handles) return result;
if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
VkDisplayKHR &opt_display = pProperties[idx0].currentDisplay;
if (opt_display) opt_display = layer_data->MaybeWrapDisplay(opt_display, layer_data);
@@ -853,7 +863,6 @@ VkResult DispatchGetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice ph
pPropertyCount, pProperties);
if (!wrap_handles) return result;
if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
VkDisplayKHR &opt_display = pProperties[idx0].displayPlaneProperties.currentDisplay;
if (opt_display) opt_display = layer_data->MaybeWrapDisplay(opt_display, layer_data);
@@ -869,7 +878,6 @@ VkResult DispatchGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDe
pDisplayCount, pDisplays);
if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pDisplays) {
if (!wrap_handles) return result;
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t i = 0; i < *pDisplayCount; ++i) {
if (pDisplays[i]) pDisplays[i] = layer_data->MaybeWrapDisplay(pDisplays[i], layer_data);
}
@@ -884,13 +892,11 @@ VkResult DispatchGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, Vk
return layer_data->instance_dispatch_table.GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount,
pProperties);
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
display = layer_data->Unwrap(display);
}
VkResult result = layer_data->instance_dispatch_table.GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
pProperties[idx0].displayMode = layer_data->WrapNew(pProperties[idx0].displayMode);
}
@@ -905,14 +911,12 @@ VkResult DispatchGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, V
return layer_data->instance_dispatch_table.GetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount,
pProperties);
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
display = layer_data->Unwrap(display);
}
VkResult result =
layer_data->instance_dispatch_table.GetDisplayModeProperties2KHR(physicalDevice, display, pPropertyCount, pProperties);
if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pProperties) {
- std::lock_guard<std::mutex> lock(dispatch_lock);
for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
pProperties[idx0].displayModeProperties.displayMode = layer_data->WrapNew(pProperties[idx0].displayModeProperties.displayMode);
}
@@ -925,7 +929,6 @@ VkResult DispatchDebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarker
if (!wrap_handles) return layer_data->device_dispatch_table.DebugMarkerSetObjectTagEXT(device, pTagInfo);
safe_VkDebugMarkerObjectTagInfoEXT local_tag_info(pTagInfo);
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_tag_info.object));
if (it != unique_id_mapping.end()) {
local_tag_info.object = it->second;
@@ -941,7 +944,6 @@ VkResult DispatchDebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarke
if (!wrap_handles) return layer_data->device_dispatch_table.DebugMarkerSetObjectNameEXT(device, pNameInfo);
safe_VkDebugMarkerObjectNameInfoEXT local_name_info(pNameInfo);
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_name_info.object));
if (it != unique_id_mapping.end()) {
local_name_info.object = it->second;
@@ -958,7 +960,6 @@ VkResult DispatchSetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsOb
if (!wrap_handles) return layer_data->device_dispatch_table.SetDebugUtilsObjectTagEXT(device, pTagInfo);
safe_VkDebugUtilsObjectTagInfoEXT local_tag_info(pTagInfo);
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_tag_info.objectHandle));
if (it != unique_id_mapping.end()) {
local_tag_info.objectHandle = it->second;
@@ -974,7 +975,6 @@ VkResult DispatchSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsO
if (!wrap_handles) return layer_data->device_dispatch_table.SetDebugUtilsObjectNameEXT(device, pNameInfo);
safe_VkDebugUtilsObjectNameInfoEXT local_name_info(pNameInfo);
{
- std::lock_guard<std::mutex> lock(dispatch_lock);
auto it = unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_name_info.objectHandle));
if (it != unique_id_mapping.end()) {
local_name_info.objectHandle = it->second;
@@ -1121,7 +1121,18 @@ VkResult DispatchSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsO
write('// This intentionally includes a cpp file', file=self.outFile)
write('#include "vk_safe_struct.cpp"', file=self.outFile)
self.newline()
- write('std::mutex dispatch_lock;', file=self.outFile)
+ write('// shared_mutex support added in MSVC 2015 update 2', file=self.outFile)
+ write('#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918', file=self.outFile)
+ write(' #include <shared_mutex>', file=self.outFile)
+ write(' typedef std::shared_mutex dispatch_lock_t;', file=self.outFile)
+ write(' typedef std::shared_lock<dispatch_lock_t> read_dispatch_lock_guard_t;', file=self.outFile)
+ write(' typedef std::unique_lock<dispatch_lock_t> write_dispatch_lock_guard_t;', file=self.outFile)
+ write('#else', file=self.outFile)
+ write(' typedef std::mutex dispatch_lock_t;', file=self.outFile)
+ write(' typedef std::unique_lock<dispatch_lock_t> read_dispatch_lock_guard_t;', file=self.outFile)
+ write(' typedef std::unique_lock<dispatch_lock_t> write_dispatch_lock_guard_t;', file=self.outFile)
+ write('#endif', file=self.outFile)
+ write('dispatch_lock_t dispatch_lock;', file=self.outFile)
self.newline()
write('// Unique Objects pNext extension handling function', file=self.outFile)
write('%s' % extension_proc, file=self.outFile)
@@ -1270,10 +1281,6 @@ VkResult DispatchSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsO
self.structMembers.append(self.StructMemberData(name=typeName, members=membersInfo))
#
- # Insert a lock_guard line
- def lock_guard(self, indent):
- return '%sstd::lock_guard<std::mutex> lock(dispatch_lock);\n' % indent
- #
# Determine if a struct has an NDO as a member or an embedded member
def struct_contains_ndo(self, struct_item):
struct_member_dict = dict(self.structMembers)
@@ -1386,7 +1393,6 @@ VkResult DispatchSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsO
handle_name = params[-1].find('name')
create_ndo_code += '%sif (VK_SUCCESS == result) {\n' % (indent)
indent = self.incIndent(indent)
- create_ndo_code += '%sstd::lock_guard<std::mutex> lock(dispatch_lock);\n' % (indent)
ndo_dest = '*%s' % handle_name.text
if ndo_array == True:
create_ndo_code += '%sfor (uint32_t index0 = 0; index0 < %s; index0++) {\n' % (indent, cmd_info[-1].len)
@@ -1416,7 +1422,6 @@ VkResult DispatchSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsO
# This API is freeing an array of handles. Remove them from the unique_id map.
destroy_ndo_code += '%sif ((VK_SUCCESS == result) && (%s)) {\n' % (indent, cmd_info[param].name)
indent = self.incIndent(indent)
- destroy_ndo_code += '%sstd::unique_lock<std::mutex> lock(dispatch_lock);\n' % (indent)
destroy_ndo_code += '%sfor (uint32_t index0 = 0; index0 < %s; index0++) {\n' % (indent, cmd_info[param].len)
indent = self.incIndent(indent)
destroy_ndo_code += '%s%s handle = %s[index0];\n' % (indent, cmd_info[param].type, cmd_info[param].name)
@@ -1428,11 +1433,18 @@ VkResult DispatchSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsO
destroy_ndo_code += '%s}\n' % indent
else:
# Remove a single handle from the map
- destroy_ndo_code += '%sstd::unique_lock<std::mutex> lock(dispatch_lock);\n' % (indent)
destroy_ndo_code += '%suint64_t %s_id = reinterpret_cast<uint64_t &>(%s);\n' % (indent, cmd_info[param].name, cmd_info[param].name)
- destroy_ndo_code += '%s%s = (%s)unique_id_mapping[%s_id];\n' % (indent, cmd_info[param].name, cmd_info[param].type, cmd_info[param].name)
- destroy_ndo_code += '%sunique_id_mapping.erase(%s_id);\n' % (indent, cmd_info[param].name)
- destroy_ndo_code += '%slock.unlock();\n' % (indent)
+ destroy_ndo_code += '%sauto iter = unique_id_mapping.pop(%s_id);\n' % (indent, cmd_info[param].name)
+ destroy_ndo_code += '%sif (iter != unique_id_mapping.end()) {\n' % (indent)
+ indent = self.incIndent(indent)
+ destroy_ndo_code += '%s%s = (%s)iter->second;\n' % (indent, cmd_info[param].name, cmd_info[param].type)
+ indent = self.decIndent(indent);
+ destroy_ndo_code += '%s} else {\n' % (indent)
+ indent = self.incIndent(indent)
+ destroy_ndo_code += '%s%s = (%s)0;\n' % (indent, cmd_info[param].name, cmd_info[param].type)
+ indent = self.decIndent(indent);
+ destroy_ndo_code += '%s}\n' % (indent)
+
return ndo_array, destroy_ndo_code
#
@@ -1624,7 +1636,7 @@ VkResult DispatchSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsO
param_pre_code += destroy_ndo_code
if param_pre_code:
if (not destroy_func) or (destroy_array):
- param_pre_code = '%s{\n%s%s%s%s}\n' % (' ', indent, self.lock_guard(indent), param_pre_code, indent)
+ param_pre_code = '%s{\n%s%s}\n' % (' ', param_pre_code, indent)
return paramdecl, param_pre_code, param_post_code
#
# Capture command parameter info needed to wrap NDOs as well as handling some boilerplate code
diff --git a/scripts/layer_chassis_generator.py b/scripts/layer_chassis_generator.py
index 332363f80..c1c7f3dc5 100644
--- a/scripts/layer_chassis_generator.py
+++ b/scripts/layer_chassis_generator.py
@@ -198,6 +198,7 @@ class LayerChassisOutputGenerator(OutputGenerator):
inline_custom_header_preamble = """
#define NOMINMAX
+#include <atomic>
#include <mutex>
#include <cinttypes>
#include <stdio.h>
@@ -225,8 +226,8 @@ class LayerChassisOutputGenerator(OutputGenerator):
#include "vk_typemap_helper.h"
-extern uint64_t global_unique_id;
-extern std::unordered_map<uint64_t, uint64_t> unique_id_mapping;
+extern std::atomic<uint64_t> global_unique_id;
+extern vl_concurrent_unordered_map<uint64_t, uint64_t, 4> unique_id_mapping;
"""
inline_custom_header_class_definition = """
@@ -346,7 +347,7 @@ class ValidationObject {
// Handle Wrapping Data
// Reverse map display handles
- std::unordered_map<VkDisplayKHR, uint64_t> display_id_reverse_mapping;
+ vl_concurrent_unordered_map<VkDisplayKHR, uint64_t, 0> display_id_reverse_mapping;
// Wrapping Descriptor Template Update structures requires access to the template createinfo structs
std::unordered_map<uint64_t, std::unique_ptr<TEMPLATE_STATE>> desc_template_createinfo_map;
struct SubpassesUsageStates {
@@ -362,31 +363,33 @@ class ValidationObject {
std::unordered_map<VkDescriptorPool, std::unordered_set<VkDescriptorSet>> pool_descriptor_sets_map;
- // Unwrap a handle. Must hold lock.
+ // Unwrap a handle.
template <typename HandleType>
HandleType Unwrap(HandleType wrappedHandle) {
- // TODO: don't use operator[] here.
- return (HandleType)unique_id_mapping[reinterpret_cast<uint64_t const &>(wrappedHandle)];
+ auto iter = unique_id_mapping.find(reinterpret_cast<uint64_t const &>(wrappedHandle));
+ if (iter == unique_id_mapping.end())
+ return (HandleType)0;
+ return (HandleType)iter->second;
}
- // Wrap a newly created handle with a new unique ID, and return the new ID -- must hold lock.
+ // Wrap a newly created handle with a new unique ID, and return the new ID.
template <typename HandleType>
HandleType WrapNew(HandleType newlyCreatedHandle) {
auto unique_id = global_unique_id++;
- unique_id_mapping[unique_id] = reinterpret_cast<uint64_t const &>(newlyCreatedHandle);
+ unique_id_mapping.insert_or_assign(unique_id, reinterpret_cast<uint64_t const &>(newlyCreatedHandle));
return (HandleType)unique_id;
}
- // Specialized handling for VkDisplayKHR. Adds an entry to enable reverse-lookup. Must hold lock.
+ // Specialized handling for VkDisplayKHR. Adds an entry to enable reverse-lookup.
VkDisplayKHR WrapDisplay(VkDisplayKHR newlyCreatedHandle, ValidationObject *map_data) {
auto unique_id = global_unique_id++;
- unique_id_mapping[unique_id] = reinterpret_cast<uint64_t const &>(newlyCreatedHandle);
- map_data->display_id_reverse_mapping[newlyCreatedHandle] = unique_id;
+ unique_id_mapping.insert_or_assign(unique_id, reinterpret_cast<uint64_t const &>(newlyCreatedHandle));
+ map_data->display_id_reverse_mapping.insert_or_assign(newlyCreatedHandle, unique_id);
return (VkDisplayKHR)unique_id;
}
// VkDisplayKHR objects don't have a single point of creation, so we need to see if one already exists in the map before
- // creating another. Must hold lock.
+ // creating another.
VkDisplayKHR MaybeWrapDisplay(VkDisplayKHR handle, ValidationObject *map_data) {
// See if this display is already known
auto it = map_data->display_id_reverse_mapping.find(handle);
@@ -434,10 +437,11 @@ class ValidationObject {
std::unordered_map<void*, ValidationObject*> layer_data_map;
-// Global unique object identifier. All increments must be guarded by a lock.
-uint64_t global_unique_id = 1;
-// Map uniqueID to actual object handle
-std::unordered_map<uint64_t, uint64_t> unique_id_mapping;
+// Global unique object identifier.
+std::atomic<uint64_t> global_unique_id(1ULL);
+// Map uniqueID to actual object handle. Accesses to the map itself are
+// internally synchronized.
+vl_concurrent_unordered_map<uint64_t, uint64_t, 4> unique_id_mapping;
// TODO: This variable controls handle wrapping -- in the future it should be hooked
// up to the new VALIDATION_FEATURES extension. Temporarily, control with a compile-time flag.