layers: Remove single-threaded one-time switch
diff --git a/layers/threading.cpp b/layers/threading.cpp
index a957a8a..d7763ad 100644
--- a/layers/threading.cpp
+++ b/layers/threading.cpp
@@ -98,16 +98,9 @@
}
}
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startWriteObject(my_data, instance);
- }
+ startWriteObject(my_data, instance);
pTable->DestroyInstance(instance, pAllocator);
- if (threadChecks) {
- finishWriteObject(my_data, instance);
- } else {
- finishMultiThread();
- }
+ finishWriteObject(my_data, instance);
// Disable and cleanup the temporary callback(s):
if (callback_setup) {
@@ -178,16 +171,9 @@
VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
dispatch_key key = get_dispatch_key(device);
layer_data *dev_data = GetLayerDataPtr(key, layer_data_map);
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startWriteObject(dev_data, device);
- }
+ startWriteObject(dev_data, device);
dev_data->device_dispatch_table->DestroyDevice(device, pAllocator);
- if (threadChecks) {
- finishWriteObject(dev_data, device);
- } else {
- finishMultiThread();
- }
+ finishWriteObject(dev_data, device);
delete dev_data->device_dispatch_table;
FreeLayerDataPtr(key, layer_data_map);
@@ -199,18 +185,11 @@
layer_data *my_data = GetLayerDataPtr(key, layer_data_map);
VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
VkResult result;
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, device);
- startReadObject(my_data, swapchain);
- }
+ startReadObject(my_data, device);
+ startReadObject(my_data, swapchain);
result = pTable->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
- if (threadChecks) {
- finishReadObject(my_data, device);
- finishReadObject(my_data, swapchain);
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, device);
+ finishReadObject(my_data, swapchain);
return result;
}
@@ -300,10 +279,7 @@
const VkAllocationCallbacks *pAllocator,
VkDebugUtilsMessengerEXT *pMessenger) {
layer_data *my_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, instance);
- }
+ startReadObject(my_data, instance);
VkResult result = my_data->instance_dispatch_table->CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
if (VK_SUCCESS == result) {
@@ -313,30 +289,19 @@
my_data->instance_dispatch_table->DestroyDebugUtilsMessengerEXT(instance, *pMessenger, pAllocator);
}
}
- if (threadChecks) {
- finishReadObject(my_data, instance);
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, instance);
return result;
}
VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks *pAllocator) {
layer_data *my_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, instance);
- startWriteObject(my_data, messenger);
- }
+ startReadObject(my_data, instance);
+ startWriteObject(my_data, messenger);
my_data->instance_dispatch_table->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
layer_destroy_messenger_callback(my_data->report_data, messenger, pAllocator);
- if (threadChecks) {
- finishReadObject(my_data, instance);
- finishWriteObject(my_data, messenger);
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, instance);
+ finishWriteObject(my_data, messenger);
}
// VK_EXT_debug_report commands
@@ -345,10 +310,7 @@
const VkAllocationCallbacks *pAllocator,
VkDebugReportCallbackEXT *pMsgCallback) {
layer_data *my_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, instance);
- }
+ startReadObject(my_data, instance);
VkResult result =
my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
if (VK_SUCCESS == result) {
@@ -358,30 +320,19 @@
my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, *pMsgCallback, pAllocator);
}
}
- if (threadChecks) {
- finishReadObject(my_data, instance);
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, instance);
return result;
}
VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator) {
layer_data *my_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, instance);
- startWriteObject(my_data, callback);
- }
+ startReadObject(my_data, instance);
+ startWriteObject(my_data, callback);
my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
layer_destroy_report_callback(my_data->report_data, callback, pAllocator);
- if (threadChecks) {
- finishReadObject(my_data, instance);
- finishWriteObject(my_data, callback);
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, instance);
+ finishWriteObject(my_data, callback);
}
VKAPI_ATTR VkResult VKAPI_CALL AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
@@ -390,19 +341,12 @@
layer_data *my_data = GetLayerDataPtr(key, layer_data_map);
VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
VkResult result;
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, device);
- startWriteObject(my_data, pAllocateInfo->commandPool);
- }
+ startReadObject(my_data, device);
+ startWriteObject(my_data, pAllocateInfo->commandPool);
result = pTable->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
- if (threadChecks) {
- finishReadObject(my_data, device);
- finishWriteObject(my_data, pAllocateInfo->commandPool);
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, device);
+ finishWriteObject(my_data, pAllocateInfo->commandPool);
// Record mapping from command buffer to command pool
if (VK_SUCCESS == result) {
@@ -421,20 +365,13 @@
layer_data *my_data = GetLayerDataPtr(key, layer_data_map);
VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
VkResult result;
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, device);
- startWriteObject(my_data, pAllocateInfo->descriptorPool);
- // Host access to pAllocateInfo::descriptorPool must be externally synchronized
- }
+ startReadObject(my_data, device);
+ startWriteObject(my_data, pAllocateInfo->descriptorPool);
+ // Host access to pAllocateInfo::descriptorPool must be externally synchronized
result = pTable->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
- if (threadChecks) {
- finishReadObject(my_data, device);
- finishWriteObject(my_data, pAllocateInfo->descriptorPool);
- // Host access to pAllocateInfo::descriptorPool must be externally synchronized
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, device);
+ finishWriteObject(my_data, pAllocateInfo->descriptorPool);
+ // Host access to pAllocateInfo::descriptorPool must be externally synchronized
return result;
}
@@ -444,53 +381,39 @@
layer_data *my_data = GetLayerDataPtr(key, layer_data_map);
VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
const bool lockCommandPool = false; // pool is already directly locked
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, device);
- startWriteObject(my_data, commandPool);
- for (uint32_t index = 0; index < commandBufferCount; index++) {
- startWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
- }
- // The driver may immediately reuse command buffers in another thread.
- // These updates need to be done before calling down to the driver.
- for (uint32_t index = 0; index < commandBufferCount; index++) {
- finishWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
- std::lock_guard<std::mutex> lock(command_pool_lock);
- command_pool_map.erase(pCommandBuffers[index]);
- }
+ startReadObject(my_data, device);
+ startWriteObject(my_data, commandPool);
+ for (uint32_t index = 0; index < commandBufferCount; index++) {
+ startWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
+ }
+ // The driver may immediately reuse command buffers in another thread.
+ // These updates need to be done before calling down to the driver.
+ for (uint32_t index = 0; index < commandBufferCount; index++) {
+ finishWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
+ std::lock_guard<std::mutex> lock(command_pool_lock);
+ command_pool_map.erase(pCommandBuffers[index]);
}
pTable->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
- if (threadChecks) {
- finishReadObject(my_data, device);
- finishWriteObject(my_data, commandPool);
- } else {
- finishMultiThread();
- }
-}
+ finishReadObject(my_data, device);
+ finishWriteObject(my_data, commandPool);
+} // namespace threading
VKAPI_ATTR VkResult VKAPI_CALL ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
dispatch_key key = get_dispatch_key(device);
layer_data *my_data = GetLayerDataPtr(key, layer_data_map);
VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
VkResult result;
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, device);
- startWriteObject(my_data, commandPool);
- // Check for any uses of non-externally sync'd command buffers (for example from vkCmdExecuteCommands)
- my_data->c_VkCommandPoolContents.startWrite(my_data->report_data, commandPool);
- // Host access to commandPool must be externally synchronized
- }
+ startReadObject(my_data, device);
+ startWriteObject(my_data, commandPool);
+ // Check for any uses of non-externally sync'd command buffers (for example from vkCmdExecuteCommands)
+ my_data->c_VkCommandPoolContents.startWrite(my_data->report_data, commandPool);
+ // Host access to commandPool must be externally synchronized
result = pTable->ResetCommandPool(device, commandPool, flags);
- if (threadChecks) {
- finishReadObject(my_data, device);
- finishWriteObject(my_data, commandPool);
- my_data->c_VkCommandPoolContents.finishWrite(commandPool);
- // Host access to commandPool must be externally synchronized
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, device);
+ finishWriteObject(my_data, commandPool);
+ my_data->c_VkCommandPoolContents.finishWrite(commandPool);
+ // Host access to commandPool must be externally synchronized
return result;
}
@@ -498,23 +421,16 @@
dispatch_key key = get_dispatch_key(device);
layer_data *my_data = GetLayerDataPtr(key, layer_data_map);
VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
- bool threadChecks = startMultiThread();
- if (threadChecks) {
- startReadObject(my_data, device);
- startWriteObject(my_data, commandPool);
- // Check for any uses of non-externally sync'd command buffers (for example from vkCmdExecuteCommands)
- my_data->c_VkCommandPoolContents.startWrite(my_data->report_data, commandPool);
- // Host access to commandPool must be externally synchronized
- }
+ startReadObject(my_data, device);
+ startWriteObject(my_data, commandPool);
+ // Check for any uses of non-externally sync'd command buffers (for example from vkCmdExecuteCommands)
+ my_data->c_VkCommandPoolContents.startWrite(my_data->report_data, commandPool);
+ // Host access to commandPool must be externally synchronized
pTable->DestroyCommandPool(device, commandPool, pAllocator);
- if (threadChecks) {
- finishReadObject(my_data, device);
- finishWriteObject(my_data, commandPool);
- my_data->c_VkCommandPoolContents.finishWrite(commandPool);
- // Host access to commandPool must be externally synchronized
- } else {
- finishMultiThread();
- }
+ finishReadObject(my_data, device);
+ finishWriteObject(my_data, commandPool);
+ my_data->c_VkCommandPoolContents.finishWrite(commandPool);
+ // Host access to commandPool must be externally synchronized
}
} // namespace threading
diff --git a/layers/threading.h b/layers/threading.h
index 0ca2f78..9cecbb6 100644
--- a/layers/threading.h
+++ b/layers/threading.h
@@ -67,29 +67,9 @@
struct layer_data;
-namespace threading {
-volatile bool vulkan_in_use = false;
-volatile bool vulkan_multi_threaded = false;
-// starting check if an application is using vulkan from multiple threads.
-inline bool startMultiThread() {
- if (vulkan_multi_threaded) {
- return true;
- }
- if (vulkan_in_use) {
- vulkan_multi_threaded = true;
- return true;
- }
- vulkan_in_use = true;
- return false;
-}
-
-// finishing check if an application is using vulkan from multiple threads.
-inline void finishMultiThread() { vulkan_in_use = false; }
-} // namespace threading
-
template <typename T>
class counter {
- public:
+ public:
const char *typeName;
VkDebugReportObjectTypeEXT objectType;
std::unordered_map<T, object_use_data> uses;
diff --git a/scripts/threading_generator.py b/scripts/threading_generator.py
index 96d1eed..c3c5e96 100644
--- a/scripts/threading_generator.py
+++ b/scripts/threading_generator.py
@@ -169,15 +169,16 @@
externsync = param.attrib.get('externsync')
if externsync == 'true':
if self.paramIsArray(param):
- paramdecl += ' for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
- paramdecl += ' ' + functionprefix + 'WriteObject(my_data, ' + paramname.text + '[index]);\n'
- paramdecl += ' }\n'
+ paramdecl += 'for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
+ paramdecl += ' ' + functionprefix + 'WriteObject(my_data, ' + paramname.text + '[index]);\n'
+ paramdecl += '}\n'
else:
- paramdecl += ' ' + functionprefix + 'WriteObject(my_data, ' + paramname.text + ');\n'
+ paramdecl += functionprefix + 'WriteObject(my_data, ' + paramname.text + ');\n'
elif (param.attrib.get('externsync')):
if self.paramIsArray(param):
# Externsync can list pointers to arrays of members to synchronize
- paramdecl += ' for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
+ paramdecl += 'for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
+ second_indent = ''
for member in externsync.split(","):
# Replace first empty [] in member name with index
element = member.replace('[]','[index]',1)
@@ -190,10 +191,11 @@
limit = element[0:element.find('s[]')] + 'Count'
dotp = limit.rfind('.p')
limit = limit[0:dotp+1] + limit[dotp+2:dotp+3].lower() + limit[dotp+3:]
- paramdecl += ' for(uint32_t index2=0;index2<'+limit+';index2++)\n'
+ paramdecl += ' for(uint32_t index2=0;index2<'+limit+';index2++)\n'
element = element.replace('[]','[index2]')
- paramdecl += ' ' + functionprefix + 'WriteObject(my_data, ' + element + ');\n'
- paramdecl += ' }\n'
+ second_indent = ' '
+ paramdecl += ' ' + second_indent + functionprefix + 'WriteObject(my_data, ' + element + ');\n'
+ paramdecl += '}\n'
else:
# externsync can list members to synchronize
for member in externsync.split(","):
@@ -215,19 +217,19 @@
if self.paramIsPointer(candidate):
dereference = '*'
param_len = str(param.attrib.get('len')).replace("::", "->")
- paramdecl += ' for (uint32_t index = 0; index < ' + dereference + param_len + '; index++) {\n'
- paramdecl += ' ' + functionprefix + 'ReadObject(my_data, ' + paramname.text + '[index]);\n'
- paramdecl += ' }\n'
+ paramdecl += 'for (uint32_t index = 0; index < ' + dereference + param_len + '; index++) {\n'
+ paramdecl += ' ' + functionprefix + 'ReadObject(my_data, ' + paramname.text + '[index]);\n'
+ paramdecl += '}\n'
elif not self.paramIsPointer(param):
# Pointer params are often being created.
# They are not being read from.
- paramdecl += ' ' + functionprefix + 'ReadObject(my_data, ' + paramname.text + ');\n'
+ paramdecl += functionprefix + 'ReadObject(my_data, ' + paramname.text + ');\n'
explicitexternsyncparams = cmd.findall("param[@externsync]")
if (explicitexternsyncparams is not None):
for param in explicitexternsyncparams:
externsyncattrib = param.attrib.get('externsync')
paramname = param.find('name')
- paramdecl += ' // Host access to '
+ paramdecl += '// Host access to '
if externsyncattrib == 'true':
if self.paramIsArray(param):
paramdecl += 'each member of ' + paramname.text
@@ -243,7 +245,7 @@
implicitexternsyncparams = cmd.find('implicitexternsyncparams')
if (implicitexternsyncparams is not None):
for elem in implicitexternsyncparams:
- paramdecl += ' // '
+ paramdecl += '// '
paramdecl += elem.text
paramdecl += ' must be externally synchronized between host accesses\n'
@@ -436,20 +438,12 @@
assignresult = 'result = '
else:
assignresult = ''
-
- self.appendSection('command', ' bool threadChecks = startMultiThread();')
- self.appendSection('command', ' if (threadChecks) {')
- self.appendSection('command', " "+"\n ".join(str(startthreadsafety).rstrip().split("\n")))
- self.appendSection('command', ' }')
+ self.appendSection('command', " " + "\n ".join(str(startthreadsafety).rstrip().split("\n")))
params = cmdinfo.elem.findall('param/name')
paramstext = ','.join([str(param.text) for param in params])
API = cmdinfo.elem.attrib.get('name').replace('vk','pTable->',1)
self.appendSection('command', ' ' + assignresult + API + '(' + paramstext + ');')
- self.appendSection('command', ' if (threadChecks) {')
- self.appendSection('command', " "+"\n ".join(str(finishthreadsafety).rstrip().split("\n")))
- self.appendSection('command', ' } else {')
- self.appendSection('command', ' finishMultiThread();')
- self.appendSection('command', ' }')
+ self.appendSection('command', " " + "\n ".join(str(finishthreadsafety).rstrip().split("\n")))
# Return result variable, if any.
if (resulttype is not None):
self.appendSection('command', ' return result;')