diff options
| author | Tobin Ehlis <tobine@google.com> | 2016-04-13 12:59:43 -0600 |
|---|---|---|
| committer | Tobin Ehlis <tobine@google.com> | 2016-04-14 16:43:21 -0600 |
| commit | dcab5c002f0494a9651022c7d0c03bc2e91ce76e (patch) | |
| tree | 11d93dff07e9964fc0617f3245e7887758f85a94 | |
| parent | b4caf1b9c5541899bc987565330bb599f0ad2f61 (diff) | |
| download | usermoji-dcab5c002f0494a9651022c7d0c03bc2e91ce76e.tar.xz | |
layers: Overhaul unique_objects
Unique objects now uses a 64-bit counter as the unique handle returned
to the app. It stores an internal mapping of handles to actual object
ptrs that are used for all non-dispatchable objects. This virtually
eliminates the possibility of having a repeat handle as objects
are created and destroyed.
All counter increments and map accesses are protected by a mutex.
| -rw-r--r-- | layers/unique_objects.h | 342 | ||||
| -rwxr-xr-x | vk-layer-generate.py | 54 |
2 files changed, 118 insertions, 278 deletions
diff --git a/layers/unique_objects.h b/layers/unique_objects.h index 3fbf54e5..b4376a54 100644 --- a/layers/unique_objects.h +++ b/layers/unique_objects.h @@ -33,8 +33,9 @@ #include <string.h> #include <inttypes.h> -#include <vector> #include <unordered_map> +#include <vector> +#include <mutex> #include "vulkan/vk_layer.h" #include "vk_layer_config.h" @@ -47,8 +48,11 @@ struct layer_data { bool wsi_enabled; + uint64_t unique_id; // All increments are guarded by global_lock + std::unordered_map<uint64_t, uint64_t> unique_id_mapping; // Map uniqueID to actual object handle + VkPhysicalDevice gpu; - layer_data() : wsi_enabled(false){}; + layer_data() : wsi_enabled(false), unique_id(1), gpu(VK_NULL_HANDLE){}; }; struct instExts { @@ -65,11 +69,7 @@ static std::unordered_map<void *, struct instExts> instanceExtMap; static std::unordered_map<void *, layer_data *> layer_data_map; static device_table_map unique_objects_device_table_map; static instance_table_map unique_objects_instance_table_map; -// Structure to wrap returned non-dispatchable objects to guarantee they have unique handles -// address of struct will be used as the unique handle -struct VkUniqueObject { - uint64_t actualObject; -}; +static std::mutex global_lock; // Protect map accesses and unique_id increments // Handle CreateInstance static void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) { @@ -172,6 +172,11 @@ VkResult explicit_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const return result; } +void explicit_DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { + get_dispatch_table(unique_objects_instance_table_map, instance)->DestroyInstance(instance, pAllocator); + layer_data_map.erase(get_dispatch_key(instance)); +} + // Handle CreateDevice static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) { layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); @@ -213,233 +218,16 @@ VkResult explicit_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *p initDeviceTable(*pDevice, fpGetDeviceProcAddr, unique_objects_device_table_map); createDeviceRegisterExtensions(pCreateInfo, *pDevice); + // Set gpu for this device in order to get at any objects mapped at instance level + layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); + my_device_data->gpu = gpu; return result; } -VkResult explicit_QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) { - // UNWRAP USES: - // 0 : fence,VkFence - if (VK_NULL_HANDLE != fence) { - fence = (VkFence)((VkUniqueObject *)fence)->actualObject; - } - // waitSemaphoreCount : pSubmits[submitCount]->pWaitSemaphores,VkSemaphore - std::vector<VkSemaphore> original_pWaitSemaphores = {}; - // signalSemaphoreCount : pSubmits[submitCount]->pSignalSemaphores,VkSemaphore - std::vector<VkSemaphore> original_pSignalSemaphores = {}; - if (pSubmits) { - for (uint32_t index0 = 0; index0 < submitCount; ++index0) { - if (pSubmits[index0].pWaitSemaphores) { - for (uint32_t index1 = 0; index1 < pSubmits[index0].waitSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pSubmits[index0].pWaitSemaphores); - original_pWaitSemaphores.push_back(pSubmits[index0].pWaitSemaphores[index1]); - *(ppSemaphore[index1]) = - (VkSemaphore)((VkUniqueObject *)pSubmits[index0].pWaitSemaphores[index1])->actualObject; - } - } - if (pSubmits[index0].pSignalSemaphores) { - for (uint32_t index1 = 0; index1 < pSubmits[index0].signalSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pSubmits[index0].pSignalSemaphores); - original_pSignalSemaphores.push_back(pSubmits[index0].pSignalSemaphores[index1]); - *(ppSemaphore[index1]) = - (VkSemaphore)((VkUniqueObject *)pSubmits[index0].pSignalSemaphores[index1])->actualObject; - } - } - } - } - VkResult result = get_dispatch_table(unique_objects_device_table_map, queue)->QueueSubmit(queue, submitCount, pSubmits, fence); - if (pSubmits) { - for (uint32_t index0 = 0; index0 < submitCount; ++index0) { - if (pSubmits[index0].pWaitSemaphores) { - for (uint32_t index1 = 0; index1 < pSubmits[index0].waitSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pSubmits[index0].pWaitSemaphores); - *(ppSemaphore[index1]) = original_pWaitSemaphores[index1]; - } - } - if (pSubmits[index0].pSignalSemaphores) { - for (uint32_t index1 = 0; index1 < pSubmits[index0].signalSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pSubmits[index0].pSignalSemaphores); - *(ppSemaphore[index1]) = original_pSignalSemaphores[index1]; - } - } - } - } - return result; -} - -VkResult explicit_QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence) { - // UNWRAP USES: - // 0 : pBindInfo[bindInfoCount]->pBufferBinds[bufferBindCount]->buffer,VkBuffer, - // pBindInfo[bindInfoCount]->pBufferBinds[bufferBindCount]->pBinds[bindCount]->memory,VkDeviceMemory, - // pBindInfo[bindInfoCount]->pImageOpaqueBinds[imageOpaqueBindCount]->image,VkImage, - // pBindInfo[bindInfoCount]->pImageOpaqueBinds[imageOpaqueBindCount]->pBinds[bindCount]->memory,VkDeviceMemory, - // pBindInfo[bindInfoCount]->pImageBinds[imageBindCount]->image,VkImage, - // pBindInfo[bindInfoCount]->pImageBinds[imageBindCount]->pBinds[bindCount]->memory,VkDeviceMemory - std::vector<VkBuffer> original_buffer = {}; - std::vector<VkDeviceMemory> original_memory1 = {}; - std::vector<VkImage> original_image1 = {}; - std::vector<VkDeviceMemory> original_memory2 = {}; - std::vector<VkImage> original_image2 = {}; - std::vector<VkDeviceMemory> original_memory3 = {}; - std::vector<VkSemaphore> original_pWaitSemaphores = {}; - std::vector<VkSemaphore> original_pSignalSemaphores = {}; - if (pBindInfo) { - for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) { - if (pBindInfo[index0].pBufferBinds) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].bufferBindCount; ++index1) { - if (pBindInfo[index0].pBufferBinds[index1].buffer) { - VkBuffer *pBuffer = (VkBuffer *)&(pBindInfo[index0].pBufferBinds[index1].buffer); - original_buffer.push_back(pBindInfo[index0].pBufferBinds[index1].buffer); - *(pBuffer) = (VkBuffer)((VkUniqueObject *)pBindInfo[index0].pBufferBinds[index1].buffer)->actualObject; - } - if (pBindInfo[index0].pBufferBinds[index1].pBinds) { - for (uint32_t index2 = 0; index2 < pBindInfo[index0].pBufferBinds[index1].bindCount; ++index2) { - if (pBindInfo[index0].pBufferBinds[index1].pBinds[index2].memory) { - VkDeviceMemory *pDeviceMemory = - (VkDeviceMemory *)&(pBindInfo[index0].pBufferBinds[index1].pBinds[index2].memory); - original_memory1.push_back(pBindInfo[index0].pBufferBinds[index1].pBinds[index2].memory); - *(pDeviceMemory) = - (VkDeviceMemory)((VkUniqueObject *)pBindInfo[index0].pBufferBinds[index1].pBinds[index2].memory) - ->actualObject; - } - } - } - } - } - if (pBindInfo[index0].pImageOpaqueBinds) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].imageOpaqueBindCount; ++index1) { - if (pBindInfo[index0].pImageOpaqueBinds[index1].image) { - VkImage *pImage = (VkImage *)&(pBindInfo[index0].pImageOpaqueBinds[index1].image); - original_image1.push_back(pBindInfo[index0].pImageOpaqueBinds[index1].image); - *(pImage) = (VkImage)((VkUniqueObject *)pBindInfo[index0].pImageOpaqueBinds[index1].image)->actualObject; - } - if (pBindInfo[index0].pImageOpaqueBinds[index1].pBinds) { - for (uint32_t index2 = 0; index2 < pBindInfo[index0].pImageOpaqueBinds[index1].bindCount; ++index2) { - if (pBindInfo[index0].pImageOpaqueBinds[index1].pBinds[index2].memory) { - VkDeviceMemory *pDeviceMemory = - (VkDeviceMemory *)&(pBindInfo[index0].pImageOpaqueBinds[index1].pBinds[index2].memory); - original_memory2.push_back(pBindInfo[index0].pImageOpaqueBinds[index1].pBinds[index2].memory); - *(pDeviceMemory) = - (VkDeviceMemory)( - (VkUniqueObject *)pBindInfo[index0].pImageOpaqueBinds[index1].pBinds[index2].memory) - ->actualObject; - } - } - } - } - } - if (pBindInfo[index0].pImageBinds) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].imageBindCount; ++index1) { - if (pBindInfo[index0].pImageBinds[index1].image) { - VkImage *pImage = (VkImage *)&(pBindInfo[index0].pImageBinds[index1].image); - original_image2.push_back(pBindInfo[index0].pImageBinds[index1].image); - *(pImage) = (VkImage)((VkUniqueObject *)pBindInfo[index0].pImageBinds[index1].image)->actualObject; - } - if (pBindInfo[index0].pImageBinds[index1].pBinds) { - for (uint32_t index2 = 0; index2 < pBindInfo[index0].pImageBinds[index1].bindCount; ++index2) { - if (pBindInfo[index0].pImageBinds[index1].pBinds[index2].memory) { - VkDeviceMemory *pDeviceMemory = - (VkDeviceMemory *)&(pBindInfo[index0].pImageBinds[index1].pBinds[index2].memory); - original_memory3.push_back(pBindInfo[index0].pImageBinds[index1].pBinds[index2].memory); - *(pDeviceMemory) = - (VkDeviceMemory)((VkUniqueObject *)pBindInfo[index0].pImageBinds[index1].pBinds[index2].memory) - ->actualObject; - } - } - } - } - } - if (pBindInfo[index0].pWaitSemaphores) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].waitSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pBindInfo[index0].pWaitSemaphores); - original_pWaitSemaphores.push_back(pBindInfo[index0].pWaitSemaphores[index1]); - *(ppSemaphore[index1]) = - (VkSemaphore)((VkUniqueObject *)pBindInfo[index0].pWaitSemaphores[index1])->actualObject; - } - } - if (pBindInfo[index0].pSignalSemaphores) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].signalSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pBindInfo[index0].pSignalSemaphores); - original_pSignalSemaphores.push_back(pBindInfo[index0].pSignalSemaphores[index1]); - *(ppSemaphore[index1]) = - (VkSemaphore)((VkUniqueObject *)pBindInfo[index0].pSignalSemaphores[index1])->actualObject; - } - } - } - } - if (VK_NULL_HANDLE != fence) { - fence = (VkFence)((VkUniqueObject *)fence)->actualObject; - } - VkResult result = - get_dispatch_table(unique_objects_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence); - if (pBindInfo) { - for (uint32_t index0 = 0; index0 < bindInfoCount; ++index0) { - if (pBindInfo[index0].pBufferBinds) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].bufferBindCount; ++index1) { - if (pBindInfo[index0].pBufferBinds[index1].buffer) { - VkBuffer *pBuffer = (VkBuffer *)&(pBindInfo[index0].pBufferBinds[index1].buffer); - *(pBuffer) = original_buffer[index1]; - } - if (pBindInfo[index0].pBufferBinds[index1].pBinds) { - for (uint32_t index2 = 0; index2 < pBindInfo[index0].pBufferBinds[index1].bindCount; ++index2) { - if (pBindInfo[index0].pBufferBinds[index1].pBinds[index2].memory) { - VkDeviceMemory *pDeviceMemory = - (VkDeviceMemory *)&(pBindInfo[index0].pBufferBinds[index1].pBinds[index2].memory); - *(pDeviceMemory) = original_memory1[index2]; - } - } - } - } - } - if (pBindInfo[index0].pImageOpaqueBinds) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].imageOpaqueBindCount; ++index1) { - if (pBindInfo[index0].pImageOpaqueBinds[index1].image) { - VkImage *pImage = (VkImage *)&(pBindInfo[index0].pImageOpaqueBinds[index1].image); - *(pImage) = original_image1[index1]; - } - if (pBindInfo[index0].pImageOpaqueBinds[index1].pBinds) { - for (uint32_t index2 = 0; index2 < pBindInfo[index0].pImageOpaqueBinds[index1].bindCount; ++index2) { - if (pBindInfo[index0].pImageOpaqueBinds[index1].pBinds[index2].memory) { - VkDeviceMemory *pDeviceMemory = - (VkDeviceMemory *)&(pBindInfo[index0].pImageOpaqueBinds[index1].pBinds[index2].memory); - *(pDeviceMemory) = original_memory2[index2]; - } - } - } - } - } - if (pBindInfo[index0].pImageBinds) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].imageBindCount; ++index1) { - if (pBindInfo[index0].pImageBinds[index1].image) { - VkImage *pImage = (VkImage *)&(pBindInfo[index0].pImageBinds[index1].image); - *(pImage) = original_image2[index1]; - } - if (pBindInfo[index0].pImageBinds[index1].pBinds) { - for (uint32_t index2 = 0; index2 < pBindInfo[index0].pImageBinds[index1].bindCount; ++index2) { - if (pBindInfo[index0].pImageBinds[index1].pBinds[index2].memory) { - VkDeviceMemory *pDeviceMemory = - (VkDeviceMemory *)&(pBindInfo[index0].pImageBinds[index1].pBinds[index2].memory); - *(pDeviceMemory) = original_memory3[index2]; - } - } - } - } - } - if (pBindInfo[index0].pWaitSemaphores) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].waitSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pBindInfo[index0].pWaitSemaphores); - *(ppSemaphore[index1]) = original_pWaitSemaphores[index1]; - } - } - if (pBindInfo[index0].pSignalSemaphores) { - for (uint32_t index1 = 0; index1 < pBindInfo[index0].signalSemaphoreCount; ++index1) { - VkSemaphore **ppSemaphore = (VkSemaphore **)&(pBindInfo[index0].pSignalSemaphores); - *(ppSemaphore[index1]) = original_pSignalSemaphores[index1]; - } - } - } - } - return result; +void explicit_DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { + get_dispatch_table(unique_objects_device_table_map, device)->DestroyDevice(device, pAllocator); + layer_data_map.erase(get_dispatch_key(device)); } VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, @@ -448,38 +236,44 @@ VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipeli // STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'stage': {'module': 'VkShaderModule'}, // 'layout': 'VkPipelineLayout', 'basePipelineHandle': 'VkPipeline'}} // LOCAL DECLS:{'pCreateInfos': 'VkComputePipelineCreateInfo*'} + layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); safe_VkComputePipelineCreateInfo *local_pCreateInfos = NULL; if (pCreateInfos) { + std::lock_guard<std::mutex> lock(global_lock); local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount]; for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) { local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]); if (pCreateInfos[idx0].basePipelineHandle) { local_pCreateInfos[idx0].basePipelineHandle = - (VkPipeline)((VkUniqueObject *)pCreateInfos[idx0].basePipelineHandle)->actualObject; + (VkPipeline) + my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfos[idx0].basePipelineHandle)]; } if (pCreateInfos[idx0].layout) { - local_pCreateInfos[idx0].layout = (VkPipelineLayout)((VkUniqueObject *)pCreateInfos[idx0].layout)->actualObject; + local_pCreateInfos[idx0].layout = + (VkPipelineLayout)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfos[idx0].layout)]; } if (pCreateInfos[idx0].stage.module) { local_pCreateInfos[idx0].stage.module = - (VkShaderModule)((VkUniqueObject *)pCreateInfos[idx0].stage.module)->actualObject; + (VkShaderModule)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfos[idx0].stage.module)]; } } } if (pipelineCache) { - pipelineCache = (VkPipelineCache)((VkUniqueObject *)pipelineCache)->actualObject; + std::lock_guard<std::mutex> lock(global_lock); + pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pipelineCache)]; } - // CODEGEN : file /usr/local/google/home/tobine/vulkan_work/LoaderAndTools/vk-layer-generate.py line #1671 + VkResult result = get_dispatch_table(unique_objects_device_table_map, device) ->CreateComputePipelines(device, pipelineCache, createInfoCount, (const VkComputePipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines); delete[] local_pCreateInfos; if (VK_SUCCESS == result) { - VkUniqueObject *pUO = NULL; + uint64_t unique_id = 0; + std::lock_guard<std::mutex> lock(global_lock); for (uint32_t i = 0; i < createInfoCount; ++i) { - pUO = new VkUniqueObject(); - pUO->actualObject = (uint64_t)pPipelines[i]; - pPipelines[i] = (VkPipeline)pUO; + unique_id = my_device_data->unique_id++; + my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t>(pPipelines[i]); + pPipelines[i] = reinterpret_cast<VkPipeline>(unique_id); } } return result; @@ -491,68 +285,108 @@ VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipel // STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'layout': 'VkPipelineLayout', // 'pStages[stageCount]': {'module': 'VkShaderModule'}, 'renderPass': 'VkRenderPass', 'basePipelineHandle': 'VkPipeline'}} // LOCAL DECLS:{'pCreateInfos': 'VkGraphicsPipelineCreateInfo*'} + layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = NULL; if (pCreateInfos) { local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount]; + std::lock_guard<std::mutex> lock(global_lock); for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) { local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]); if (pCreateInfos[idx0].basePipelineHandle) { local_pCreateInfos[idx0].basePipelineHandle = - (VkPipeline)((VkUniqueObject *)pCreateInfos[idx0].basePipelineHandle)->actualObject; + (VkPipeline) + my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfos[idx0].basePipelineHandle)]; } if (pCreateInfos[idx0].layout) { - local_pCreateInfos[idx0].layout = (VkPipelineLayout)((VkUniqueObject *)pCreateInfos[idx0].layout)->actualObject; + local_pCreateInfos[idx0].layout = + (VkPipelineLayout)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfos[idx0].layout)]; } if (pCreateInfos[idx0].pStages) { for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) { if (pCreateInfos[idx0].pStages[idx1].module) { local_pCreateInfos[idx0].pStages[idx1].module = - (VkShaderModule)((VkUniqueObject *)pCreateInfos[idx0].pStages[idx1].module)->actualObject; + (VkShaderModule)my_device_data + ->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfos[idx0].pStages[idx1].module)]; } } } if (pCreateInfos[idx0].renderPass) { - local_pCreateInfos[idx0].renderPass = (VkRenderPass)((VkUniqueObject *)pCreateInfos[idx0].renderPass)->actualObject; + local_pCreateInfos[idx0].renderPass = + (VkRenderPass)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfos[idx0].renderPass)]; } } } if (pipelineCache) { - pipelineCache = (VkPipelineCache)((VkUniqueObject *)pipelineCache)->actualObject; + std::lock_guard<std::mutex> lock(global_lock); + pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(pipelineCache)]; } - // CODEGEN : file /usr/local/google/home/tobine/vulkan_work/LoaderAndTools/vk-layer-generate.py line #1671 + VkResult result = get_dispatch_table(unique_objects_device_table_map, device) ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, (const VkGraphicsPipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines); delete[] local_pCreateInfos; if (VK_SUCCESS == result) { - VkUniqueObject *pUO = NULL; + uint64_t unique_id = 0; + std::lock_guard<std::mutex> lock(global_lock); for (uint32_t i = 0; i < createInfoCount; ++i) { - pUO = new VkUniqueObject(); - pUO->actualObject = (uint64_t)pPipelines[i]; - pPipelines[i] = (VkPipeline)pUO; + unique_id = my_device_data->unique_id++; + my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t>(pPipelines[i]); + pPipelines[i] = reinterpret_cast<VkPipeline>(unique_id); } } return result; } +VkResult explicit_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) { + layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + + safe_VkSwapchainCreateInfoKHR *local_pCreateInfo = NULL; + if (pCreateInfo) { + std::lock_guard<std::mutex> lock(global_lock); + local_pCreateInfo = new safe_VkSwapchainCreateInfoKHR(pCreateInfo); + local_pCreateInfo->oldSwapchain = + (VkSwapchainKHR)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfo->oldSwapchain)]; + // Need to pull surface mapping from the instance-level map + layer_data *instance_data = get_my_data_ptr(get_dispatch_key(my_map_data->gpu), layer_data_map); + local_pCreateInfo->surface = + (VkSurfaceKHR)instance_data->unique_id_mapping[reinterpret_cast<uint64_t>(pCreateInfo->surface)]; + } + + VkResult result = get_dispatch_table(unique_objects_device_table_map, device) + ->CreateSwapchainKHR(device, (const VkSwapchainCreateInfoKHR *)local_pCreateInfo, pAllocator, pSwapchain); + if (local_pCreateInfo) + delete local_pCreateInfo; + if (VK_SUCCESS == result) { + std::lock_guard<std::mutex> lock(global_lock); + uint64_t unique_id = my_map_data->unique_id++; + my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t>(*pSwapchain); + *pSwapchain = reinterpret_cast<VkSwapchainKHR>(unique_id); + } + return result; +} + VkResult explicit_GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { // UNWRAP USES: // 0 : swapchain,VkSwapchainKHR, pSwapchainImages,VkImage + layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); if (VK_NULL_HANDLE != swapchain) { - swapchain = (VkSwapchainKHR)((VkUniqueObject *)swapchain)->actualObject; + std::lock_guard<std::mutex> lock(global_lock); + swapchain = (VkSwapchainKHR)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t>(swapchain)]; } VkResult result = get_dispatch_table(unique_objects_device_table_map, device) ->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages); // TODO : Need to add corresponding code to delete these images if (VK_SUCCESS == result) { if ((*pSwapchainImageCount > 0) && pSwapchainImages) { - std::vector<VkUniqueObject *> uniqueImages = {}; + uint64_t unique_id = 0; + std::lock_guard<std::mutex> lock(global_lock); for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) { - uniqueImages.push_back(new VkUniqueObject()); - uniqueImages[i]->actualObject = (uint64_t)pSwapchainImages[i]; - pSwapchainImages[i] = (VkImage)uniqueImages[i]; + unique_id = my_device_data->unique_id++; + my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t>(pSwapchainImages[i]); + pSwapchainImages[i] = reinterpret_cast<VkImage>(unique_id); } } } diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 205f2bc4..0a36b778 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -208,7 +208,7 @@ class Subcommand(object): * Copyright (c) 2015-2016 The Khronos Group Inc. * Copyright (c) 2015-2016 Valve Corporation * Copyright (c) 2015-2016 LunarG, Inc. - * Copyright (c) 2015 Google, Inc. + * Copyright (c) 2015-2016 Google, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and/or associated documentation files (the "Materials"), to @@ -1435,7 +1435,7 @@ class UniqueObjectsSubcommand(Subcommand): (name, array) = obj.split('[') array = array.strip(']') ptr_type = False - if 'p' == obj[0] and obj[1] != obj[1].lower(): # TODO : Not idea way to determine ptr + if 'p' == obj[0] and obj[1] != obj[1].lower(): # TODO : Not ideal way to determine ptr ptr_type = True if isinstance(struct_uses[obj], dict): local_prefix = '' @@ -1480,7 +1480,7 @@ class UniqueObjectsSubcommand(Subcommand): else: if (array_index > 0) or array != '': # TODO : This is not ideal, really want to know if we're anywhere under an array if first_level_param: - pre_code += '%s%s* local_%s = NULL;\n' % (indent, struct_uses[obj], name) + decls += '%s%s* local_%s = NULL;\n' % (indent, struct_uses[obj], name) if array != '' and not first_level_param: # ptrs under structs will have been initialized so use local_* pre_code += '%sif (local_%s%s) {\n' %(indent, prefix, name) else: @@ -1499,7 +1499,7 @@ class UniqueObjectsSubcommand(Subcommand): pName = 'p%s' % (struct_uses[obj][2:]) if name not in vector_name_set: vector_name_set.add(name) - pre_code += '%slocal_%s%s = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, prefix, name, struct_uses[obj], prefix, name) + pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name) if array != '': indent = indent[4:] pre_code += '%s}\n' % (indent) @@ -1507,18 +1507,13 @@ class UniqueObjectsSubcommand(Subcommand): pre_code += '%s}\n' % (indent) else: pre_code += '%s\n' % (self.lineinfo.get()) - pre_code += '%sif (%s%s) {\n' %(indent, prefix, name) - indent += ' ' deref_txt = '&' if ptr_type: deref_txt = '' if '->' in prefix: # need to update local struct - pre_code += '%slocal_%s%s = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, prefix, name, struct_uses[obj], prefix, name) + pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name) else: - pre_code += '%s%s* p%s = (%s*)%s%s%s;\n' % (indent, struct_uses[obj], name, struct_uses[obj], deref_txt, prefix, name) - pre_code += '%s*p%s = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, name, struct_uses[obj], prefix, name) - indent = indent[4:] - pre_code += '%s}\n' % (indent) + pre_code += '%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t>(%s)];\n' % (indent, name, struct_uses[obj], name) return decls, pre_code, post_code def generate_intercept(self, proto, qual): @@ -1533,8 +1528,11 @@ class UniqueObjectsSubcommand(Subcommand): # A few API cases that are manual code # TODO : Special case Create*Pipelines funcs to handle creating multiple unique objects explicit_object_tracker_functions = ['GetSwapchainImagesKHR', + 'CreateSwapchainKHR', 'CreateInstance', + 'DestroyInstance', 'CreateDevice', + 'DestroyDevice', 'CreateComputePipelines', 'CreateGraphicsPipelines' ] @@ -1566,14 +1564,22 @@ class UniqueObjectsSubcommand(Subcommand): # First thing we need to do is gather uses of non-dispatchable-objects (ndos) (struct_uses, local_decls) = get_object_uses(vulkan.object_non_dispatch_list, proto.params[1:last_param_index]) + dispatch_param = proto.params[0].name + if 'CreateInstance' in proto.name: + dispatch_param = '*' + proto.params[1].name + pre_call_txt += '%slayer_data *my_map_data = get_my_data_ptr(get_dispatch_key(%s), layer_data_map);\n' % (indent, dispatch_param) if len(struct_uses) > 0: pre_call_txt += '// STRUCT USES:%s\n' % sorted(struct_uses) if len(local_decls) > 0: pre_call_txt += '//LOCAL DECLS:%s\n' % sorted(local_decls) if destroy_func: # only one object for del_obj in sorted(struct_uses): - pre_call_txt += '%s%s local_%s = %s;\n' % (indent, struct_uses[del_obj], del_obj, del_obj) - (pre_decl, pre_code, post_code) = self._gen_obj_code(struct_uses, local_decls, ' ', '', 0, set(), True) + #pre_call_txt += '%s%s local_%s = %s;\n' % (indent, struct_uses[del_obj], del_obj, del_obj) + pre_call_txt += '%suint64_t local_%s = reinterpret_cast<uint64_t>(%s);\n' % (indent, del_obj, del_obj) + pre_call_txt += '%s%s = (%s)my_map_data->unique_id_mapping[local_%s];\n' % (indent, del_obj, struct_uses[del_obj], del_obj) + (pre_decl, pre_code, post_code) = ('', '', '') + else: + (pre_decl, pre_code, post_code) = self._gen_obj_code(struct_uses, local_decls, ' ', '', 0, set(), True) # This is a bit hacky but works for now. Need to decl local versions of top-level structs for ld in sorted(local_decls): init_null_txt = 'NULL'; @@ -1581,6 +1587,8 @@ class UniqueObjectsSubcommand(Subcommand): init_null_txt = '{}'; if local_decls[ld].strip('*') not in vulkan.object_non_dispatch_list: pre_decl += ' safe_%s local_%s = %s;\n' % (local_decls[ld], ld, init_null_txt) + if pre_code != '': # lock around map uses + pre_code = '%s{\n%sstd::lock_guard<std::mutex> lock(global_lock);\n%s%s}\n' % (indent, indent, pre_code, indent) pre_call_txt += '%s%s' % (pre_decl, pre_code) post_call_txt += '%s' % (post_code) elif create_func: @@ -1595,9 +1603,6 @@ class UniqueObjectsSubcommand(Subcommand): if proto.ret != "void": ret_val = "%s result = " % proto.ret ret_stmt = " return result;\n" - dispatch_param = proto.params[0].name - if 'CreateInstance' in proto.name: - dispatch_param = '*' + proto.params[1].name if create_func: obj_type = proto.params[-1].ty.strip('*') obj_name = proto.params[-1].name @@ -1605,22 +1610,22 @@ class UniqueObjectsSubcommand(Subcommand): local_name = "unique%s" % obj_type[2:] post_call_txt += '%sif (VK_SUCCESS == result) {\n' % (indent) indent += ' ' + post_call_txt += '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % (indent) if obj_name in custom_create_dict: post_call_txt += '%s\n' % (self.lineinfo.get()) local_name = '%ss' % (local_name) # add 's' to end for vector of many - post_call_txt += '%sstd::vector<VkUniqueObject*> %s = {};\n' % (indent, local_name) post_call_txt += '%sfor (uint32_t i=0; i<%s; ++i) {\n' % (indent, custom_create_dict[obj_name]) indent += ' ' - post_call_txt += '%s%s.push_back(new VkUniqueObject());\n' % (indent, local_name) - post_call_txt += '%s%s[i]->actualObject = (uint64_t)%s[i];\n' % (indent, local_name, obj_name) - post_call_txt += '%s%s[i] = (%s)%s[i];\n' % (indent, obj_name, obj_type, local_name) + post_call_txt += '%suint64_t unique_id = my_map_data->unique_id++;\n' % (indent) + post_call_txt += '%smy_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t>(%s[i]);\n' % (indent, obj_name) + post_call_txt += '%s%s[i] = reinterpret_cast<%s>(unique_id);\n' % (indent, obj_name, obj_type) indent = indent[4:] post_call_txt += '%s}\n' % (indent) else: post_call_txt += '%s\n' % (self.lineinfo.get()) - post_call_txt += '%sVkUniqueObject* %s = new VkUniqueObject();\n' % (indent, local_name) - post_call_txt += '%s%s->actualObject = (uint64_t)*%s;\n' % (indent, local_name, obj_name) - post_call_txt += '%s*%s = (%s)%s;\n' % (indent, obj_name, obj_type, local_name) + post_call_txt += '%suint64_t unique_id = my_map_data->unique_id++;\n' % (indent) + post_call_txt += '%smy_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t>(*%s);\n' % (indent, obj_name) + post_call_txt += '%s*%s = reinterpret_cast<%s>(unique_id);\n' % (indent, obj_name, obj_type) indent = indent[4:] post_call_txt += '%s}\n' % (indent) elif destroy_func: @@ -1635,7 +1640,8 @@ class UniqueObjectsSubcommand(Subcommand): post_call_txt += '%s}\n' % (indent) else: post_call_txt += '%s\n' % (self.lineinfo.get()) - post_call_txt = '%sdelete (VkUniqueObject*)local_%s;\n' % (indent, proto.params[-2].name) + post_call_txt += '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % (indent) + post_call_txt += '%smy_map_data->unique_id_mapping.erase(local_%s);\n' % (indent, proto.params[-2].name) call_sig = proto.c_call() # Replace default params with any custom local params |
