From 2a964149e5daa6429e217f7a49e334acdbfe0a7a Mon Sep 17 00:00:00 2001 From: Tobin Ehlis Date: Tue, 8 Dec 2015 10:50:10 -0700 Subject: layers: Add UniqueObjects layer to wrap objects in unique ptr This layer should sit at the BOTTOM of the layer stack (closest to the driver, furthest from the app). It interecpts all created non-dispatchable-objects and wraps them in a struct, returning that struct ptr up the chain. For all API calls that use NDOs, this layer will unwrap them, and overwrite the wrapped handle with the actual handle before passing it down. Then, after calling down to the driver, the layer will re-overwrite the NDO handles with the original, wrapped handle. When an NDO object is destroyed, the actual handle is passed down, then the wrap struct object is destroyed. --- layers/unique_objects.h | 671 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 671 insertions(+) create mode 100644 layers/unique_objects.h (limited to 'layers/unique_objects.h') diff --git a/layers/unique_objects.h b/layers/unique_objects.h new file mode 100644 index 00000000..f12cf8c3 --- /dev/null +++ b/layers/unique_objects.h @@ -0,0 +1,671 @@ +/* + * + * Copyright (C) 2015 Google, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Tobin Ehlis + */ + +// CODEGEN : file vk-layer-generate.py line #1757 +#include +#include +#include +#include + +#include "vulkan/vulkan.h" +#include "vk_loader_platform.h" + +#include +#include + +#include "vulkan/vk_layer.h" +#include "vk_layer_config.h" +//#include "vulkan/vk_lunarg_debug_report.h" +#include "vk_layer_table.h" +#include "vk_layer_data.h" +#include "vk_layer_logging.h" +#include "vk_layer_extension_utils.h" + +struct layer_data { + debug_report_data *report_data; + VkDebugReportCallbackEXT logging_callback; + bool wsi_enabled; + + layer_data() : + report_data(nullptr), + logging_callback(VK_NULL_HANDLE), + wsi_enabled(false) + {}; +}; + +struct instExts { + bool wsi_enabled; +}; + +static std::unordered_map instanceExtMap; +static std::unordered_map 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 void +initUniqueObjects( + layer_data *my_data, + const VkAllocationCallbacks *pAllocator) +{ + uint32_t report_flags = 0; + uint32_t debug_action = 0; + FILE *log_output = NULL; + const char *option_str; + // initialize UniqueObjects options + report_flags = getLayerOptionFlags("UniqueObjectsReportFlags", 0); + getLayerOptionEnum("UniqueObjectsDebugAction", (uint32_t *) &debug_action); + + if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) + { + option_str = getLayerOption("UniqueObjectsLogFilename"); + log_output = getLayerLogOutput(option_str, "UniqueObjects"); + VkDebugReportCallbackCreateInfoEXT dbgInfo; + memset(&dbgInfo, 0, sizeof(dbgInfo)); + dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + dbgInfo.pfnCallback = log_callback; + dbgInfo.pUserData = log_output; + dbgInfo.flags = report_flags; + layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &my_data->logging_callback); + } +} + +// Handle CreateInstance +static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreateInfo, VkInstance instance) +{ + uint32_t i; + VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance); + PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr; + pDisp->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR"); + pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); + pDisp->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR"); + pDisp->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR"); +#if VK_USE_PLATFORM_WIN32_KHR + pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) gpa(instance, "vkCreateWin32SurfaceKHR"); + pDisp->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR"); +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_XCB_KHR + pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR"); + pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR"); +#endif // VK_USE_PLATFORM_XCB_KHR +#ifdef VK_USE_PLATFORM_XLIB_KHR + pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) gpa(instance, "vkCreateXlibSurfaceKHR"); + pDisp->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR"); +#endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_MIR_KHR + pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR) gpa(instance, "vkCreateMirSurfaceKHR"); + pDisp->GetPhysicalDeviceMirPresentationSupportKHR = (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR"); +#endif // VK_USE_PLATFORM_MIR_KHR +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR) gpa(instance, "vkCreateWaylandSurfaceKHR"); + pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR"); +#endif // VK_USE_PLATFORM_WAYLAND_KHR +#ifdef VK_USE_PLATFORM_ANDROID_KHR + pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) gpa(instance, "vkCreateAndroidSurfaceKHR"); +#endif // VK_USE_PLATFORM_ANDROID_KHR + + instanceExtMap[pDisp].wsi_enabled = false; + for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) { + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) + instanceExtMap[pDisp].wsi_enabled = true; + } +} + +VkResult +explicit_CreateInstance( + const VkInstanceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkInstance *pInstance) +{ + + VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(unique_objects_instance_table_map, *pInstance); + VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance); + + if (result == VK_SUCCESS) { + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); + my_data->report_data = debug_report_create_instance( + pInstanceTable, + *pInstance, + pCreateInfo->enabledExtensionNameCount, + pCreateInfo->ppEnabledExtensionNames); + createInstanceRegisterExtensions(pCreateInfo, *pInstance); + + initUniqueObjects(my_data, pAllocator); + } + return result; +} + +// 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); + VkLayerDispatchTable *pDisp = get_dispatch_table(unique_objects_device_table_map, device); + PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr; + pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR"); + pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR"); + pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR"); + pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR"); + pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR"); + my_device_data->wsi_enabled = false; + for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) { + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) + my_device_data->wsi_enabled = true; + } +} + +VkResult +explicit_CreateDevice( + VkPhysicalDevice gpu, + const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDevice *pDevice) +{ + VkLayerDispatchTable *pDeviceTable = get_dispatch_table(unique_objects_device_table_map, *pDevice); + VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result == VK_SUCCESS) { + layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map); + layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); + my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + } + 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 original_pWaitSemaphores = {}; +// signalSemaphoreCount : pSubmits[submitCount]->pSignalSemaphores,VkSemaphore + std::vector original_pSignalSemaphores = {}; + if (pSubmits) { + for (uint32_t index0=0; index0actualObject; + } + } + if (pSubmits[index0].pSignalSemaphores) { + for (uint32_t index1=0; index1actualObject; + } + } + } + } + VkResult result = get_dispatch_table(unique_objects_device_table_map, queue)->QueueSubmit(queue, submitCount, pSubmits, fence); + if (pSubmits) { + for (uint32_t index0=0; index0pBufferBinds[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 original_buffer = {}; + std::vector original_memory1 = {}; + std::vector original_image1 = {}; + std::vector original_memory2 = {}; + std::vector original_image2 = {}; + std::vector original_memory3 = {}; + std::vector original_pWaitSemaphores = {}; + std::vector original_pSignalSemaphores = {}; + if (pBindInfo) { + for (uint32_t index0=0; index0actualObject; + } + if (pBindInfo[index0].pBufferBinds[index1].pBinds) { + for (uint32_t index2=0; index2actualObject; + } + } + } + } + } + if (pBindInfo[index0].pImageOpaqueBinds) { + for (uint32_t index1=0; index1actualObject; + } + if (pBindInfo[index0].pImageOpaqueBinds[index1].pBinds) { + for (uint32_t index2=0; index2actualObject; + } + } + } + } + } + if (pBindInfo[index0].pImageBinds) { + for (uint32_t index1=0; index1actualObject; + } + if (pBindInfo[index0].pImageBinds[index1].pBinds) { + for (uint32_t index2=0; index2actualObject; + } + } + } + } + } + if (pBindInfo[index0].pWaitSemaphores) { + for (uint32_t index1=0; index1actualObject; + } + } + if (pBindInfo[index0].pSignalSemaphores) { + for (uint32_t index1=0; index1actualObject; + } + } + } + } + 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; index0stage[0]->module,VkShaderModule, pCreateInfos[createInfoCount]->layout,VkPipelineLayout, pCreateInfos[createInfoCount]->basePipelineHandle,VkPipeline + if (VK_NULL_HANDLE != pipelineCache) { + pipelineCache = (VkPipelineCache)((VkUniqueObject*)pipelineCache)->actualObject; + } + std::vector original_module = {}; + std::vector original_layout = {}; + std::vector original_basePipelineHandle = {}; + if (pCreateInfos) { + for (uint32_t index0=0; index0actualObject; + } + if (pCreateInfos[index0].layout) { + VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout); + original_layout.push_back(pCreateInfos[index0].layout); + *(pPipelineLayout) = (VkPipelineLayout)((VkUniqueObject*)pCreateInfos[index0].layout)->actualObject; + } + if (pCreateInfos[index0].basePipelineHandle) { + VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle); + original_basePipelineHandle.push_back(pCreateInfos[index0].basePipelineHandle); + *(pPipeline) = (VkPipeline)((VkUniqueObject*)pCreateInfos[index0].basePipelineHandle)->actualObject; + } + } + } + VkResult result = get_dispatch_table(unique_objects_device_table_map, device)->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); + if (pCreateInfos) { + for (uint32_t index0=0; index0 uniquePipelines = {}; + for (uint32_t i=0; iactualObject = (uint64_t)pPipelines[i]; + pPipelines[i] = (VkPipeline)uniquePipelines[i]; + } + } + return result; +} + +VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines) +{ +// UNWRAP USES: +// 0 : pipelineCache,VkPipelineCache, pCreateInfos[createInfoCount]->pStages[stageCount]->module,VkShaderModule, pCreateInfos[createInfoCount]->layout,VkPipelineLayout, pCreateInfos[createInfoCount]->renderPass,VkRenderPass, pCreateInfos[createInfoCount]->basePipelineHandle,VkPipeline + if (VK_NULL_HANDLE != pipelineCache) { + pipelineCache = (VkPipelineCache)((VkUniqueObject*)pipelineCache)->actualObject; + } + std::vector original_module = {}; + std::vector original_layout = {}; + std::vector original_renderPass = {}; + std::vector original_basePipelineHandle = {}; + if (pCreateInfos) { + for (uint32_t index0=0; index0actualObject; + } + } + } + if (pCreateInfos[index0].layout) { + VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout); + original_layout.push_back(pCreateInfos[index0].layout); + *(pPipelineLayout) = (VkPipelineLayout)((VkUniqueObject*)pCreateInfos[index0].layout)->actualObject; + } + if (pCreateInfos[index0].renderPass) { + VkRenderPass* pRenderPass = (VkRenderPass*)&(pCreateInfos[index0].renderPass); + original_renderPass.push_back(pCreateInfos[index0].renderPass); + *(pRenderPass) = (VkRenderPass)((VkUniqueObject*)pCreateInfos[index0].renderPass)->actualObject; + } + if (pCreateInfos[index0].basePipelineHandle) { + VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle); + original_basePipelineHandle.push_back(pCreateInfos[index0].basePipelineHandle); + *(pPipeline) = (VkPipeline)((VkUniqueObject*)pCreateInfos[index0].basePipelineHandle)->actualObject; + } + } + } + VkResult result = get_dispatch_table(unique_objects_device_table_map, device)->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); + if (pCreateInfos) { + for (uint32_t index0=0; index0 uniquePipelines = {}; + for (uint32_t i=0; iactualObject = (uint64_t)pPipelines[i]; + pPipelines[i] = (VkPipeline)uniquePipelines[i]; + } + } + return result; +} + +void explicit_UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies) +{ +// UNWRAP USES: +// 0 : pDescriptorWrites[descriptorWriteCount]->dstSet,VkDescriptorSet, pDescriptorWrites[descriptorWriteCount]->pImageInfo[descriptorCount]->sampler,VkSampler, pDescriptorWrites[descriptorWriteCount]->pImageInfo[descriptorCount]->imageView,VkImageView, pDescriptorWrites[descriptorWriteCount]->pBufferInfo[descriptorCount]->buffer,VkBuffer, pDescriptorCopies[descriptorCopyCount]->srcSet,VkDescriptorSet, pDescriptorCopies[descriptorCopyCount]->dstSet,VkDescriptorSet + std::vector original_dstSet1 = {}; + std::vector original_sampler = {}; + std::vector original_imageView = {}; + std::vector original_buffer = {}; + std::vector original_srcSet = {}; + std::vector original_dstSet2 = {}; +// descriptorCount : pDescriptorWrites[descriptorWriteCount]->pTexelBufferView,VkBufferView + std::vector original_pTexelBufferView = {}; + if (pDescriptorWrites) { + for (uint32_t index0=0; index0actualObject; + } + if (pDescriptorWrites[index0].pImageInfo) { + for (uint32_t index1=0; index1actualObject; + } + if (pDescriptorWrites[index0].pImageInfo[index1].imageView) { + VkImageView* pImageView = (VkImageView*)&(pDescriptorWrites[index0].pImageInfo[index1].imageView); + original_imageView.push_back(pDescriptorWrites[index0].pImageInfo[index1].imageView); + *(pImageView) = (VkImageView)((VkUniqueObject*)pDescriptorWrites[index0].pImageInfo[index1].imageView)->actualObject; + } + } + } + if (pDescriptorWrites[index0].pBufferInfo) { + for (uint32_t index1=0; index1actualObject; + } + } + } + if (pDescriptorWrites[index0].pTexelBufferView) { + for (uint32_t index1=0; index1actualObject; + } + } + } + } + if (pDescriptorCopies) { + for (uint32_t index0=0; index0actualObject; + } + if (pDescriptorCopies[index0].dstSet) { + VkDescriptorSet* pDescriptorSet = (VkDescriptorSet*)&(pDescriptorCopies[index0].dstSet); + original_dstSet2.push_back(pDescriptorCopies[index0].dstSet); + *(pDescriptorSet) = (VkDescriptorSet)((VkUniqueObject*)pDescriptorCopies[index0].dstSet)->actualObject; + } + } + } + get_dispatch_table(unique_objects_device_table_map, device)->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies); + if (pDescriptorWrites) { + for (uint32_t index0=0; index0actualObject; + } + 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 uniqueImages = {}; + 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]; + } + } + } + return result; +} -- cgit v1.2.3