layers: Make dispatch table thread safe
diff --git a/layers/multi.cpp b/layers/multi.cpp
index b0e8f21..fc0bb38 100644
--- a/layers/multi.cpp
+++ b/layers/multi.cpp
@@ -48,6 +48,23 @@
static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap1;
static bool layer1_first_activated = false;
+// Map lookup must be thread safe
+static inline VkLayerDispatchTable *device_dispatch_table1(VkObject object)
+{
+ VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;
+ std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap1.find((void *) pDisp);
+ assert(it != tableMap1.end() && "Not able to find device dispatch entry");
+ return it->second;
+}
+
+static inline VkLayerInstanceDispatchTable *instance_dispatch_table1(VkObject object)
+{
+ VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
+ std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap1.find((void *) pDisp);
+ assert(it != tableInstanceMap1.end() && "Not able to find instance dispatch entry");
+ return it->second;
+}
+
static VkLayerDispatchTable *getLayer1Table(const VkBaseLayerObject *devw)
{
VkLayerDispatchTable *pTable;
@@ -92,8 +109,7 @@
VK_LAYER_EXPORT VkResult VKAPI multi1DestroyDevice(VkDevice device)
{
VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
- VkLayerDispatchTable *pTable = tableMap1[pDisp];
- VkResult res = pTable->DestroyDevice(device);
+ VkResult res = device_dispatch_table1(device)->DestroyDevice(device);
tableMap1.erase(pDisp);
return res;
}
@@ -102,8 +118,7 @@
VK_LAYER_EXPORT VkResult VKAPI multi1DestroyInstance(VkInstance instance)
{
VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
- VkLayerInstanceDispatchTable *pTable = tableInstanceMap1[pDisp];
- VkResult res = pTable->DestroyInstance(instance);
+ VkResult res = instance_dispatch_table1(instance)->DestroyInstance(instance);
tableInstanceMap1.erase(pDisp);
return res;
}
@@ -111,10 +126,9 @@
VK_LAYER_EXPORT VkResult VKAPI multi1CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
{
VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
- VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
printf("At start of multi1 layer vkCreateSampler()\n");
- VkResult result = pTable->CreateSampler(device, pCreateInfo, pSampler);
+ VkResult result = device_dispatch_table1(device)->CreateSampler(device, pCreateInfo, pSampler);
printf("Completed multi1 layer vkCreateSampler()\n");
return result;
}
@@ -123,10 +137,9 @@
VkPipeline* pPipeline)
{
VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
- VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
printf("At start of multi1 layer vkCreateGraphicsPipeline()\n");
- VkResult result = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
+ VkResult result = device_dispatch_table1(device)->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
printf("Completed multi1 layer vkCreateGraphicsPipeline()\n");
return result;
}
@@ -134,10 +147,9 @@
VK_LAYER_EXPORT VkResult VKAPI multi1StorePipeline(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData)
{
VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
- VkLayerDispatchTable *pTable = tableMap1[*ppDisp];
printf("At start of multi1 layer vkStorePipeline()\n");
- VkResult result = pTable->StorePipeline(device, pipeline, pDataSize, pData);
+ VkResult result = device_dispatch_table1(device)->StorePipeline(device, pipeline, pDataSize, pData);
printf("Completed multi1 layer vkStorePipeline()\n");
return result;
}
@@ -165,7 +177,7 @@
return (void *) multi1StorePipeline;
else {
VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
- VkLayerDispatchTable* pTable = tableMap1[*ppDisp];
+ VkLayerDispatchTable* pTable = device_dispatch_table1(device);
if (pTable->GetDeviceProcAddr == NULL)
return NULL;
return pTable->GetDeviceProcAddr(device, pName);
@@ -191,7 +203,7 @@
return (void*) vkGetGlobalExtensionInfo;
else {
VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
- VkLayerInstanceDispatchTable* pTable = tableInstanceMap1[*ppDisp];
+ VkLayerInstanceDispatchTable* pTable = instance_dispatch_table1(inst);
if (pTable->GetInstanceProcAddr == NULL)
return NULL;
return pTable->GetInstanceProcAddr(inst, pName);
@@ -203,6 +215,23 @@
static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap2;
static bool layer2_first_activated = false;
+// Map lookup must be thread safe
+static inline VkLayerDispatchTable *device_dispatch_table2(VkObject object)
+{
+ VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;
+ std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap2.find((void *) pDisp);
+ assert(it != tableMap2.end() && "Not able to find device dispatch entry");
+ return it->second;
+}
+
+static inline VkLayerInstanceDispatchTable *instance_dispatch_table2(VkObject object)
+{
+ VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
+ std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap2.find((void *) pDisp);
+ assert(it != tableInstanceMap2.end() && "Not able to find instance dispatch entry");
+ return it->second;
+}
+
static VkLayerInstanceDispatchTable *getLayer2InstanceTable(const VkBaseLayerObject *instw)
{
VkLayerInstanceDispatchTable *pTable;
@@ -247,10 +276,9 @@
VkPhysicalDevice* pPhysicalDevices)
{
VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
- VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n");
- VkResult result = pInstTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+ VkResult result = instance_dispatch_table2(instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n");
return result;
}
@@ -259,8 +287,7 @@
VK_LAYER_EXPORT VkResult VKAPI multi2DestroyDevice(VkDevice device)
{
VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
- VkLayerDispatchTable *pTable = tableMap2[pDisp];
- VkResult res = pTable->DestroyDevice(device);
+ VkResult res = device_dispatch_table2(device)->DestroyDevice(device);
tableMap2.erase(pDisp);
return res;
}
@@ -269,8 +296,7 @@
VK_LAYER_EXPORT VkResult VKAPI multi2DestroyInstance(VkInstance instance)
{
VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
- VkLayerInstanceDispatchTable *pTable = tableInstanceMap2[pDisp];
- VkResult res = pTable->DestroyInstance(instance);
+ VkResult res = instance_dispatch_table2(instance)->DestroyInstance(instance);
tableInstanceMap2.erase(pDisp);
return res;
}
@@ -279,10 +305,8 @@
VkDevice* pDevice)
{
VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) gpu;
- VkLayerInstanceDispatchTable *pInstTable = tableInstanceMap2[*ppDisp];
-
printf("At start of multi2 vkCreateDevice()\n");
- VkResult result = pInstTable->CreateDevice(gpu, pCreateInfo, pDevice);
+ VkResult result = instance_dispatch_table2(gpu)->CreateDevice(gpu, pCreateInfo, pDevice);
printf("Completed multi2 layer vkCreateDevice()\n");
return result;
}
@@ -291,10 +315,9 @@
VkCmdBuffer* pCmdBuffer)
{
VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
- VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
printf("At start of multi2 layer vkCreateCommandBuffer()\n");
- VkResult result = pTable->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
+ VkResult result = device_dispatch_table2(device)->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
printf("Completed multi2 layer vkCreateCommandBuffer()\n");
return result;
}
@@ -302,10 +325,9 @@
VK_LAYER_EXPORT VkResult VKAPI multi2BeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
{
VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) cmdBuffer;
- VkLayerDispatchTable *pTable = tableMap2[*ppDisp];
printf("At start of multi2 layer vkBeginCommandBuffer()\n");
- VkResult result = pTable->BeginCommandBuffer(cmdBuffer, pBeginInfo);
+ VkResult result = device_dispatch_table2(cmdBuffer)->BeginCommandBuffer(cmdBuffer, pBeginInfo);
printf("Completed multi2 layer vkBeginCommandBuffer()\n");
return result;
@@ -330,7 +352,7 @@
return (void *) multi2BeginCommandBuffer;
else {
VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
- VkLayerDispatchTable* pTable = tableMap2[*ppDisp];
+ VkLayerDispatchTable* pTable = device_dispatch_table2(device);
if (pTable->GetDeviceProcAddr == NULL)
return NULL;
return pTable->GetDeviceProcAddr(device, pName);
@@ -358,7 +380,7 @@
return (void*) vkGetGlobalExtensionInfo;
else {
VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
- VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[*ppDisp];
+ VkLayerInstanceDispatchTable* pTable = instance_dispatch_table2(inst);
if (pTable->GetInstanceProcAddr == NULL)
return NULL;
return pTable->GetInstanceProcAddr(inst, pName);