| /* |
| * Vulkan |
| * |
| * Copyright (C) 2014 LunarG, 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. |
| * |
| */ |
| |
| #include <string.h> |
| #include <stdlib.h> |
| #include <assert.h> |
| #include <unordered_map> |
| #include "vk_loader_platform.h" |
| #include "vk_layer.h" |
| #include "vk_layer_table.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| |
| static device_table_map multi1_device_table_map; |
| /******************************** Layer multi1 functions **************************/ |
| |
| /* hook DestroyDevice to remove tableMap entry */ |
| VK_LAYER_EXPORT void VKAPI multi1DestroyDevice(VkDevice device) |
| { |
| VkLayerDispatchTable *pDisp = get_dispatch_table(multi1_device_table_map, device); |
| dispatch_key key = get_dispatch_key(device); |
| |
| printf("At start of multi1 layer vkDestroyDevice()\n"); |
| pDisp->DestroyDevice(device); |
| multi1_device_table_map.erase(key); |
| printf("Completed multi1 layer vkDestroyDevice()\n"); |
| } |
| |
| VK_LAYER_EXPORT VkResult VKAPI multi1CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler) |
| { |
| VkLayerDispatchTable *pDisp = get_dispatch_table(multi1_device_table_map, device); |
| |
| printf("At start of multi1 layer vkCreateSampler()\n"); |
| VkResult result = pDisp->CreateSampler(device, pCreateInfo, pSampler); |
| printf("Completed multi1 layer vkCreateSampler()\n"); |
| return result; |
| } |
| |
| VK_LAYER_EXPORT VkResult VKAPI multi1CreateGraphicsPipelines( |
| VkDevice device, |
| VkPipelineCache pipelineCache, |
| uint32_t count, |
| const VkGraphicsPipelineCreateInfo* pCreateInfos, |
| VkPipeline* pPipelines) |
| { |
| VkLayerDispatchTable *pDisp = get_dispatch_table(multi1_device_table_map, device); |
| |
| printf("At start of multi1 layer vkCreateGraphicsPipeline()\n"); |
| VkResult result = pDisp->CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pPipelines); |
| printf("Completed multi1 layer vkCreateGraphicsPipeline()\n"); |
| return result; |
| } |
| |
| VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI multi1GetDeviceProcAddr(VkDevice device, const char* pName) |
| { |
| |
| if (device == NULL) |
| return NULL; |
| |
| /* loader uses this to force layer initialization; device object is wrapped */ |
| if (!strcmp(pName, "multi1GetDeviceProcAddr") || !strcmp(pName, "vkGetDeviceProcAddr")) { |
| initDeviceTable(multi1_device_table_map, (const VkBaseLayerObject *) device); |
| return (PFN_vkVoidFunction) multi1GetDeviceProcAddr; |
| } |
| |
| if (!strcmp("vkDestroyDevice", pName)) |
| return (PFN_vkVoidFunction) multi1DestroyDevice; |
| if (!strcmp("vkCreateSampler", pName)) |
| return (PFN_vkVoidFunction) multi1CreateSampler; |
| if (!strcmp("vkCreateGraphicsPipelines", pName)) |
| return (PFN_vkVoidFunction) multi1CreateGraphicsPipelines; |
| else { |
| VkLayerDispatchTable *pTable = get_dispatch_table(multi1_device_table_map, device); |
| if (pTable->GetDeviceProcAddr == NULL) |
| return NULL; |
| return pTable->GetDeviceProcAddr(device, pName); |
| } |
| } |
| |
| |
| static instance_table_map multi2_instance_table_map; |
| /******************************** Layer multi2 functions **************************/ |
| VK_LAYER_EXPORT VkResult VKAPI multi2EnumeratePhysicalDevices( |
| VkInstance instance, |
| uint32_t* pPhysicalDeviceCount, |
| VkPhysicalDevice* pPhysicalDevices) |
| { |
| VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(multi2_instance_table_map, instance); |
| |
| printf("At start of wrapped multi2 vkEnumeratePhysicalDevices()\n"); |
| VkResult result = pDisp->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); |
| printf("Completed multi2 layer vkEnumeratePhysicalDevices()\n"); |
| return result; |
| } |
| |
| VK_LAYER_EXPORT void VKAPI multi2GetPhysicalDeviceProperties( |
| VkPhysicalDevice physicalDevice, |
| VkPhysicalDeviceProperties* pProperties) |
| { |
| VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(multi2_instance_table_map, physicalDevice); |
| printf("At start of wrapped multi2 vkGetPhysicalDeviceProperties()\n"); |
| pDisp->GetPhysicalDeviceProperties(physicalDevice, pProperties); |
| printf("Completed multi2 layer vkGetPhysicalDeviceProperties()\n"); |
| } |
| |
| VK_LAYER_EXPORT void VKAPI multi2GetPhysicalDeviceFeatures( |
| VkPhysicalDevice physicalDevice, |
| VkPhysicalDeviceFeatures* pFeatures) |
| { |
| VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(multi2_instance_table_map, physicalDevice); |
| printf("At start of wrapped multi2 vkGetPhysicalDeviceFeatures()\n"); |
| pDisp->GetPhysicalDeviceFeatures(physicalDevice, pFeatures); |
| printf("Completed multi2 layer vkGetPhysicalDeviceFeatures()\n"); |
| } |
| |
| /* hook DestroyInstance to remove tableInstanceMap entry */ |
| VK_LAYER_EXPORT void VKAPI multi2DestroyInstance(VkInstance instance) |
| { |
| VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(multi2_instance_table_map, instance); |
| dispatch_key key = get_dispatch_key(instance); |
| |
| printf("At start of wrapped multi2 vkDestroyInstance()\n"); |
| pDisp->DestroyInstance(instance); |
| multi2_instance_table_map.erase(key); |
| printf("Completed multi2 layer vkDestroyInstance()\n"); |
| } |
| |
| VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI multi2GetInstanceProcAddr(VkInstance inst, const char* pName) |
| { |
| if (inst == NULL) |
| return NULL; |
| |
| /* loader uses this to force layer initialization; device object is wrapped */ |
| if (!strcmp(pName, "multi2GetInstanceProcAddr") || !strcmp(pName, "vkGetInstanceProcAddr")) { |
| initInstanceTable(multi2_instance_table_map, (const VkBaseLayerObject *) inst); |
| return (PFN_vkVoidFunction) multi2GetInstanceProcAddr; |
| } |
| |
| if (!strcmp("vkEnumeratePhysicalDevices", pName)) |
| return (PFN_vkVoidFunction) multi2EnumeratePhysicalDevices; |
| if (!strcmp("GetPhysicalDeviceProperties", pName)) |
| return (PFN_vkVoidFunction) multi2GetPhysicalDeviceProperties; |
| if (!strcmp("GetPhysicalDeviceFeatures", pName)) |
| return (PFN_vkVoidFunction) multi2GetPhysicalDeviceFeatures; |
| if (!strcmp("vkDestroyInstance", pName)) |
| return (PFN_vkVoidFunction) multi2DestroyInstance; |
| else { |
| VkLayerInstanceDispatchTable *pTable = get_dispatch_table(multi2_instance_table_map, inst); |
| if (pTable->GetInstanceProcAddr == NULL) |
| return NULL; |
| return pTable->GetInstanceProcAddr(inst, pName); |
| } |
| } |
| |
| #ifdef __cplusplus |
| } //extern "C" |
| #endif |
| |