--- /dev/null
+/*
+ *
+ * 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 <tobine@google.com>
+ */
+
+// CODEGEN : file vk-layer-generate.py line #1757
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "vulkan/vulkan.h"
+#include "vk_loader_platform.h"
+
+#include <vector>
+#include <unordered_map>
+
+#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<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 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<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;
+}
+
+VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
+{
+// UNWRAP USES:
+// 0 : pipelineCache,VkPipelineCache, pCreateInfos[createInfoCount]->stage[0]->module,VkShaderModule, pCreateInfos[createInfoCount]->layout,VkPipelineLayout, pCreateInfos[createInfoCount]->basePipelineHandle,VkPipeline
+ if (VK_NULL_HANDLE != pipelineCache) {
+ pipelineCache = (VkPipelineCache)((VkUniqueObject*)pipelineCache)->actualObject;
+ }
+ std::vector<VkShaderModule> original_module = {};
+ std::vector<VkPipelineLayout> original_layout = {};
+ std::vector<VkPipeline> original_basePipelineHandle = {};
+ if (pCreateInfos) {
+ for (uint32_t index0=0; index0<createInfoCount; ++index0) {
+ if (pCreateInfos[index0].stage.module) {
+ VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].stage.module);
+ original_module.push_back(pCreateInfos[index0].stage.module);
+ *(pShaderModule) = (VkShaderModule)((VkUniqueObject*)pCreateInfos[index0].stage.module)->actualObject;
+ }
+ 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<createInfoCount; ++index0) {
+ if (pCreateInfos[index0].stage.module) {
+ VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].stage.module);
+ *(pShaderModule) = original_module[index0];
+ }
+ if (pCreateInfos[index0].layout) {
+ VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout);
+ *(pPipelineLayout) = original_layout[index0];
+ }
+ if (pCreateInfos[index0].basePipelineHandle) {
+ VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle);
+ *(pPipeline) = original_basePipelineHandle[index0];
+ }
+ }
+ }
+ if (VK_SUCCESS == result) {
+ std::vector<VkUniqueObject*> uniquePipelines = {};
+ for (uint32_t i=0; i<createInfoCount; ++i) {
+ uniquePipelines.push_back(new VkUniqueObject());
+ uniquePipelines[i]->actualObject = (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<VkShaderModule> original_module = {};
+ std::vector<VkPipelineLayout> original_layout = {};
+ std::vector<VkRenderPass> original_renderPass = {};
+ std::vector<VkPipeline> original_basePipelineHandle = {};
+ if (pCreateInfos) {
+ for (uint32_t index0=0; index0<createInfoCount; ++index0) {
+ if (pCreateInfos[index0].pStages) {
+ for (uint32_t index1=0; index1<pCreateInfos[index0].stageCount; ++index1) {
+ if (pCreateInfos[index0].pStages[index1].module) {
+ VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].pStages[index1].module);
+ original_module.push_back(pCreateInfos[index0].pStages[index1].module);
+ *(pShaderModule) = (VkShaderModule)((VkUniqueObject*)pCreateInfos[index0].pStages[index1].module)->actualObject;
+ }
+ }
+ }
+ 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<createInfoCount; ++index0) {
+ if (pCreateInfos[index0].pStages) {
+ for (uint32_t index1=0; index1<pCreateInfos[index0].stageCount; ++index1) {
+ if (pCreateInfos[index0].pStages[index1].module) {
+ VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].pStages[index1].module);
+ *(pShaderModule) = original_module[index1];
+ }
+ }
+ }
+ if (pCreateInfos[index0].layout) {
+ VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout);
+ *(pPipelineLayout) = original_layout[index0];
+ }
+ if (pCreateInfos[index0].renderPass) {
+ VkRenderPass* pRenderPass = (VkRenderPass*)&(pCreateInfos[index0].renderPass);
+ *(pRenderPass) = original_renderPass[index0];
+ }
+ if (pCreateInfos[index0].basePipelineHandle) {
+ VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle);
+ *(pPipeline) = original_basePipelineHandle[index0];
+ }
+ }
+ }
+ if (VK_SUCCESS == result) {
+ std::vector<VkUniqueObject*> uniquePipelines = {};
+ for (uint32_t i=0; i<createInfoCount; ++i) {
+ uniquePipelines.push_back(new VkUniqueObject());
+ uniquePipelines[i]->actualObject = (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<VkDescriptorSet> original_dstSet1 = {};
+ std::vector<VkSampler> original_sampler = {};
+ std::vector<VkImageView> original_imageView = {};
+ std::vector<VkBuffer> original_buffer = {};
+ std::vector<VkDescriptorSet> original_srcSet = {};
+ std::vector<VkDescriptorSet> original_dstSet2 = {};
+// descriptorCount : pDescriptorWrites[descriptorWriteCount]->pTexelBufferView,VkBufferView
+ std::vector<VkBufferView> original_pTexelBufferView = {};
+ if (pDescriptorWrites) {
+ for (uint32_t index0=0; index0<descriptorWriteCount; ++index0) {
+ if (pDescriptorWrites[index0].dstSet) {
+ VkDescriptorSet* pDescriptorSet = (VkDescriptorSet*)&(pDescriptorWrites[index0].dstSet);
+ original_dstSet1.push_back(pDescriptorWrites[index0].dstSet);
+ *(pDescriptorSet) = (VkDescriptorSet)((VkUniqueObject*)pDescriptorWrites[index0].dstSet)->actualObject;
+ }
+ if (pDescriptorWrites[index0].pImageInfo) {
+ for (uint32_t index1=0; index1<pDescriptorWrites[index0].descriptorCount; ++index1) {
+ if (pDescriptorWrites[index0].pImageInfo[index1].sampler) {
+ VkSampler* pSampler = (VkSampler*)&(pDescriptorWrites[index0].pImageInfo[index1].sampler);
+ original_sampler.push_back(pDescriptorWrites[index0].pImageInfo[index1].sampler);
+ *(pSampler) = (VkSampler)((VkUniqueObject*)pDescriptorWrites[index0].pImageInfo[index1].sampler)->actualObject;
+ }
+ 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; index1<pDescriptorWrites[index0].descriptorCount; ++index1) {
+ if (pDescriptorWrites[index0].pBufferInfo[index1].buffer) {
+ VkBuffer* pBuffer = (VkBuffer*)&(pDescriptorWrites[index0].pBufferInfo[index1].buffer);
+ original_buffer.push_back(pDescriptorWrites[index0].pBufferInfo[index1].buffer);
+ *(pBuffer) = (VkBuffer)((VkUniqueObject*)pDescriptorWrites[index0].pBufferInfo[index1].buffer)->actualObject;
+ }
+ }
+ }
+ if (pDescriptorWrites[index0].pTexelBufferView) {
+ for (uint32_t index1=0; index1<pDescriptorWrites[index0].descriptorCount; ++index1) {
+ VkBufferView** ppBufferView = (VkBufferView**)&(pDescriptorWrites[index0].pTexelBufferView);
+ original_pTexelBufferView.push_back(pDescriptorWrites[index0].pTexelBufferView[index1]);
+ *(ppBufferView[index1]) = (VkBufferView)((VkUniqueObject*)pDescriptorWrites[index0].pTexelBufferView[index1])->actualObject;
+ }
+ }
+ }
+ }
+ if (pDescriptorCopies) {
+ for (uint32_t index0=0; index0<descriptorCopyCount; ++index0) {
+ if (pDescriptorCopies[index0].srcSet) {
+ VkDescriptorSet* pDescriptorSet = (VkDescriptorSet*)&(pDescriptorCopies[index0].srcSet);
+ original_srcSet.push_back(pDescriptorCopies[index0].srcSet);
+ *(pDescriptorSet) = (VkDescriptorSet)((VkUniqueObject*)pDescriptorCopies[index0].srcSet)->actualObject;
+ }
+ 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; index0<descriptorWriteCount; ++index0) {
+ if (pDescriptorWrites[index0].dstSet) {
+ VkDescriptorSet* pDescriptorSet = (VkDescriptorSet*)&(pDescriptorWrites[index0].dstSet);
+ *(pDescriptorSet) = original_dstSet1[index0];
+ }
+ if (pDescriptorWrites[index0].pImageInfo) {
+ for (uint32_t index1=0; index1<pDescriptorWrites[index0].descriptorCount; ++index1) {
+ if (pDescriptorWrites[index0].pImageInfo[index1].sampler) {
+ VkSampler* pSampler = (VkSampler*)&(pDescriptorWrites[index0].pImageInfo[index1].sampler);
+ *(pSampler) = original_sampler[index1];
+ }
+ if (pDescriptorWrites[index0].pImageInfo[index1].imageView) {
+ VkImageView* pImageView = (VkImageView*)&(pDescriptorWrites[index0].pImageInfo[index1].imageView);
+ *(pImageView) = original_imageView[index1];
+ }
+ }
+ }
+ if (pDescriptorWrites[index0].pBufferInfo) {
+ for (uint32_t index1=0; index1<pDescriptorWrites[index0].descriptorCount; ++index1) {
+ if (pDescriptorWrites[index0].pBufferInfo[index1].buffer) {
+ VkBuffer* pBuffer = (VkBuffer*)&(pDescriptorWrites[index0].pBufferInfo[index1].buffer);
+ *(pBuffer) = original_buffer[index1];
+ }
+ }
+ }
+ if (pDescriptorWrites[index0].pTexelBufferView) {
+ for (uint32_t index1=0; index1<pDescriptorWrites[index0].descriptorCount; ++index1) {
+ VkBufferView** ppBufferView = (VkBufferView**)&(pDescriptorWrites[index0].pTexelBufferView);
+ *(ppBufferView[index1]) = original_pTexelBufferView[index1];
+ }
+ }
+ }
+ }
+ if (pDescriptorCopies) {
+ for (uint32_t index0=0; index0<descriptorCopyCount; ++index0) {
+ if (pDescriptorCopies[index0].srcSet) {
+ VkDescriptorSet* pDescriptorSet = (VkDescriptorSet*)&(pDescriptorCopies[index0].srcSet);
+ *(pDescriptorSet) = original_srcSet[index0];
+ }
+ if (pDescriptorCopies[index0].dstSet) {
+ VkDescriptorSet* pDescriptorSet = (VkDescriptorSet*)&(pDescriptorCopies[index0].dstSet);
+ *(pDescriptorSet) = original_dstSet2[index0];
+ }
+ }
+ }
+}
+
+VkResult explicit_GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages)
+{
+// UNWRAP USES:
+// 0 : swapchain,VkSwapchainKHR, pSwapchainImages,VkImage
+ if (VK_NULL_HANDLE != swapchain) {
+ swapchain = (VkSwapchainKHR)((VkUniqueObject*)swapchain)->actualObject;
+ }
+ 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 = {};
+ 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;
+}
# VK
#
# Copyright (C) 2015 Valve Corporation
-# Copyright (C) 2015 Google Inc.
+# 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"),
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
-# Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+# Author: Tobin Ehlis <tobine@google.com>
+# Author: Courtney Goeltzenleuchter <courtneygo@google.com>
# Author: Jon Ashburn <jon@lunarg.com>
# Author: Mark Lobodzinski <mark@lunarg.com>
-# Author: Mike Stroyan <mike@LunarG.com>
+# Author: Mike Stroyan <stroyan@google.com>
# Author: Tony Barbour <tony@LunarG.com>
-# Author: Chia-I Wu <olv@lunarg.com>
+# Author: Chia-I Wu <olv@google.com>
import sys
import os
/*
*
* Copyright (C) 2015 Valve Corporation
+ * 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"),
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Tobin Ehlis <tobine@google.com>
+ * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
* Author: Jon Ashburn <jon@lunarg.com>
* Author: Mark Lobodzinski <mark@lunarg.com>
- * Author: Mike Stroyan <mike@LunarG.com>
+ * Author: Mike Stroyan <stroyan@google.com>
* Author: Tony Barbour <tony@LunarG.com>
*/"""
r_body.append(' VkDebugReportCallbackEXT* pCallback)')
r_body.append('{')
# Switch to this code section for the new per-instance storage and debug callbacks
- if self.layer_name == 'object_tracker' or self.layer_name == 'threading':
+ if self.layer_name in ['object_tracker', 'threading', 'unique_objects']:
r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
r_body.append(' VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
r_body.append(' if (VK_SUCCESS == result) {')
r_body.append('VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)')
r_body.append('{')
# Switch to this code section for the new per-instance storage and debug callbacks
- if self.layer_name == 'object_tracker' or self.layer_name == 'threading':
+ if self.layer_name in ['object_tracker', 'threading', 'unique_objects']:
r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
else:
r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
#
# New style of GPA Functions for the new layer_data/layer_logging changes
#
- if self.layer_name == 'object_tracker' or self.layer_name == 'threading':
+ if self.layer_name in ['object_tracker', 'threading', 'unique_objects']:
func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
"{\n"
" PFN_vkVoidFunction addr;\n"
'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
'vkGetPhysicalDeviceSurfaceFormatsKHR',
'vkGetPhysicalDeviceSurfacePresentModesKHR'])]
- extensions=[('wsi_enabled',
+ extensions=[('wsi_enabled',
['vkCreateSwapchainKHR',
'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0, reinterpret_cast<uint64_t>(object), __LINE__, OBJTRACK_INVALID_OBJECT, "OBJTRACK",')
procs_txt.append(' "Invalid %s Object 0x%%" PRIx64 ,reinterpret_cast<uint64_t>(object));' % o)
else:
+ if o == "VkPipelineCache":
+ procs_txt.append(' // VkPipelineCache object can be NULL if not caching')
+ procs_txt.append(' if (object == VK_NULL_HANDLE) return VK_TRUE;')
+ procs_txt.append('')
if o == "VkImage":
procs_txt.append(' // We need to validate normal image objects and those from the swapchain')
procs_txt.append(' if ((%sMap.find((uint64_t)object) == %sMap.end()) &&' % (o, o))
create_line = ''
destroy_line = ''
# Dict below tracks params that are vk objects. Dict is "loop count"->["params w/ that loop count"] where '0' is params that aren't in an array
+ # TODO : Should integrate slightly better code for this purpose from unique_objects layer
loop_params = defaultdict(list) # Dict uses loop count as key to make final code generation cleaner so params shared in single loop where needed
loop_types = defaultdict(list)
# TODO : For now skipping objs that can be NULL. Really should check these and have special case that allows them to be NULL
using_line += ' if (fence != VK_NULL_HANDLE) {\n'
using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
using_line += ' }\n'
- elif ('CreateGraphicsPipelines' in proto.name or 'CreateComputePipelines' in proto.name) and 'pipelineCache' == opn:
- using_line += ' // PipelineCache is optional, validate if present\n'
- using_line += ' if (pipelineCache != VK_NULL_HANDLE) {\n'
- using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
- using_line += ' }\n'
else:
using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
else:
instance_extensions)]
return "\n\n".join(body)
+class UniqueObjectsSubcommand(Subcommand):
+ def generate_header(self):
+ header_txt = []
+ header_txt.append('%s' % self.lineinfo.get())
+ header_txt.append('#include "unique_objects.h"')
+ header_txt.append('')
+ header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
+ return "\n".join(header_txt)
+
+ # Parse complete struct chain and add any new ndo_uses to the dict
+ def _gather_struct_ndos(self, name_prefix, struct_type, ndo_uses):
+ if vk_helper.typedef_rev_dict[struct_type] in vk_helper.struct_dict:
+ struct_type = vk_helper.typedef_rev_dict[struct_type]
+ # Parse elements of this struct param to identify objects and/or arrays of objects
+ for m in sorted(vk_helper.struct_dict[struct_type]):
+ array_len = "%s" % (str(vk_helper.struct_dict[struct_type][m]['array_size']))
+ base_type = vk_helper.struct_dict[struct_type][m]['type']
+ struct_name = vk_helper.struct_dict[struct_type][m]['name']
+ if base_type in vulkan.object_non_dispatch_list:
+ if array_len not in ndo_uses:
+ ndo_uses[array_len] = []
+ ndo_uses[array_len].append("%s%s,%s" % (name_prefix, struct_name, base_type))
+ elif vk_helper.is_type(base_type, 'struct'):
+ ndo_uses = self._gather_struct_ndos("%s%s[%s]->" % (name_prefix, struct_name, array_len), base_type, ndo_uses)
+ return ndo_uses
+
+ # Parse the given list of params and return true if any ndos
+ # TODO : This analysis could be done up-front at vk_helper time
+ def _get_ndo_uses(self, params):
+ ndo_uses = {}
+ param_count = 'NONE' # track params that give array sizes
+ for p in params:
+ base_type = p.ty.replace('const ', '').strip('*')
+ array_len = '0'
+ is_ptr = False
+ if 'count' in p.name.lower():
+ param_count = p.name
+ if '*' in p.ty:
+ is_ptr = True
+ if base_type in vulkan.object_non_dispatch_list:
+ if is_ptr and 'const' in p.ty and param_count != 'NONE':
+ array_len = param_count
+ if array_len not in ndo_uses:
+ ndo_uses[array_len] = []
+ ndo_uses[array_len].append("%s,%s" % (p.name, base_type))
+ elif vk_helper.is_type(base_type, 'struct'):
+ struct_name = p.name
+ if 'NONE' != param_count:
+ struct_name = "%s[%s]" % (struct_name, param_count)
+ ndo_uses = self._gather_struct_ndos("%s->" % struct_name, base_type, ndo_uses)
+ return ndo_uses
+
+ def generate_intercept(self, proto, qual):
+ create_func = False
+ destroy_func = False
+ last_param_index = None #typcially we look at all params for ndos
+ pre_call_txt = '' # code prior to calling down chain such as unwrap uses of ndos
+ post_call_txt = '' # code following call down chain such to wrap newly created ndos, or destroy local wrap struct
+ funcs = []
+ indent = ' ' # indent level for generated code
+ decl = proto.c_func(prefix="vk", attr="VKAPI")
+ # TODO : A few API cases that will be manual code initially, could potentially move
+ # them to generated code
+ # Also, here's generated functions that could be improved: vkAllocateDescriptorSets, vkCmdBeginRenderPass
+ explicit_object_tracker_functions = ['QueueSubmit',
+ 'QueueBindSparse',
+ 'CreateComputePipelines',
+ 'CreateGraphicsPipelines',
+ 'UpdateDescriptorSets',
+ 'GetSwapchainImagesKHR',
+ 'CreateInstance',
+ 'CreateDevice',]
+ # Give special treatment to create functions that return multiple new objects
+ # This dict stores array name and size of array
+ custom_create_dict = {'pDescriptorSets' : 'pAllocateInfo->setLayoutCount'}
+ if proto.name in explicit_object_tracker_functions:
+ funcs.append('%s%s\n'
+ '{\n'
+ ' return explicit_%s;\n'
+ '}' % (qual, decl, proto.c_call()))
+ return "".join(funcs)
+ if True in [create_txt in proto.name for create_txt in ['Create', 'Allocate']]:
+ create_func = True
+ last_param_index = -1 # For create funcs don't care if last param is ndo
+ if True in [destroy_txt in proto.name for destroy_txt in ['Destroy', 'Free']]:
+ destroy_obj_type = proto.params[-2].ty
+ if destroy_obj_type in vulkan.object_non_dispatch_list:
+ destroy_func = True
+
+ # First thing we need to do is update any uses for non-dispatchable-objects (ndos)
+ ndo_uses = self._get_ndo_uses(proto.params[1:last_param_index])
+ if len(ndo_uses) > 0:
+ pre_call_txt = '// UNWRAP USES:\n'
+ for ndo in ndo_uses:
+ pre_call_txt += '// %s : %s\n' % (ndo, ', '.join(ndo_uses[ndo]))
+ for member in ndo_uses[ndo]:
+ # pairs of (m)ember (n)ames and (t)ypes
+ mnt_array = member.split(',')
+ has_ptr = False
+ pname = mnt_array[0]
+ if '->' in pname:
+ has_ptr = True
+ pname = mnt_array[0].split('->')[-1]
+ if not has_ptr and '0' == ndo:
+ if destroy_func:
+ pre_call_txt += '%s%s local_%s = %s;\n' % (indent, mnt_array[1], pname, pname)
+ pre_call_txt += '%s\n' % (self.lineinfo.get())
+ pre_call_txt += '%sif (VK_NULL_HANDLE != %s) {\n' % (indent, mnt_array[0])
+ indent += ' '
+ pre_call_txt += '%s%s = (%s)((VkUniqueObject*)%s)->actualObject;\n' % (indent, pname, mnt_array[1], pname)
+ indent = indent [4:]
+ pre_call_txt += '%s}\n' % (indent)
+ else: # ptr and/or loop case
+ name_hier = mnt_array[0].split('->')
+ last_seg = False # is this last seg of the name?
+ prev_seg = ''
+ loop_indicies = ['0'] # track all the loop indices
+ loop_idx_num = 0
+ loop_count = '' # Upper limit of current loop
+ orig_indent = indent # store this so we can close out blocks at the end
+ # Declare vector of ndos in order to restore them after call
+ pre_call_txt += '%s\n' % (self.lineinfo.get())
+ pre_call_txt += '%sstd::vector<%s> original_%s = {};\n' % (indent, mnt_array[1], name_hier[-1])
+ for seg in name_hier:
+ array = False
+ if seg == name_hier[-1]:
+ last_seg = True
+ if '[' in seg or (last_seg and '0' != ndo): # array access, so store off array counter and update name
+ array = True
+ loop_indicies.append('index%s' % str(loop_idx_num))
+ loop_idx_num += 1
+ if '[' in seg: # explicit array case is not ndo
+ (seg, loop_count) = seg.split('[')
+ loop_count = loop_count.strip(']')
+ else: # ndo case the loop_count is key
+ loop_count = ndo
+ pre_call_txt += '%sif (%s%s) {\n' % (indent, prev_seg, seg)
+ # We replicate the ndo update code after the call to restore original handle
+ post_call_txt += '%sif (%s%s) {\n' % (indent, prev_seg, seg)
+ indent += ' '
+ if array:
+ pre_call_txt += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, loop_indicies[-1], loop_indicies[-1], prev_seg, loop_count, loop_indicies[-1])
+ post_call_txt += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, loop_indicies[-1], loop_indicies[-1], prev_seg, loop_count, loop_indicies[-1])
+ indent += ' '
+ if last_seg:
+ p_name = 'p%s' % mnt_array[1][2:] # Used to allow overwriting of ndo object in const ptr chain
+ # TODO - need type of element ABOVE NDO in this case, this is BROKEN right now
+ ndo_ref_name = prev_seg.strip('->').strip('.')
+ ndo_name = '%s%s' % (prev_seg, seg)
+ if array:
+ ndo_ref_name = '%s%s' % (prev_seg, seg)
+ ndo_name = '%s[%s]' % (ndo_ref_name, loop_indicies[-1])
+ pre_call_txt += '%s%s* %s = (%s*)&(%s);\n' % (indent, mnt_array[1], p_name, mnt_array[1], ndo_name)
+ post_call_txt += '%s%s* %s = (%s*)&(%s);\n' % (indent, mnt_array[1], p_name, mnt_array[1], ndo_name)
+ # Save off this object to restore it after the call
+ pre_call_txt += '%soriginal_%s.push_back(%s);\n' % (indent, seg, ndo_name)
+ pre_call_txt += '%s*(%s) = (%s)((VkUniqueObject*)%s)->actualObject;\n' % (indent, p_name, mnt_array[1], ndo_name)
+ post_call_txt += '%s*(%s) = original_%s[%s];\n' % (indent, p_name, seg, loop_indicies[-1])
+ indent = indent[4:]
+ # Update prev segment to be used in next loop iteration
+ if not array:
+ prev_seg = '%s%s->' % (prev_seg, seg)
+ else:
+ prev_seg = '%s%s[%s].' % (prev_seg, seg, loop_indicies[-1])
+ if indent != orig_indent:
+ while indent != ' ': # close previous code blocks
+ pre_call_txt += '%s}\n' % (indent)
+ post_call_txt += '%s}\n' % (indent)
+ indent = indent[4:]
+ pre_call_txt += '%s}\n' % (indent)
+ post_call_txt += '%s}\n' % (indent)
+ elif create_func:
+ base_type = proto.params[-1].ty.replace('const ', '').strip('*')
+ if base_type not in vulkan.object_non_dispatch_list:
+ return None
+ else:
+ return None
+
+ ret_val = ''
+ ret_stmt = ''
+ 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
+ if obj_type in vulkan.object_non_dispatch_list:
+ local_name = "unique%s" % obj_type[2:]
+ post_call_txt += '%sif (VK_SUCCESS == result) {\n' % (indent)
+ 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)
+ 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)
+ indent = indent[4:]
+ post_call_txt += '%s}\n' % (indent)
+ elif destroy_func:
+ del_obj = proto.params[-2].name
+ if 'count' in del_obj.lower():
+ post_call_txt += '%s\n' % (self.lineinfo.get())
+ post_call_txt += '%sfor (uint32_t i=0; i<%s; ++i) {\n' % (indent, del_obj)
+ del_obj = proto.params[-1].name
+ indent += ' '
+ post_call_txt += '%sdelete (VkUniqueObject*)%s[i];\n' % (indent, del_obj)
+ indent = indent[4:]
+ 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)
+
+ call_sig = proto.c_call()
+ if proto_is_global(proto):
+ table_type = "instance"
+ else:
+ table_type = "device"
+ pre_call_txt += '%s\n' % (self.lineinfo.get())
+ funcs.append('%s%s\n'
+ '{\n'
+ '%s'
+ ' %sget_dispatch_table(unique_objects_%s_table_map, %s)->%s;\n'
+ '%s'
+ '%s'
+ '}' % (qual, decl, pre_call_txt, ret_val, table_type, dispatch_param, call_sig, post_call_txt, ret_stmt))
+ return "\n\n".join(funcs)
+
+ def generate_body(self):
+ self.layer_name = "unique_objects"
+ extensions=[('wsi_enabled',
+ ['vkCreateSwapchainKHR',
+ 'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
+ 'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
+ if sys.platform.startswith('win32'):
+ instance_extensions=[('wsi_enabled',
+ ['vkGetPhysicalDeviceSurfaceSupportKHR',
+ 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
+ 'vkGetPhysicalDeviceSurfaceFormatsKHR',
+ 'vkGetPhysicalDeviceSurfacePresentModesKHR',
+ 'vkCreateWin32SurfaceKHR',
+ 'vkGetPhysicalDeviceWin32PresentationSupportKHR'])]
+ elif sys.platform.startswith('linux'):
+ instance_extensions=[('wsi_enabled',
+ ['vkGetPhysicalDeviceSurfaceSupportKHR',
+ 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
+ 'vkGetPhysicalDeviceSurfaceFormatsKHR',
+ 'vkGetPhysicalDeviceSurfacePresentModesKHR',
+ 'vkCreateXcbSurfaceKHR',
+ 'vkGetPhysicalDeviceXcbPresentationSupportKHR'])]
+ # TODO: Add cases for Mir, Wayland and Xlib
+ else: # android
+ instance_extensions=[('wsi_enabled',
+ ['vkGetPhysicalDeviceSurfaceSupportKHR',
+ 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
+ 'vkGetPhysicalDeviceSurfaceFormatsKHR',
+ 'vkGetPhysicalDeviceSurfacePresentModesKHR'])]
+ body = [self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
+ self._generate_layer_gpa_function(extensions,
+ instance_extensions)]
+ return "\n\n".join(body)
+
class ThreadingSubcommand(Subcommand):
thread_check_dispatchable_objects = [
"VkQueue",
"api_dump" : APIDumpSubcommand,
"object_tracker" : ObjectTrackerSubcommand,
"threading" : ThreadingSubcommand,
+ "unique_objects" : UniqueObjectsSubcommand,
}
if len(sys.argv) < 3 or sys.argv[1] not in subcommands or not os.path.exists(sys.argv[2]):