diff options
| -rw-r--r-- | include/vulkan/vk_layer.h | 46 | ||||
| -rw-r--r-- | layers/api_dump.h | 31 | ||||
| -rw-r--r-- | layers/basic.cpp | 94 | ||||
| -rw-r--r-- | layers/device_limits.cpp | 115 | ||||
| -rw-r--r-- | layers/draw_state.cpp | 126 | ||||
| -rw-r--r-- | layers/image.cpp | 123 | ||||
| -rw-r--r-- | layers/mem_tracker.cpp | 124 | ||||
| -rw-r--r-- | layers/multi.cpp | 47 | ||||
| -rw-r--r-- | layers/object_tracker.h | 79 | ||||
| -rw-r--r-- | layers/param_checker.cpp | 109 | ||||
| -rw-r--r-- | layers/screenshot.cpp | 69 | ||||
| -rw-r--r-- | layers/swapchain.cpp | 179 | ||||
| -rw-r--r-- | layers/unique_objects.h | 48 | ||||
| -rw-r--r-- | layers/vk_layer_table.cpp | 59 | ||||
| -rw-r--r-- | layers/vk_layer_table.h | 13 | ||||
| -rw-r--r-- | loader/loader.c | 481 | ||||
| -rw-r--r-- | loader/loader.h | 14 | ||||
| -rw-r--r-- | loader/table_ops.h | 27 | ||||
| -rw-r--r-- | loader/trampoline.c | 14 | ||||
| -rwxr-xr-x | vk-generate.py | 31 | ||||
| -rwxr-xr-x | vk-layer-generate.py | 213 |
21 files changed, 1232 insertions, 810 deletions
diff --git a/include/vulkan/vk_layer.h b/include/vulkan/vk_layer.h index 68991824..da19dddb 100644 --- a/include/vulkan/vk_layer.h +++ b/include/vulkan/vk_layer.h @@ -26,7 +26,6 @@ typedef struct VkBaseLayerObject_ typedef struct VkLayerDispatchTable_ { PFN_vkGetDeviceProcAddr GetDeviceProcAddr; - PFN_vkCreateDevice CreateDevice; PFN_vkDestroyDevice DestroyDevice; PFN_vkGetDeviceQueue GetDeviceQueue; PFN_vkQueueSubmit QueueSubmit; @@ -159,6 +158,7 @@ typedef struct VkLayerInstanceDispatchTable_ PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkCreateInstance CreateInstance; PFN_vkDestroyInstance DestroyInstance; + PFN_vkCreateDevice CreateDevice; PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures; PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties; @@ -223,15 +223,51 @@ typedef enum VkLayerDbgAction_ // ------------------------------------------------------------------------------------------------ // CreateInstance and CreateDevice support structures + +typedef enum VkLayerFunction_ +{ + VK_LAYER_LINK_INFO = 0, + VK_LAYER_DEVICE_INFO = 1, + VK_LAYER_INSTANCE_INFO = 2 +} VkLayerFunction; + +/* + * When creating the device chain the loader needs to pass + * down information about it's device structure needed at + * the end of the chain. Passing the data via the + * VkLayerDeviceInfo avoids issues with finding the + * exact instance being used. + */ +typedef struct VkLayerInstanceInfo_ { + void *instance_info; + PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; +} VkLayerInstanceInfo; + typedef struct VkLayerInstanceLink_ { struct VkLayerInstanceLink_* pNext; PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; } VkLayerInstanceLink; +/* + * When creating the device chain the loader needs to pass + * down information about it's device structure needed at + * the end of the chain. Passing the data via the + * VkLayerDeviceInfo avoids issues with finding the + * exact instance being used. + */ +typedef struct VkLayerDeviceInfo_ { + void *device_info; + PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr; +} VkLayerDeviceInfo; + typedef struct { VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_INSTANCE_CREATE_INFO const void* pNext; - VkLayerInstanceLink* pLayerInfo; + VkLayerFunction function; + union { + VkLayerInstanceLink* pLayerInfo; + VkLayerInstanceInfo instanceInfo; + } u; } VkLayerInstanceCreateInfo; typedef struct VkLayerDeviceLink_ { @@ -243,7 +279,11 @@ typedef struct VkLayerDeviceLink_ { typedef struct { VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_DEVICE_CREATE_INFO const void* pNext; - VkLayerDeviceLink* pLayerInfo; + VkLayerFunction function; + union { + VkLayerDeviceLink* pLayerInfo; + VkLayerDeviceInfo deviceInfo; + } u; } VkLayerDeviceCreateInfo; // ------------------------------------------------------------------------------------------------ diff --git a/layers/api_dump.h b/layers/api_dump.h index 3dc8e2f1..73c6a491 100644 --- a/layers/api_dump.h +++ b/layers/api_dump.h @@ -125,3 +125,34 @@ static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreate } } +VkResult +explicit_CreateDevice( + VkPhysicalDevice gpu, + const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDevice *pDevice) +{ + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; + } + + initDeviceTable(*pDevice, fpGetDeviceProcAddr); + + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + + return result; +} diff --git a/layers/basic.cpp b/layers/basic.cpp index 77b08c05..45cb9998 100644 --- a/layers/basic.cpp +++ b/layers/basic.cpp @@ -95,6 +95,32 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionPropert } } +VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_CreateInstance( + const VkInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance) +{ + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) + return result; + + initInstanceTable(*pInstance, fpGetInstanceProcAddr); + + return result; +} + VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_EnumeratePhysicalDevices( VkInstance instance, uint32_t* pPhysicalDeviceCount, @@ -106,11 +132,31 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_EnumeratePhysicalDevices( return result; } -VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) +VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { - printf("At start of wrapped vkCreateDevice() call w/ gpu: %p\n", (void*)gpu); - VkResult result = device_dispatch_table(*pDevice)->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice); - printf("Completed wrapped vkCreateDevice() call w/ pDevice, Device %p: %p\n", (void*)pDevice, (void *) *pDevice); + printf("VK_LAYER_LUNARG_Basic: At start of vkCreateDevice() call w/ gpu: %p\n", (void*)physicalDevice); + + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; + } + + initDeviceTable(*pDevice, fpGetDeviceProcAddr); + + printf("VK_LAYER_LUNARG_Basic: Completed vkCreateDevice() call w/ pDevice, Device %p: %p\n", (void*)pDevice, (void *) *pDevice); return result; } @@ -139,51 +185,43 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL basic_GetPhysicalDeviceFormatProperti VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName) { - if (device == NULL) - return NULL; - - /* loader uses this to force layer initialization; device object is wrapped */ - if (!strcmp("vkGetDeviceProcAddr", pName)) { - initDeviceTable((const VkBaseLayerObject *) device); + if (!strcmp("vkGetDeviceProcAddr", pName)) return (PFN_vkVoidFunction) vkGetDeviceProcAddr; - } - - if (!strcmp("vkCreateDevice", pName)) - return (PFN_vkVoidFunction) basic_CreateDevice; if (!strcmp("vkDestroyDevice", pName)) return (PFN_vkVoidFunction) basic_DestroyDevice; if (!strcmp("vkLayerExtension1", pName)) return (PFN_vkVoidFunction) vkLayerExtension1; - else - { - if (device_dispatch_table(device)->GetDeviceProcAddr == NULL) - return NULL; - return device_dispatch_table(device)->GetDeviceProcAddr(device, pName); - } + + if (device == NULL) + return NULL; + + if (device_dispatch_table(device)->GetDeviceProcAddr == NULL) + return NULL; + return device_dispatch_table(device)->GetDeviceProcAddr(device, pName); } VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) { - if (instance == NULL) - return NULL; - - /* loader uses this to force layer initialization; instance object is wrapped */ - if (!strcmp("vkGetInstanceProcAddr", pName)) { - initInstanceTable((const VkBaseLayerObject *) instance); + if (!strcmp("vkGetInstanceProcAddr", pName)) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } - if (!strcmp("vkEnumerateDeviceLayerProperties", pName)) return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties; if (!strcmp("vkEnumerateDeviceExtensionProperties", pName)) return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties; if (!strcmp("vkGetPhysicalDeviceFormatProperties", pName)) return (PFN_vkVoidFunction) basic_GetPhysicalDeviceFormatProperties; + if (!strcmp("vkCreateInstance", pName)) + return (PFN_vkVoidFunction) basic_CreateInstance; if (!strcmp("vkDestroyInstance", pName)) return (PFN_vkVoidFunction) basic_DestroyInstance; + if (!strcmp("vkCreateDevice", pName)) + return (PFN_vkVoidFunction) basic_CreateDevice; if (!strcmp("vkEnumeratePhysicalDevices", pName)) return (PFN_vkVoidFunction) basic_EnumeratePhysicalDevices; + if (instance == NULL) + return NULL; + if (instance_dispatch_table(instance)->GetInstanceProcAddr == NULL) return NULL; return instance_dispatch_table(instance)->GetInstanceProcAddr(instance, pName); diff --git a/layers/device_limits.cpp b/layers/device_limits.cpp index fbb9af3b..24df64e1 100644 --- a/layers/device_limits.cpp +++ b/layers/device_limits.cpp @@ -43,6 +43,7 @@ #endif #include "vk_struct_size_helper.h" #include "device_limits.h" +#include "vulkan/vk_layer.h" #include "vk_layer_config.h" #include "vulkan/vk_debug_marker_layer.h" #include "vk_layer_table.h" @@ -183,21 +184,36 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerPropertie VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { - layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); - VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; - VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance); - - if (result == VK_SUCCESS) { - my_data->report_data = debug_report_create_instance( - pTable, - *pInstance, - pCreateInfo->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames); - - init_device_limits(my_data, pAllocator); - my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE()); + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; } - return result; + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) + return result; + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); + my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; + layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); + + my_data->report_data = debug_report_create_instance( + my_data->instance_dispatch_table, + *pInstance, + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + + init_device_limits(my_data, pAllocator); + my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE()); + + return VK_SUCCESS; } /* hook DestroyInstance to remove tableInstanceMap entry */ @@ -448,17 +464,34 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice g if (skipCall) return VK_ERROR_VALIDATION_FAILED_EXT; - layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); - VkResult result = device_data->device_dispatch_table->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice); - if (result == VK_SUCCESS) { - device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice); - createDeviceRegisterExtensions(pCreateInfo, *pDevice); - device_data->physicalDevice = gpu; + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); - // Get physical device properties for this device - phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(phy_dev_data->physDevPropertyMap[*pDevice])); + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; } + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; + } + + 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->device_dispatch_table = new VkLayerDispatchTable; + layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); + my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); + my_device_data->physicalDevice = gpu; + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + + // Get physical device properties for this device + phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(phy_dev_data->physDevPropertyMap[*pDevice])); return result; } @@ -685,21 +718,8 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName) { - if (dev == NULL) - return NULL; - - layer_data *my_data; - /* loader uses this to force layer initialization; device object is wrapped */ - if (!strcmp(funcName, "vkGetDeviceProcAddr")) { - VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map); - my_data->device_dispatch_table = new VkLayerDispatchTable; - layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev); + if (!strcmp(funcName, "vkGetDeviceProcAddr")) return (PFN_vkVoidFunction) vkGetDeviceProcAddr; - } - my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map); - if (!strcmp(funcName, "vkCreateDevice")) - return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkDestroyDevice")) return (PFN_vkVoidFunction) vkDestroyDevice; if (!strcmp(funcName, "vkGetDeviceQueue")) @@ -723,6 +743,10 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD if (!strcmp(funcName, "vkCmdFillBuffer")) return (PFN_vkVoidFunction) vkCmdFillBuffer; + if (dev == NULL) + return NULL; + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map); VkLayerDispatchTable* pTable = my_data->device_dispatch_table; { if (pTable->GetDeviceProcAddr == NULL) @@ -734,23 +758,18 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) { PFN_vkVoidFunction fptr; - if (instance == NULL) - return NULL; layer_data *my_data; - /* loader uses this to force layer initialization; instance object is wrapped */ - if (!strcmp(funcName, "vkGetInstanceProcAddr")) { - VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map); - my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; - layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst); + if (!strcmp(funcName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } - my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + if (!strcmp(funcName, "vkGetDeviceProcAddr")) + return (PFN_vkVoidFunction) vkGetDeviceProcAddr; if (!strcmp(funcName, "vkCreateInstance")) return (PFN_vkVoidFunction) vkCreateInstance; if (!strcmp(funcName, "vkDestroyInstance")) return (PFN_vkVoidFunction) vkDestroyInstance; + if (!strcmp(funcName, "vkCreateDevice")) + return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkEnumeratePhysicalDevices")) return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices; if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures")) @@ -772,6 +791,10 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(V if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties; + if (!instance) return NULL; + + my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); if (fptr) return fptr; diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index c85598d4..8d6ac658 100644 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -2813,21 +2813,34 @@ static void init_draw_state(layer_data *my_data, const VkAllocationCallbacks *pA VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { - // TODOSC : Shouldn't need any customization here + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) + return result; + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); - VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; - VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance); + my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; + layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); - 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( - pTable, - *pInstance, - pCreateInfo->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames); + my_data->report_data = debug_report_create_instance( + my_data->instance_dispatch_table, + *pInstance, + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + + init_draw_state(my_data, pAllocator); - init_draw_state(my_data, pAllocator); - } return result; } @@ -2890,16 +2903,35 @@ static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { - layer_data *instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map); - layer_data *dev_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); - VkResult result = dev_data->device_dispatch_table->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); - if (result == VK_SUCCESS) { - dev_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice); - createDeviceRegisterExtensions(pCreateInfo, *pDevice); - // Get physical device limits for this device - instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(instance_data->physDevPropertyMap[*pDevice])); + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; } + + 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); + + // Setup device dispatch table + my_device_data->device_dispatch_table = new VkLayerDispatchTable; + layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); + + my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + // Get physical device limits for this device + my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_instance_data->physDevPropertyMap[*pDevice])); return result; } @@ -6088,21 +6120,8 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDbgMarkerEnd(VkCommandBuffer com VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName) { - if (dev == NULL) - return NULL; - - layer_data *dev_data; - /* loader uses this to force layer initialization; device object is wrapped */ - if (!strcmp(funcName, "vkGetDeviceProcAddr")) { - VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev; - dev_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map); - dev_data->device_dispatch_table = new VkLayerDispatchTable; - layer_initialize_dispatch_table(dev_data->device_dispatch_table, wrapped_dev); + if (!strcmp(funcName, "vkGetDeviceProcAddr")) return (PFN_vkVoidFunction) vkGetDeviceProcAddr; - } - dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map); - if (!strcmp(funcName, "vkCreateDevice")) - return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkDestroyDevice")) return (PFN_vkVoidFunction) vkDestroyDevice; if (!strcmp(funcName, "vkQueueSubmit")) @@ -6306,6 +6325,12 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD if (!strcmp(funcName, "vkCreateSemaphore")) return (PFN_vkVoidFunction) vkCreateSemaphore; + if (dev == NULL) + return NULL; + + layer_data *dev_data; + dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map); + if (dev_data->device_extensions.wsi_enabled) { if (!strcmp(funcName, "vkCreateSwapchainKHR")) @@ -6337,21 +6362,14 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) { - PFN_vkVoidFunction fptr; - if (instance == NULL) - return NULL; - - layer_data* my_data; - /* loader uses this to force layer initialization; instance object is wrapped */ - if (!strcmp(funcName, "vkGetInstanceProcAddr")) { - VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map); - my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; - layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst); + if (!strcmp(funcName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } + if (!strcmp(funcName, "vkGetDeviceProcAddr")) + return (PFN_vkVoidFunction) vkGetDeviceProcAddr; if (!strcmp(funcName, "vkCreateInstance")) return (PFN_vkVoidFunction) vkCreateInstance; + if (!strcmp(funcName, "vkCreateDevice")) + return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkDestroyInstance")) return (PFN_vkVoidFunction) vkDestroyInstance; if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) @@ -6363,15 +6381,19 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(V if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties")) return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties; + if (instance == NULL) + return NULL; + + PFN_vkVoidFunction fptr; + + layer_data* my_data; my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); if (fptr) return fptr; - { - VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; - if (pTable->GetInstanceProcAddr == NULL) - return NULL; - return pTable->GetInstanceProcAddr(instance, funcName); - } + VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; + if (pTable->GetInstanceProcAddr == NULL) + return NULL; + return pTable->GetInstanceProcAddr(instance, funcName); } diff --git a/layers/image.cpp b/layers/image.cpp index 1281dfba..f371bdc8 100644 --- a/layers/image.cpp +++ b/layers/image.cpp @@ -146,16 +146,34 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) + return result; + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); - VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; - VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance); + my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; + layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); - if (result == VK_SUCCESS) { - my_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames); + my_data->report_data = debug_report_create_instance( + my_data->instance_dispatch_table, + *pInstance, + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + + InitImage(my_data, pAllocator); - InitImage(my_data, pAllocator); - } return result; } @@ -182,16 +200,35 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { - layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); - layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); - VkResult result = device_data->device_dispatch_table->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); - if(result == VK_SUCCESS) - { - device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice); - device_data->physicalDevice = physicalDevice; + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; } - instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &(device_data->physicalDeviceProperties)); + layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); + + // Setup device dispatch table + my_device_data->device_dispatch_table = new VkLayerDispatchTable; + layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); + + my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); + my_device_data->physicalDevice = physicalDevice; + + my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &(my_device_data->physicalDeviceProperties)); return result; } @@ -1141,23 +1178,8 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysi VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName) { - if (device == NULL) { - return NULL; - } - - layer_data *my_data; - // loader uses this to force layer initialization; device object is wrapped - if (!strcmp(funcName, "vkGetDeviceProcAddr")) { - VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map); - my_data->device_dispatch_table = new VkLayerDispatchTable; - layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev); + if (!strcmp(funcName, "vkGetDeviceProcAddr")) return (PFN_vkVoidFunction) vkGetDeviceProcAddr; - } - - my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); - if (!strcmp(funcName, "vkCreateDevice")) - return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkDestroyDevice")) return (PFN_vkVoidFunction) vkDestroyDevice; if (!strcmp(funcName, "vkCreateImage")) @@ -1189,6 +1211,12 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD if (!strcmp(funcName, "vkGetImageSubresourceLayout")) return (PFN_vkVoidFunction) vkGetImageSubresourceLayout; + if (device == NULL) { + return NULL; + } + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkLayerDispatchTable* pTable = my_data->device_dispatch_table; { if (pTable->GetDeviceProcAddr == NULL) @@ -1199,25 +1227,14 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) { - if (instance == NULL) { - return NULL; - } - - layer_data *my_data; - // loader uses this to force layer initialization; instance object is wrapped - if (!strcmp(funcName, "vkGetInstanceProcAddr")) { - VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map); - my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; - layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst); + if (!strcmp(funcName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } - - my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); if (!strcmp(funcName, "vkCreateInstance")) return (PFN_vkVoidFunction) vkCreateInstance; if (!strcmp(funcName, "vkDestroyInstance")) return (PFN_vkVoidFunction) vkDestroyInstance; + if (!strcmp(funcName, "vkCreateDevice")) + return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties; if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) @@ -1229,14 +1246,18 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(V if (!strcmp(funcName, "vkGetPhysicalDeviceProperties")) return (PFN_vkVoidFunction) vkGetPhysicalDeviceProperties; + if (instance == NULL) { + return NULL; + } + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); if(fptr) return fptr; - { - VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; - if (pTable->GetInstanceProcAddr == NULL) - return NULL; - return pTable->GetInstanceProcAddr(instance, funcName); - } + VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; + if (pTable->GetInstanceProcAddr == NULL) + return NULL; + return pTable->GetInstanceProcAddr(instance, funcName); } diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp index b621c6e6..afcc7cd4 100644 --- a/layers/mem_tracker.cpp +++ b/layers/mem_tracker.cpp @@ -1119,19 +1119,35 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { - layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); - VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; - VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance); + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); - if (result == VK_SUCCESS) { - my_data->report_data = debug_report_create_instance( - pTable, - *pInstance, - pCreateInfo->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames); + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; - init_mem_tracker(my_data, pAllocator); + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) { + return result; } + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); + my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; + layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); + + my_data->report_data = debug_report_create_instance( + my_data->instance_dispatch_table, + *pInstance, + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + + init_mem_tracker(my_data, pAllocator); + return result; } @@ -1161,15 +1177,35 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { - layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); - VkLayerDispatchTable *pDeviceTable = my_device_data->device_dispatch_table; - 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); - my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); - createDeviceRegisterExtensions(pCreateInfo, *pDevice); - my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &my_device_data->properties); + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; } + + 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); + + // Setup device dispatch table + my_device_data->device_dispatch_table = new VkLayerDispatchTable; + layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); + + my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &my_device_data->properties); + return result; } @@ -3192,20 +3228,8 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( VkDevice dev, const char *funcName) { - if (dev == NULL) - return NULL; - - layer_data *my_data; - /* loader uses this to force layer initialization; device object is wrapped */ - if (!strcmp(funcName, "vkGetDeviceProcAddr")) { - VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map); - my_data->device_dispatch_table = new VkLayerDispatchTable; - layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev); + if (!strcmp(funcName, "vkGetDeviceProcAddr")) return (PFN_vkVoidFunction) vkGetDeviceProcAddr; - } - if (!strcmp(funcName, "vkCreateDevice")) - return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkDestroyDevice")) return (PFN_vkVoidFunction) vkDestroyDevice; if (!strcmp(funcName, "vkQueueSubmit")) @@ -3332,6 +3356,10 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( return (PFN_vkVoidFunction) vkDestroyFramebuffer; + if (dev == NULL) + return NULL; + + layer_data *my_data; my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map); if (my_data->wsi_enabled) { @@ -3358,25 +3386,19 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( const char *funcName) { PFN_vkVoidFunction fptr; - if (instance == NULL) - return NULL; - layer_data *my_data; - /* loader uses this to force layer initialization; instance object is wrapped */ - if (!strcmp(funcName, "vkGetInstanceProcAddr")) { - VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map); - my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; - layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst); + if (!strcmp(funcName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } - my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + if (!strcmp(funcName, "vkGetDeviceProcAddr")) + return (PFN_vkVoidFunction) vkGetDeviceProcAddr; if (!strcmp(funcName, "vkDestroyInstance")) return (PFN_vkVoidFunction) vkDestroyInstance; if (!strcmp(funcName, "vkCreateInstance")) return (PFN_vkVoidFunction) vkCreateInstance; if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties")) return (PFN_vkVoidFunction) vkGetPhysicalDeviceMemoryProperties; + if (!strcmp(funcName, "vkCreateDevice")) + return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties; if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) @@ -3386,14 +3408,16 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties")) return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties; + if (instance == NULL) return NULL; + + layer_data *my_data; + my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); - if (fptr) - return fptr; + if (fptr) return fptr; - { - VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; - if (pTable->GetInstanceProcAddr == NULL) - return NULL; - return pTable->GetInstanceProcAddr(instance, funcName); - } + VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; + if (pTable->GetInstanceProcAddr == NULL) + return NULL; + return pTable->GetInstanceProcAddr(instance, funcName); } diff --git a/layers/multi.cpp b/layers/multi.cpp index c5d9d1b5..3bbea8c5 100644 --- a/layers/multi.cpp +++ b/layers/multi.cpp @@ -80,28 +80,22 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL multi1CreateGraphicsPipelines( VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 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); + if (!strcmp(pName, "multi1GetDeviceProcAddr") || !strcmp(pName, "vkGetDeviceProcAddr")) 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); - } + + if (device == NULL) + return NULL; + + VkLayerDispatchTable *pTable = get_dispatch_table(multi1_device_table_map, device); + if (pTable->GetDeviceProcAddr == NULL) + return NULL; + return pTable->GetDeviceProcAddr(device, pName); } @@ -154,15 +148,8 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL multi2DestroyInstance(VkInstance inst VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 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); + if (!strcmp(pName, "multi2GetInstanceProcAddr") || !strcmp(pName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction) multi2GetInstanceProcAddr; - } - if (!strcmp("vkEnumeratePhysicalDevices", pName)) return (PFN_vkVoidFunction) multi2EnumeratePhysicalDevices; if (!strcmp("GetPhysicalDeviceProperties", pName)) @@ -171,12 +158,14 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL multi2GetInstanceProcAd 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); - } + + if (inst == NULL) + return NULL; + + VkLayerInstanceDispatchTable *pTable = get_dispatch_table(multi2_instance_table_map, inst); + if (pTable->GetInstanceProcAddr == NULL) + return NULL; + return pTable->GetInstanceProcAddr(inst, pName); } #ifdef __cplusplus diff --git a/layers/object_tracker.h b/layers/object_tracker.h index de44f0e2..4622c189 100644 --- a/layers/object_tracker.h +++ b/layers/object_tracker.h @@ -29,6 +29,7 @@ #include "vulkan/vk_layer.h" #include "vk_layer_extension_utils.h" #include "vk_enum_string_helper.h" +#include "vk_layer_table.h" // Object Tracker ERROR codes typedef enum _OBJECT_TRACK_ERROR @@ -689,22 +690,38 @@ explicit_CreateInstance( const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); - VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance); - VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance); + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } - 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->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames); - createInstanceRegisterExtensions(pCreateInfo, *pInstance); - - initObjectTracker(my_data, pAllocator); - create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT); + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) { + return result; } + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); + initInstanceTable(*pInstance, fpGetInstanceProcAddr, object_tracker_instance_table_map); + VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance); + + my_data->report_data = debug_report_create_instance( + pInstanceTable, + *pInstance, + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + + initObjectTracker(my_data, pAllocator); + createInstanceRegisterExtensions(pCreateInfo, *pInstance); + + create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT); + return result; } @@ -730,16 +747,36 @@ explicit_CreateDevice( VkDevice *pDevice) { loader_platform_thread_lock_mutex(&objLock); - VkLayerDispatchTable *pDeviceTable = get_dispatch_table(object_tracker_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); - create_device(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT); - createDeviceRegisterExtensions(pCreateInfo, *pDevice); + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + loader_platform_thread_unlock_mutex(&objLock); + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + loader_platform_thread_unlock_mutex(&objLock); + return result; } + 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); + + initDeviceTable(*pDevice, fpGetDeviceProcAddr, object_tracker_device_table_map); + + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + + create_device(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT); + loader_platform_thread_unlock_mutex(&objLock); return result; } diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp index c3518373..f63562d4 100644 --- a/layers/param_checker.cpp +++ b/layers/param_checker.cpp @@ -1760,18 +1760,34 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { - VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, *pInstance); - VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance); + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); - if (result == VK_SUCCESS) { - layer_data *data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); - data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames); - - InitParamChecker(data, pAllocator); + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; } + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) return result; + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); + VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, pc_instance_table_map); + + my_data->report_data = debug_report_create_instance( + pTable, + *pInstance, + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + + InitParamChecker(my_data, pAllocator); + + return result; } VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance( @@ -2035,21 +2051,32 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( VkDevice* pDevice) { /* - * NOTE: The loader fills in the ICD's device object in *pDevice. - * Use that object to get the dispatch table. - * * NOTE: We do not validate physicalDevice or any dispatchable * object as the first parameter. We couldn't get here if it was wrong! */ - VkLayerDispatchTable *pTable = get_dispatch_table(pc_device_table_map, *pDevice); - VkResult result = pTable->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); - if(result == VK_SUCCESS) - { - layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); - layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); - device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice); + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; } + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; + } + + layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), 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); + initDeviceTable(*pDevice, fpGetDeviceProcAddr, pc_device_table_map); + return result; } @@ -6437,18 +6464,8 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName) { - if (device == NULL) { - return NULL; - } - - /* loader uses this to force layer initialization; device object is wrapped */ - if (!strcmp(funcName, "vkGetDeviceProcAddr")) { - initDeviceTable(pc_device_table_map, (const VkBaseLayerObject *) device); + if (!strcmp(funcName, "vkGetDeviceProcAddr")) return (PFN_vkVoidFunction) vkGetDeviceProcAddr; - } - - if (!strcmp(funcName, "vkCreateDevice")) - return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkDestroyDevice")) return (PFN_vkVoidFunction) vkDestroyDevice; if (!strcmp(funcName, "vkGetDeviceQueue")) @@ -6608,29 +6625,25 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD if (!strcmp(funcName, "vkCmdNextSubpass")) return (PFN_vkVoidFunction) vkCmdNextSubpass; - { - if (get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr == NULL) - return NULL; - return get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr(device, funcName); + if (device == NULL) { + return NULL; } + + if (get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr == NULL) + return NULL; + return get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr(device, funcName); } VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) { - if (instance == NULL) { - return NULL; - } - - /* loader uses this to force layer initialization; instance object is wrapped */ - if (!strcmp(funcName, "vkGetInstanceProcAddr")) { - initInstanceTable(pc_instance_table_map, (const VkBaseLayerObject *) instance); + if (!strcmp(funcName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } - if (!strcmp(funcName, "vkCreateInstance")) return (PFN_vkVoidFunction) vkCreateInstance; if (!strcmp(funcName, "vkDestroyInstance")) return (PFN_vkVoidFunction) vkDestroyInstance; + if (!strcmp(funcName, "vkCreateDevice")) + return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkEnumeratePhysicalDevices")) return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices; if (!strcmp(funcName, "vkGetPhysicalDeviceProperties")) @@ -6648,14 +6661,16 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(V if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties")) return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties; + if (instance == NULL) { + return NULL; + } + layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName); if(fptr) return fptr; - { - if (get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr == NULL) - return NULL; - return get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName); - } + if (get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr == NULL) + return NULL; + return get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName); } diff --git a/layers/screenshot.cpp b/layers/screenshot.cpp index 521aedc6..32312897 100644 --- a/layers/screenshot.cpp +++ b/layers/screenshot.cpp @@ -406,21 +406,36 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( const VkAllocationCallbacks* pAllocator, VkDevice *pDevice) { - VkLayerDispatchTable *pDisp = get_dispatch_table(screenshot_device_table_map, *pDevice); - VkResult result = pDisp->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice); - - if (result == VK_SUCCESS) { - init_screenshot(); - createDeviceRegisterExtensions(pCreateInfo, *pDevice); - // Create a mapping from a device to a physicalDevice - if (deviceMap[*pDevice] == NULL) - { - DeviceMapStruct *deviceMapElem = new DeviceMapStruct; - deviceMap[*pDevice] = deviceMapElem; - } - deviceMap[*pDevice]->physicalDevice = gpu; + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; } + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; + } + + initDeviceTable(*pDevice, fpGetDeviceProcAddr, screenshot_device_table_map); + + init_screenshot(); + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + // Create a mapping from a device to a physicalDevice + if (deviceMap[*pDevice] == NULL) + { + DeviceMapStruct *deviceMapElem = new DeviceMapStruct; + deviceMap[*pDevice] = deviceMapElem; + } + deviceMap[*pDevice]->physicalDevice = gpu; + return result; } @@ -743,17 +758,9 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( VkDevice dev, const char *funcName) { - if (dev == NULL) { - return NULL; - } - - /* loader uses this to force layer initialization; device object is wrapped */ if (!strcmp(funcName, "vkGetDeviceProcAddr")) { - initDeviceTable(screenshot_device_table_map, (const VkBaseLayerObject *) dev); return (PFN_vkVoidFunction)vkGetDeviceProcAddr; } - if (!strcmp(funcName, "vkCreateDevice")) - return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkGetDeviceQueue")) return (PFN_vkVoidFunction) vkGetDeviceQueue; @@ -761,6 +768,10 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( if (!strcmp(funcName, "vkCreateCommandPool")) return (PFN_vkVoidFunction) vkCreateCommandPool; + if (dev == NULL) { + return NULL; + } + VkLayerDispatchTable *pDisp = get_dispatch_table(screenshot_device_table_map, dev); if (deviceExtMap.size() != 0 && deviceExtMap[pDisp].wsi_enabled) { @@ -780,21 +791,19 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) { - if (instance == VK_NULL_HANDLE) { - return NULL; - } - - /* loader uses this to force layer initialization; instance object is wrapped */ - if (!strcmp("vkGetInstanceProcAddr", funcName)) { - initInstanceTable((const VkBaseLayerObject *) instance); + if (!strcmp("vkGetInstanceProcAddr", funcName)) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } - + if (!strcmp(funcName, "vkCreateDevice")) + return (PFN_vkVoidFunction) vkCreateDevice; if (!strcmp(funcName, "vkEnumeratePhysicalDevices")) return (PFN_vkVoidFunction)vkEnumeratePhysicalDevices; if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties")) return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties; + if (instance == VK_NULL_HANDLE) { + return NULL; + } + VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance); if (pTable->GetInstanceProcAddr == NULL) return NULL; diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp index d9e0a092..051d14f4 100644 --- a/layers/swapchain.cpp +++ b/layers/swapchain.cpp @@ -286,22 +286,37 @@ static const char *sharingModeStr(VkSharingMode value) VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { - layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); - // Call down the call chain: - VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; - VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance); - if (result == VK_SUCCESS) { - // Since it succeeded, do layer-specific work: - layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); - my_data->report_data = debug_report_create_instance( - pTable, - *pInstance, - pCreateInfo->enabledExtensionCount, - pCreateInfo->ppEnabledExtensionNames); - // Call the following function after my_data is initialized: - createInstanceRegisterExtensions(pCreateInfo, *pInstance); - initSwapchain(my_data, pAllocator); + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) { + return result; } + + layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); + my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; + layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); + + my_data->report_data = debug_report_create_instance( + my_data->instance_dispatch_table, + *pInstance, + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + + // Call the following function after my_data is initialized: + createInstanceRegisterExtensions(pCreateInfo, *pInstance); + initSwapchain(my_data, pAllocator); + return result; } @@ -874,22 +889,34 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInst VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { - VkResult result = VK_SUCCESS; - VkBool32 skipCall = VK_FALSE; - layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); - if (VK_FALSE == skipCall) { - layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); - // Call down the call chain: - result = my_device_data->device_dispatch_table->CreateDevice( - physicalDevice, pCreateInfo, pAllocator, pDevice); - if (result == VK_SUCCESS) { - // Since it succeeded, do layer-specific work: - layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); - my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); - createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice); - } + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; + } + + layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); + + // Setup device dispatch table + my_device_data->device_dispatch_table = new VkLayerDispatchTable; + layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); + + my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); + createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice); + return result; } @@ -1861,41 +1888,6 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( return VK_ERROR_VALIDATION_FAILED_EXT; } -static inline PFN_vkVoidFunction layer_intercept_proc(const char *name) -{ - if (!name || name[0] != 'v' || name[1] != 'k') - return NULL; - - name += 2; - if (!strcmp(name, "CreateInstance")) - return (PFN_vkVoidFunction) vkCreateInstance; - if (!strcmp(name, "DestroyInstance")) - return (PFN_vkVoidFunction) vkDestroyInstance; - if (!strcmp(name, "EnumeratePhysicalDevices")) - return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices; - if (!strcmp(name, "CreateDevice")) - return (PFN_vkVoidFunction) vkCreateDevice; - if (!strcmp(name, "DestroyDevice")) - return (PFN_vkVoidFunction) vkDestroyDevice; - - return NULL; -} -static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name) -{ - if (!name || name[0] != 'v' || name[1] != 'k') - return NULL; - - name += 2; - if (!strcmp(name, "CreateInstance")) - return (PFN_vkVoidFunction) vkCreateInstance; - if (!strcmp(name, "DestroyInstance")) - return (PFN_vkVoidFunction) vkDestroyInstance; - if (!strcmp(name, "EnumeratePhysicalDevices")) - return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices; - - return NULL; -} - VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, @@ -1933,24 +1925,16 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName) { - PFN_vkVoidFunction addr; + if (!strcmp("vkGetDeviceProcAddr", funcName)) + return (PFN_vkVoidFunction) vkGetDeviceProcAddr; + if (!strcmp(funcName, "vkDestroyDevice")) + return (PFN_vkVoidFunction) vkDestroyDevice; + if (device == VK_NULL_HANDLE) { return NULL; } layer_data *my_data; - /* loader uses this to force layer initialization; device object is wrapped */ - if (!strcmp("vkGetDeviceProcAddr", funcName)) { - VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map); - my_data->device_dispatch_table = new VkLayerDispatchTable; - layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev); - return (PFN_vkVoidFunction) vkGetDeviceProcAddr; - } - - addr = layer_intercept_proc(funcName); - if (addr) - return addr; my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); VkLayerDispatchTable *pDisp = my_data->device_dispatch_table; @@ -1968,39 +1952,36 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD if (!strcmp("vkQueuePresentKHR", funcName)) return reinterpret_cast<PFN_vkVoidFunction>(vkQueuePresentKHR); } - { - if (pDisp->GetDeviceProcAddr == NULL) - return NULL; - return pDisp->GetDeviceProcAddr(device, funcName); - } + + if (pDisp->GetDeviceProcAddr == NULL) + return NULL; + return pDisp->GetDeviceProcAddr(device, funcName); } VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) { - PFN_vkVoidFunction addr; - if (instance == VK_NULL_HANDLE) { - return NULL; - } - - layer_data *my_data; - /* loader uses this to force layer initialization; instance object is wrapped */ - if (!strcmp("vkGetInstanceProcAddr", funcName)) { - VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance; - my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map); - my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; - layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst); + if (!strcmp("vkGetInstanceProcAddr", funcName)) return (PFN_vkVoidFunction) vkGetInstanceProcAddr; - } - + if (!strcmp(funcName, "vkCreateInstance")) + return (PFN_vkVoidFunction) vkCreateInstance; + if (!strcmp(funcName, "vkDestroyInstance")) + return (PFN_vkVoidFunction) vkDestroyInstance; + if (!strcmp(funcName, "vkCreateDevice")) + return (PFN_vkVoidFunction) vkCreateDevice; + if (!strcmp(funcName, "vkEnumeratePhysicalDevices")) + return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices; if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties; if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties; - addr = layer_intercept_instance_proc(funcName); - if (addr) - return addr; + if (instance == VK_NULL_HANDLE) { + return NULL; + } + + PFN_vkVoidFunction addr; + layer_data *my_data; my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table; addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); diff --git a/layers/unique_objects.h b/layers/unique_objects.h index 02e66990..8d344a05 100644 --- a/layers/unique_objects.h +++ b/layers/unique_objects.h @@ -141,13 +141,27 @@ explicit_CreateInstance( const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { + VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); - VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(unique_objects_instance_table_map, *pInstance); - VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance); + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance"); + if (fpCreateInstance == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; - if (result == VK_SUCCESS) { - createInstanceRegisterExtensions(pCreateInfo, *pInstance); + VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); + if (result != VK_SUCCESS) { + return result; } + + initInstanceTable(*pInstance, fpGetInstanceProcAddr, unique_objects_instance_table_map); + + createInstanceRegisterExtensions(pCreateInfo, *pInstance); + return result; } @@ -176,11 +190,29 @@ explicit_CreateDevice( 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) { - createDeviceRegisterExtensions(pCreateInfo, *pDevice); + VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); + + assert(chain_info->u.pLayerInfo); + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; } + + // Advance the link info for the next element on the chain + chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; + + VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); + if (result != VK_SUCCESS) { + return result; + } + + // Setup layer's device dispatch table + initDeviceTable(*pDevice, fpGetDeviceProcAddr, unique_objects_device_table_map); + + createDeviceRegisterExtensions(pCreateInfo, *pDevice); + return result; } diff --git a/layers/vk_layer_table.cpp b/layers/vk_layer_table.cpp index 93d2fbf4..b06fb312 100644 --- a/layers/vk_layer_table.cpp +++ b/layers/vk_layer_table.cpp @@ -100,9 +100,9 @@ VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object) device_table_map::const_iterator it = map.find((void *) key); #if DISPATCH_MAP_DEBUG if (it != map.end()) { - fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second); + fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second); } else { - fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key); + fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key); } #endif assert(it != map.end() && "Not able to find device dispatch entry"); @@ -125,20 +125,22 @@ VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* return it->second; } -VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo) +VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func) { VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *) pCreateInfo->pNext; - while (chain_info && chain_info->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO) { + while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO + && chain_info->function == func)) { chain_info = (VkLayerInstanceCreateInfo *) chain_info->pNext; } assert(chain_info != NULL); return chain_info; } -VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo) +VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func) { VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *) pCreateInfo->pNext; - while (chain_info && chain_info->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO) { + while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO + && chain_info->function == func)) { chain_info = (VkLayerDeviceCreateInfo *) chain_info->pNext; } assert(chain_info != NULL); @@ -152,67 +154,64 @@ VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo) * Device -> CommandBuffer or Queue * If use the object themselves as key to map then implies Create entrypoints have to be intercepted * and a new key inserted into map */ -VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew) +VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map) { VkLayerInstanceDispatchTable *pTable; - assert(instancew); - VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject; + dispatch_key key = get_dispatch_key(instance); + instance_table_map::const_iterator it = map.find((void *) key); - std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp); if (it == map.end()) { pTable = new VkLayerInstanceDispatchTable; - map[(void *) *ppDisp] = pTable; + map[(void *) key] = pTable; #if DISPATCH_MAP_DEBUG - fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable); + fprintf(stderr, "New, Instance: map: %p, key: %p, table: %p\n", &map, key, pTable); #endif } else { #if DISPATCH_MAP_DEBUG - fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second); + fprintf(stderr, "Instance: map: %p, key: %p, table: %p\n", &map, key, it->second); #endif return it->second; } - layer_init_instance_dispatch_table(pTable, instancew); + layer_init_instance_dispatch_table(instance, pTable, gpa); return pTable; } -VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew) +VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa) { - return initInstanceTable(tableInstanceMap, instancew); + return initInstanceTable(instance, gpa, tableInstanceMap); } -VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw) +VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map) { - VkLayerDispatchTable *layer_device_table = NULL; - assert(devw); - VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject); - VkLayerDispatchTable *base_device_table = *ppDisp; + VkLayerDispatchTable *pTable; + dispatch_key key = get_dispatch_key(device); + device_table_map::const_iterator it = map.find((void *) key); - std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table); if (it == map.end()) { - layer_device_table = new VkLayerDispatchTable; - map[(void *) base_device_table] = layer_device_table; + pTable = new VkLayerDispatchTable; + map[(void *) key] = pTable; #if DISPATCH_MAP_DEBUG - fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table); + fprintf(stderr, "New, Device: map: %p, key: %p, table: %p\n", &map, key, pTable); #endif } else { #if DISPATCH_MAP_DEBUG - fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second); + fprintf(stderr, "Device: map: %p, key: %p, table: %p\n", &map, key, it->second); #endif return it->second; } - layer_initialize_dispatch_table(layer_device_table, devw); + layer_init_device_dispatch_table(device, pTable, gpa); - return layer_device_table; + return pTable; } -VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw) +VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa) { - return initDeviceTable(tableMap, devw); + return initDeviceTable(device, gpa, tableMap); } diff --git a/layers/vk_layer_table.h b/layers/vk_layer_table.h index 04ea2661..0011c857 100644 --- a/layers/vk_layer_table.h +++ b/layers/vk_layer_table.h @@ -29,10 +29,11 @@ typedef std::unordered_map<void *, VkLayerDispatchTable *> device_table_map; typedef std::unordered_map<void *, VkLayerInstanceDispatchTable *> instance_table_map; -VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw); -VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw); -VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew); -VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew); +VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map); +VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa); +VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map); +VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa); + typedef void *dispatch_key; @@ -49,8 +50,8 @@ VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object); VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object); -VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo); -VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo); +VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func); +VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func); void destroy_device_dispatch_table(dispatch_key key); void destroy_instance_dispatch_table(dispatch_key key); diff --git a/loader/loader.c b/loader/loader.c index 9a3aa3f4..82aaafa0 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -1140,21 +1140,19 @@ static void loader_destroy_logical_device(const struct loader_instance *inst, static struct loader_device *loader_add_logical_device( const struct loader_instance *inst, - const VkDevice dev, struct loader_device **device_list) { struct loader_device *new_dev; new_dev = loader_heap_alloc(inst, sizeof(struct loader_device), VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); if (!new_dev) { - loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc struct laoder-device"); + loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc struct loader-device"); return NULL; } memset(new_dev, 0, sizeof(struct loader_device)); new_dev->next = *device_list; - new_dev->device = dev; *device_list = new_dev; return new_dev; } @@ -2295,6 +2293,13 @@ void loader_layer_scan( static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_internal(VkInstance inst, const char * pName) { + if (!strcmp(pName, "vkGetInstanceProcAddr")) + return (void *) loader_gpa_instance_internal; + if (!strcmp(pName, "vkCreateInstance")) + return (void *) loader_CreateInstance; + if (!strcmp(pName, "vkCreateDevice")) + return (void *) loader_create_device_terminator; + // inst is not wrapped if (inst == VK_NULL_HANDLE) { return NULL; @@ -2302,9 +2307,6 @@ static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_internal(VkI VkLayerInstanceDispatchTable* disp_table = * (VkLayerInstanceDispatchTable **) inst; void *addr; - if (!strcmp(pName, "vkGetInstanceProcAddr")) - return (void *) loader_gpa_instance_internal; - if (disp_table == NULL) return NULL; @@ -2785,19 +2787,17 @@ VkResult loader_enable_instance_layers( } /* Add any implicit layers first */ - loader_add_layer_implicit( - inst, - VK_LAYER_TYPE_INSTANCE_IMPLICIT, - &inst->activated_layer_list, - instance_layers); + loader_add_layer_implicit(inst, + VK_LAYER_TYPE_INSTANCE_IMPLICIT, + &inst->activated_layer_list, + instance_layers); /* Add any layers specified via environment variable next */ - loader_add_layer_env( - inst, - VK_LAYER_TYPE_INSTANCE_EXPLICIT, - "VK_INSTANCE_LAYERS", - &inst->activated_layer_list, - instance_layers); + loader_add_layer_env(inst, + VK_LAYER_TYPE_INSTANCE_EXPLICIT, + "VK_INSTANCE_LAYERS", + &inst->activated_layer_list, + instance_layers); /* Add layers specified by the application */ err = loader_add_layer_names_to_list( @@ -2810,87 +2810,116 @@ VkResult loader_enable_instance_layers( return err; } -uint32_t loader_activate_instance_layers(struct loader_instance *inst) -{ - uint32_t layer_idx; - VkBaseLayerObject *wrappedInstance; +/* + * Given the list of layers to activate in the loader_instance + * structure. This function will add a VkLayerInstanceCreateInfo + * structure to the VkInstanceCreateInfo.pNext pointer. + * Each activated layer will have it's own VkLayerInstanceLink + * structure that tells the layer what Get*ProcAddr to call to + * get function pointers to the next layer down. + * Once the chain info has been created this function will + * execute the CreateInstance call chain. Each layer will + * then have an opportunity in it's CreateInstance function + * to setup it's dispatch table when the lower layer returns + * successfully. + * Each layer can wrap or not-wrap the returned VkInstance object + * as it sees fit. + * The instance chain is terminated by a loader function + * that will call CreateInstance on all available ICD's and + * cache those VkInstance objects for future use. + */ +VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, + const VkAllocationCallbacks* pAllocator, + struct loader_instance *inst) +{ + uint32_t activated_layers = 0; + VkLayerInstanceCreateInfo chain_info; + VkLayerInstanceLink *layer_instance_link_info = NULL; + VkInstanceCreateInfo loader_create_info; + VkResult res; - if (inst == NULL) { - return 0; - } + PFN_vkGetInstanceProcAddr nextGIPA = loader_gpa_instance_internal; + PFN_vkGetInstanceProcAddr fpGIPA = loader_gpa_instance_internal; - // NOTE inst is unwrapped at this point in time - void* baseObj = (void*) inst; - void* nextObj = (void*) inst; - VkBaseLayerObject *nextInstObj; - PFN_vkGetInstanceProcAddr nextGPA = loader_gpa_instance_internal; + memcpy(&loader_create_info, pCreateInfo, sizeof(VkInstanceCreateInfo)); - if (!inst->activated_layer_list.count) { - loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj); - return 0; - } + if (inst->activated_layer_list.count > 0) { - wrappedInstance = loader_stack_alloc(sizeof(VkBaseLayerObject) - * inst->activated_layer_list.count); - if (!wrappedInstance) { - loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Instance objects for layer"); - return 0; - } + chain_info.u.pLayerInfo = NULL; + chain_info.pNext = pCreateInfo->pNext; + chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO; + chain_info.function = VK_LAYER_LINK_INFO; + loader_create_info.pNext = &chain_info; - /* Create instance chain of enabled layers */ - layer_idx = inst->activated_layer_list.count - 1; - for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) { - struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i]; - loader_platform_dl_handle lib_handle; - - /* - * Note: An extension's Get*ProcAddr should not return a function pointer for - * any extension entry points until the extension has been enabled. - * To do this requires a different behavior from Get*ProcAddr functions implemented - * in layers. - * The very first call to a layer will be it's Get*ProcAddr function requesting - * the layer's vkGet*ProcAddr. The layer should initialize its internal dispatch table - * with the wrapped object given (either Instance or Device) and return the layer's - * Get*ProcAddr function. The layer should also use this opportunity to record the - * baseObject so that it can find the correct local dispatch table on future calls. - * Subsequent calls to Get*ProcAddr, CreateInstance, CreateDevice - * will not use a wrapped object and must look up their local dispatch table from - * the given baseObject. - */ - nextInstObj = (wrappedInstance + layer_idx); - nextInstObj->pGPA = (PFN_vkGPA) nextGPA; - nextInstObj->baseObject = baseObj; - nextInstObj->nextObject = nextObj; - nextObj = (void*) nextInstObj; - - lib_handle = loader_add_layer_lib(inst, "instance", layer_prop); - if (!lib_handle) - continue; // TODO what should we do in this case - if ((nextGPA = layer_prop->functions.get_instance_proc_addr) == NULL) { - if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) { - nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr"); - layer_prop->functions.get_instance_proc_addr = nextGPA; - } else - nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa); - if (!nextGPA) { - loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name); - - /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/ - continue; + layer_instance_link_info = loader_stack_alloc(sizeof(VkLayerInstanceLink) + * inst->activated_layer_list.count); + if (!layer_instance_link_info) { + loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Instance objects for layer"); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + /* Create instance chain of enabled layers */ + for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) { + struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i]; + loader_platform_dl_handle lib_handle; + + lib_handle = loader_add_layer_lib(inst, "instance", layer_prop); + if (!lib_handle) + continue; // TODO what should we do in this case + if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) == NULL) { + if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) { + fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr"); + layer_prop->functions.get_instance_proc_addr = fpGIPA; + } else + fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa); + if (!fpGIPA) { + loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name); + + /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/ + continue; + } } + + layer_instance_link_info[activated_layers].pNext = chain_info.u.pLayerInfo; + layer_instance_link_info[activated_layers].pfnNextGetInstanceProcAddr = nextGIPA; + chain_info.u.pLayerInfo = &layer_instance_link_info[activated_layers]; + nextGIPA = fpGIPA; + + loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0, + "Insert instance layer %s (%s)", + layer_prop->info.layerName, + layer_prop->lib_name); + + activated_layers++; } + } + + PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) nextGIPA(VK_NULL_HANDLE, "vkCreateInstance"); + if (fpCreateInstance) { + VkLayerInstanceCreateInfo instance_create_info; + + instance_create_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO; + instance_create_info.function = VK_LAYER_INSTANCE_INFO; + + instance_create_info.u.instanceInfo.instance_info = inst; + instance_create_info.u.instanceInfo.pfnNextGetInstanceProcAddr= nextGIPA; - loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0, - "Insert instance layer %s (%s)", - layer_prop->info.layerName, - layer_prop->lib_name); + instance_create_info.pNext = loader_create_info.pNext; + loader_create_info.pNext = &instance_create_info; - layer_idx--; + res = fpCreateInstance(&loader_create_info, pAllocator, &inst->instance); + } else { + // Couldn't find CreateInstance function! + res = VK_ERROR_INITIALIZATION_FAILED; } - loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj); + if (res != VK_SUCCESS) { + // TODO: Need to clean up here + } else { + loader_init_instance_core_dispatch_table(inst->disp, nextGIPA, inst->instance); + } - return inst->activated_layer_list.count; + return res; } void loader_activate_instance_layer_extensions(struct loader_instance *inst, VkInstance created_inst) @@ -2948,100 +2977,164 @@ static VkResult loader_enable_device_layers( return err; } -/* - * This function terminates the device chain for CreateDevice. - * CreateDevice is a special case and so the loader call's - * the ICD's CreateDevice before creating the chain. Since - * we can't call CreateDevice twice we must terminate the - * device chain with something else. - */ -static VKAPI_ATTR VkResult VKAPI_CALL scratch_vkCreateDevice( - VkPhysicalDevice physicalDevice, - const VkDeviceCreateInfo *pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDevice *pDevice) +VkResult loader_create_device_terminator( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice) { - return VK_SUCCESS; + struct loader_physical_device *phys_dev; + phys_dev = loader_get_physical_device(physicalDevice); + + VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *) pCreateInfo->pNext; + while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO + && chain_info->function == VK_LAYER_DEVICE_INFO)) { + chain_info = (VkLayerDeviceCreateInfo *) chain_info->pNext; + } + assert(chain_info != NULL); + + struct loader_device *dev = (struct loader_device *) chain_info->u.deviceInfo.device_info; + PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.deviceInfo.pfnNextGetInstanceProcAddr; + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(phys_dev->this_icd->instance, "vkCreateDevice"); + if (fpCreateDevice == NULL) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + VkDeviceCreateInfo localCreateInfo; + memcpy(&localCreateInfo, pCreateInfo, sizeof(localCreateInfo)); + localCreateInfo.pNext = NULL; + // ICDs do not support layers + localCreateInfo.enabledLayerCount = 0; + localCreateInfo.ppEnabledLayerNames = NULL; + + VkDevice localDevice; + VkResult res = fpCreateDevice(phys_dev->phys_dev, &localCreateInfo, pAllocator, &localDevice); + + if (res != VK_SUCCESS) { + return res; + } + + *pDevice = localDevice; + + /* Init dispatch pointer in new device object */ + loader_init_dispatch(*pDevice, &dev->loader_dispatch); + + return res; } -static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_GetDeviceChainProcAddr(VkDevice device, const char * name) +VkResult loader_create_device_chain( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks* pAllocator, + struct loader_instance *inst, + struct loader_icd *icd, + struct loader_device *dev) { - if (!strcmp(name, "vkGetDeviceProcAddr")) - return (PFN_vkVoidFunction) loader_GetDeviceChainProcAddr; - if (!strcmp(name, "vkCreateDevice")) - return (PFN_vkVoidFunction) scratch_vkCreateDevice; + uint32_t activated_layers = 0; + VkLayerDeviceLink *layer_device_link_info; + VkLayerDeviceCreateInfo chain_info; + VkLayerDeviceCreateInfo device_info; + VkDeviceCreateInfo loader_create_info; + VkResult res; - struct loader_device *found_dev; - struct loader_icd *icd = loader_get_icd_and_device(device, &found_dev); - return icd->GetDeviceProcAddr(device, name); -} + PFN_vkGetDeviceProcAddr fpGDPA, nextGDPA = icd->GetDeviceProcAddr; + PFN_vkGetInstanceProcAddr fpGIPA, nextGIPA = loader_gpa_instance_internal; -static uint32_t loader_activate_device_layers( - const struct loader_instance *inst, - struct loader_device *dev, - VkDevice device) -{ - if (!dev) { - return 0; - } - - /* activate any layer libraries */ - void* nextObj = (void*) device; - void* baseObj = nextObj; - VkBaseLayerObject *nextGpuObj; - PFN_vkGetDeviceProcAddr nextGPA = loader_GetDeviceChainProcAddr; - VkBaseLayerObject *wrappedGpus; - - if (!dev->activated_layer_list.count) { - loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA, - (VkDevice) nextObj, (VkDevice) baseObj); - return 0; - } - - wrappedGpus = loader_heap_alloc(inst, - sizeof (VkBaseLayerObject) * dev->activated_layer_list.count, - VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); - if (!wrappedGpus) { - loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Gpu objects for layer"); - return 0; - } - - for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) { - - struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i]; - loader_platform_dl_handle lib_handle; - - nextGpuObj = (wrappedGpus + i); - nextGpuObj->pGPA = (PFN_vkGPA)nextGPA; - nextGpuObj->baseObject = baseObj; - nextGpuObj->nextObject = nextObj; - nextObj = (void*) nextGpuObj; - - lib_handle = loader_add_layer_lib(inst, "device", layer_prop); - if ((nextGPA = layer_prop->functions.get_device_proc_addr) == NULL) { - if (layer_prop->functions.str_gdpa == NULL || strlen(layer_prop->functions.str_gdpa) == 0) { - nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr"); - layer_prop->functions.get_device_proc_addr = nextGPA; - } else - nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa); - if (!nextGPA) { - loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->lib_name); - continue; + memcpy(&loader_create_info, pCreateInfo, sizeof(VkDeviceCreateInfo)); + + chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO; + chain_info.function = VK_LAYER_LINK_INFO; + chain_info.u.pLayerInfo = NULL; + chain_info.pNext = pCreateInfo->pNext; + + layer_device_link_info = loader_stack_alloc(sizeof(VkLayerDeviceLink) + * dev->activated_layer_list.count); + if (!layer_device_link_info) { + loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Device objects for layer"); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + /* + * This structure is used by loader_create_device_terminator + * so that it can intialize the device dispatch table pointer + * in the device object returned by the ICD. Without this + * structure the code wouldn't know where the loader's device_info + * structure is located. + */ + device_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO; + device_info.function = VK_LAYER_DEVICE_INFO; + device_info.pNext = &chain_info; + device_info.u.deviceInfo.device_info = dev; + device_info.u.deviceInfo.pfnNextGetInstanceProcAddr = icd->this_icd_lib->GetInstanceProcAddr; + + loader_create_info.pNext = &device_info; + + if (dev->activated_layer_list.count > 0) { + /* Create instance chain of enabled layers */ + for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) { + struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i]; + loader_platform_dl_handle lib_handle; + + lib_handle = loader_add_layer_lib(inst, "device", layer_prop); + if (!lib_handle) + continue; // TODO what should we do in this case + if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) == NULL) { + if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) { + fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr"); + layer_prop->functions.get_instance_proc_addr = fpGIPA; + } else + fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa); + if (!fpGIPA) { + loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name); + + /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/ + continue; + } } - } + if ((fpGDPA = layer_prop->functions.get_device_proc_addr) == NULL) { + if (layer_prop->functions.str_gdpa == NULL || strlen(layer_prop->functions.str_gdpa) == 0) { + fpGDPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr"); + layer_prop->functions.get_device_proc_addr = fpGDPA; + } else + fpGDPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa); + if (!fpGDPA) { + loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->lib_name); + + /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/ + continue; + } + } + + layer_device_link_info[activated_layers].pNext = chain_info.u.pLayerInfo; + layer_device_link_info[activated_layers].pfnNextGetInstanceProcAddr = nextGIPA; + layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr = nextGDPA; + chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers]; + nextGIPA = fpGIPA; + nextGDPA = fpGDPA; - loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0, - "Insert device layer library %s (%s)", - layer_prop->info.layerName, - layer_prop->lib_name); + loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0, + "Insert device layer %s (%s)", + layer_prop->info.layerName, + layer_prop->lib_name); + activated_layers++; + } } - loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA, - (VkDevice) nextObj, (VkDevice) baseObj); - loader_heap_free(inst, wrappedGpus); + PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) nextGIPA(VK_NULL_HANDLE, "vkCreateDevice"); + if (fpCreateDevice) { + res = fpCreateDevice(physicalDevice, &loader_create_info, pAllocator, &dev->device); + } else { + // Couldn't find CreateDevice function! + return VK_ERROR_INITIALIZATION_FAILED; + } + + /* Initialize device dispatch table */ + loader_init_device_dispatch_table(&dev->loader_dispatch, + nextGDPA, + dev->device); - return dev->activated_layer_list.count; + return res; } VkResult loader_validate_layers( @@ -3149,7 +3242,6 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateInstance( const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { - struct loader_instance *ptr_instance = *(struct loader_instance **) pInstance; struct loader_icd *icd; VkExtensionProperties *prop; char **filtered_extension_names = NULL; @@ -3157,11 +3249,22 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateInstance( VkResult res = VK_SUCCESS; bool success = false; + VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *) pCreateInfo->pNext; + while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO + && chain_info->function == VK_LAYER_INSTANCE_INFO)) { + chain_info = (VkLayerInstanceCreateInfo *) chain_info->pNext; + } + assert(chain_info != NULL); + + struct loader_instance *ptr_instance = (struct loader_instance *) chain_info->u.instanceInfo.instance_info; memcpy(&icd_create_info, pCreateInfo, sizeof(icd_create_info)); icd_create_info.enabledLayerCount = 0; icd_create_info.ppEnabledLayerNames = NULL; + // TODO: Should really strip off the VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO entries + icd_create_info.pNext = NULL; + /* * NOTE: Need to filter the extensions to only those * supported by the ICD. @@ -3233,6 +3336,8 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateInstance( } } + *pInstance = (VkInstance) ptr_instance; + return VK_SUCCESS; } @@ -3362,6 +3467,7 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_EnumeratePhysicalDevices( VkPhysicalDevice* pPhysicalDevices) { uint32_t i; + uint32_t copy_count = 0; struct loader_instance *ptr_instance = (struct loader_instance *) instance; VkResult res = VK_SUCCESS; @@ -3374,9 +3480,15 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_EnumeratePhysicalDevices( return res; } - for (i = 0; i < ptr_instance->total_gpu_count; i++) { + copy_count = (ptr_instance->total_gpu_count < *pPhysicalDeviceCount) ? ptr_instance->total_gpu_count : *pPhysicalDeviceCount; + for (i = 0; i < copy_count; i++) { pPhysicalDevices[i] = (VkPhysicalDevice) &ptr_instance->phys_devs[i]; } + *pPhysicalDeviceCount = copy_count; + + if (copy_count < ptr_instance->total_gpu_count) { + return VK_INCOMPLETE; + } return res; } @@ -3578,21 +3690,12 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice( } } - // since physicalDevice object maybe wrapped by a layer need to get unwrapped version - // we haven't yet called down the chain for the layer to unwrap the object - res = icd->CreateDevice(phys_dev->phys_dev, &device_create_info, pAllocator, pDevice); - if (res != VK_SUCCESS) { - loader_destroy_generic_list(inst, (struct loader_generic_list *) &activated_layer_list); - return res; - } - - dev = loader_add_logical_device(inst, *pDevice, &icd->logical_device_list); + dev = loader_add_logical_device(inst, &icd->logical_device_list); if (dev == NULL) { loader_destroy_generic_list(inst, (struct loader_generic_list *) &activated_layer_list); return VK_ERROR_OUT_OF_HOST_MEMORY; } - loader_init_dispatch(*pDevice, &dev->loader_dispatch); /* move the locally filled layer list into the device, and pass ownership of the memory */ dev->activated_layer_list.capacity = activated_layer_list.capacity; @@ -3600,11 +3703,20 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice( dev->activated_layer_list.list = activated_layer_list.list; memset(&activated_layer_list, 0, sizeof(activated_layer_list)); - /* activate any layers on device chain which terminates with device*/ - loader_activate_device_layers(inst, dev, *pDevice); + /* activate any layers on device chain which terminates with device*/ + res = loader_enable_device_layers(inst, icd, &dev->activated_layer_list, pCreateInfo, &inst->device_layer_list); + if (res != VK_SUCCESS) { + loader_destroy_logical_device(inst, dev); + return res; + } + + res = loader_create_device_chain(physicalDevice, pCreateInfo, pAllocator, inst, icd, dev); + if (res != VK_SUCCESS) { + loader_destroy_logical_device(inst, dev); + return res; + } - /* finally can call down the chain */ - res = dev->loader_dispatch.core_dispatch.CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); + *pDevice = dev->device; /* initialize any device extension dispatch entry's from the instance list*/ loader_init_dispatch_dev_ext(inst, dev); @@ -3614,7 +3726,6 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice( loader_init_device_extension_dispatch_table(&dev->loader_dispatch, dev->loader_dispatch.core_dispatch.GetDeviceProcAddr, *pDevice); - dev->loader_dispatch.core_dispatch.CreateDevice = icd->CreateDevice; return res; } diff --git a/loader/loader.h b/loader/loader.h index b5b3d2c9..55662b73 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -241,6 +241,8 @@ struct loader_instance { struct loader_layer_list activated_layer_list; + VkInstance instance; + bool debug_report_enabled; VkLayerDbgFunctionNode *DbgFunctionHead; @@ -425,6 +427,12 @@ VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceMemoryProperties ( VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties * pProperties); +VkResult loader_create_device_terminator( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); + VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice( VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, @@ -490,7 +498,11 @@ VkResult loader_enable_instance_layers( const VkInstanceCreateInfo *pCreateInfo, const struct loader_layer_list *instance_layers); void loader_deactivate_instance_layers(struct loader_instance *instance); -uint32_t loader_activate_instance_layers(struct loader_instance *inst); + +VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, + const VkAllocationCallbacks* pAllocator, + struct loader_instance *inst); + void loader_activate_instance_layer_extensions(struct loader_instance *inst, VkInstance created_inst); void* loader_heap_alloc( diff --git a/loader/table_ops.h b/loader/table_ops.h index 1577409c..1ddef206 100644 --- a/loader/table_ops.h +++ b/loader/table_ops.h @@ -38,17 +38,14 @@ static VkResult vkDevExtError(VkDevice dev) static inline void loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa, - VkDevice dev_next, VkDevice dev) { VkLayerDispatchTable *table = &dev_table->core_dispatch; for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++) dev_table->ext_dispatch.DevExt[i] = (PFN_vkDevExt) vkDevExtError; - // If layer is next, this will trigger layers to initialize their dispatch tables - //then use the gpa in their dispatch for subsequent layers in the chain - table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(dev_next, "vkGetDeviceProcAddr"); - table->CreateDevice = (PFN_vkCreateDevice) gpa(dev, "vkCreateDevice"); + table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(dev, "vkGetDeviceProcAddr"); +// table->CreateDevice = (PFN_vkCreateDevice) gpa(dev, "vkCreateDevice"); table->DestroyDevice = (PFN_vkDestroyDevice) gpa(dev, "vkDestroyDevice"); table->GetDeviceQueue = (PFN_vkGetDeviceQueue) gpa(dev, "vkGetDeviceQueue"); table->QueueSubmit = (PFN_vkQueueSubmit) gpa(dev, "vkQueueSubmit"); @@ -194,8 +191,8 @@ static inline void *loader_lookup_device_dispatch_table( name += 2; if (!strcmp(name, "GetDeviceProcAddr")) return (void *) table->GetDeviceProcAddr; - if (!strcmp(name, "CreateDevice")) - return (void *) table->CreateDevice; +// if (!strcmp(name, "CreateDevice")) +// return (void *) table->CreateDevice; if (!strcmp(name, "DestroyDevice")) return (void *) table->DestroyDevice; if (!strcmp(name, "GetDeviceQueue")) @@ -440,17 +437,15 @@ static inline void *loader_lookup_device_dispatch_table( return NULL; } -static inline void loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table, - PFN_vkGetInstanceProcAddr gpa, - VkInstance inst_next, - VkInstance inst) +static inline void loader_init_instance_core_dispatch_table( + VkLayerInstanceDispatchTable *table, + PFN_vkGetInstanceProcAddr gpa, + VkInstance inst) { - // If layer is next, this will trigger layers to initialize their dispatch tables - //then use the gpa in their dispatch for subsequent layers in the chain - table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(inst_next, "vkGetInstanceProcAddr"); - + table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(inst, "vkGetInstanceProcAddr"); table->CreateInstance = (PFN_vkCreateInstance) gpa(inst, "vkCreateInstance"); table->DestroyInstance = (PFN_vkDestroyInstance) gpa(inst, "vkDestroyInstance"); + table->CreateDevice = (PFN_vkCreateDevice) gpa(inst, "vkCreateDevice"); table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) gpa(inst, "vkEnumeratePhysicalDevices"); table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) gpa(inst, "vkGetPhysicalDeviceFeatures"); table->GetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) gpa(inst, "vkGetPhysicalDeviceImageFormatProperties"); @@ -510,6 +505,8 @@ static inline void *loader_lookup_instance_dispatch_table( return (void *) table->CreateInstance; if (!strcmp(name, "DestroyInstance")) return (void *) table->DestroyInstance; + if (!strcmp(name, "CreateDevice")) + return (void *) table->CreateDevice; if (!strcmp(name, "EnumeratePhysicalDevices")) return (void *) table->EnumeratePhysicalDevices; if (!strcmp(name, "GetPhysicalDeviceFeatures")) diff --git a/loader/trampoline.c b/loader/trampoline.c index 563fec60..d525158d 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -176,24 +176,28 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( loader_heap_free(ptr_instance, ptr_instance); return res; } - loader_activate_instance_layers(ptr_instance); - - wsi_create_instance(ptr_instance, pCreateInfo); - debug_report_create_instance(ptr_instance, pCreateInfo); created_instance = (VkInstance) ptr_instance; - res = ptr_instance->disp->CreateInstance(pCreateInfo, pAllocator, &created_instance); + res = loader_create_instance_chain(pCreateInfo, pAllocator, ptr_instance); if (res == VK_SUCCESS) { + wsi_create_instance(ptr_instance, pCreateInfo); + debug_report_create_instance(ptr_instance, pCreateInfo); + *pInstance = created_instance; + /* + * TODO: This can go away now? * Finally have the layers in place and everyone has seen * the CreateInstance command go by. This allows the layer's * GetInstanceProcAddr functions to return valid extension functions * if enabled. */ loader_activate_instance_layer_extensions(ptr_instance, *pInstance); + } else { + // TODO: cleanup here. } + /* Remove temporary debug_report callback */ util_DestroyDebugReportCallback(ptr_instance, instance_callback, pAllocator); diff --git a/vk-generate.py b/vk-generate.py index bed56645..7b1b0f70 100755 --- a/vk-generate.py +++ b/vk-generate.py @@ -116,41 +116,34 @@ class DispatchTableOpsSubcommand(Subcommand): func = [] if type == "device": # GPA has to be first one and uses wrapped object - stmts.append("VkDevice device = (VkDevice) devw->nextObject;") - stmts.append("PFN_vkGetDeviceProcAddr gpa = (PFN_vkGetDeviceProcAddr) devw->pGPA;") - stmts.append("VkDevice baseDevice = (VkDevice) devw->baseObject;") - stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init") stmts.append("memset(table, 0, sizeof(*table));") stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr) gpa(device,\"vkGetDeviceProcAddr\");") for proto in self.protos: - if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or (proto.params[0].ty == "VkPhysicalDevice" and proto.name != "CreateDevice"): + if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice": continue if proto.name != "GetDeviceProcAddr" and 'KHR' not in proto.name: - stmts.append("table->%s = (PFN_vk%s) gpa(baseDevice, \"vk%s\");" % + stmts.append("table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" % (proto.name, proto.name, proto.name)) - func.append("static inline void %s_initialize_dispatch_table(VkLayerDispatchTable *table," + func.append("static inline void %s_init_device_dispatch_table(VkDevice device," % self.prefix) - func.append("%s const VkBaseLayerObject *devw)" + func.append("%s VkLayerDispatchTable *table," + % (" " * len(self.prefix))) + func.append("%s PFN_vkGetDeviceProcAddr gpa)" % (" " * len(self.prefix))) else: - # GPA has to be first one and uses wrapped object - stmts.append("VkInstance instance = (VkInstance) instw->nextObject;") - stmts.append("PFN_vkGetInstanceProcAddr gpa = (PFN_vkGetInstanceProcAddr) instw->pGPA;") - stmts.append("VkInstance baseInstance = (VkInstance) instw->baseObject;") - stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init") stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr) gpa(instance,\"vkGetInstanceProcAddr\");") for proto in self.protos: - if proto.name != "CreateInstance" and proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice": + if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice": continue if proto.name == "CreateDevice": continue if proto.name != "GetInstanceProcAddr" and 'KHR' not in proto.name: - stmts.append("table->%s = (PFN_vk%s) gpa(baseInstance, \"vk%s\");" % + stmts.append("table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" % (proto.name, proto.name, proto.name)) - func.append("static inline void %s_init_instance_dispatch_table(VkLayerInstanceDispatchTable *table," - % self.prefix) - func.append("%s const VkBaseLayerObject *instw)" - % (" " * len(self.prefix))) + func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix) + func.append("%s VkInstance instance," % (" " * len(self.prefix))) + func.append("%s VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix))) + func.append("%s PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix))) func.append("{") func.append(" %s" % "\n ".join(stmts)) func.append("}") diff --git a/vk-layer-generate.py b/vk-layer-generate.py index f8518ee0..d2435968 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -473,6 +473,8 @@ class Subcommand(object): if not proto in intercepted: continue + if proto.name == "CreateInstance": + continue if proto.name == "CreateDevice": continue lookups.append("if (!strcmp(name, \"%s\"))" % proto.name) @@ -508,17 +510,15 @@ class Subcommand(object): func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n" "{\n" " PFN_vkVoidFunction addr;\n" - " if (device == VK_NULL_HANDLE) {\n" - " return NULL;\n" - " }\n" - " /* loader uses this to force layer initialization; device object is wrapped */\n" " if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n" - " initDeviceTable(%s_device_table_map, (const VkBaseLayerObject *) device);\n" " return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n" " }\n\n" " addr = layer_intercept_proc(funcName);\n" " if (addr)\n" - " return addr;" % self.layer_name) + " return addr;\n" + " if (device == VK_NULL_HANDLE) {\n" + " return NULL;\n" + " }\n") if 0 != len(extensions): func_body.append('%s' % self.lineinfo.get()) func_body.append(' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);') @@ -539,18 +539,20 @@ class Subcommand(object): func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)\n" "{\n" " PFN_vkVoidFunction addr;\n" - " if (instance == VK_NULL_HANDLE) {\n" - " return NULL;\n" - " }\n" - " /* loader uses this to force layer initialization; instance object is wrapped */\n" - " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n" - " initInstanceTable(%s_instance_table_map, (const VkBaseLayerObject *) instance);\n" + " if (!strcmp(funcName, \"vkGetInstanceProcAddr\"))\n" " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n" - " }\n\n" + " if (!strcmp(funcName, \"vkCreateInstance\"))\n" + " return (PFN_vkVoidFunction) vkCreateInstance;\n" + " if (!strcmp(funcName, \"vkCreateDevice\"))\n" + " return (PFN_vkVoidFunction) vkCreateDevice;\n" " addr = layer_intercept_instance_proc(funcName);\n" " if (addr) {\n" " return addr;" - " }\n" % self.layer_name) + " }\n" + " if (instance == VK_NULL_HANDLE) {\n" + " return NULL;\n" + " }\n" + ) table_declared = False if 0 != len(instance_extensions): @@ -590,15 +592,10 @@ class Subcommand(object): func_body.append('%s' % self.lineinfo.get()) func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n" "{\n" - " PFN_vkVoidFunction addr;\n" - " if (device == VK_NULL_HANDLE) {\n" - " return NULL;\n" - " }\n") + " PFN_vkVoidFunction addr;\n") if self.layer_name == 'generic': func_body.append("\n" - " /* loader uses this to force layer initialization; device object is wrapped */\n" " if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n" - " initDeviceTable((const VkBaseLayerObject *) device);\n" " return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n" " }\n\n" " addr = layer_intercept_proc(funcName);\n" @@ -607,14 +604,15 @@ class Subcommand(object): else: func_body.append("\n" " loader_platform_thread_once(&initOnce, init%s);\n\n" - " /* loader uses this to force layer initialization; device object is wrapped */\n" " if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n" - " initDeviceTable((const VkBaseLayerObject *) device);\n" " return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n" " }\n\n" " addr = layer_intercept_proc(funcName);\n" " if (addr)\n" " return addr;" % self.layer_name) + func_body.append(" if (device == VK_NULL_HANDLE) {\n" + " return NULL;\n" + " }\n") func_body.append('') func_body.append(' VkLayerDispatchTable *pDisp = device_dispatch_table(device);') if 0 != len(extensions): @@ -640,32 +638,29 @@ class Subcommand(object): func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)\n" "{\n" " PFN_vkVoidFunction addr;\n" - " if (instance == VK_NULL_HANDLE) {\n" - " return NULL;\n" - " }\n") + " if (!strcmp(funcName, \"vkGetInstanceProcAddr\"))\n" + " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n" + " if (!strcmp(funcName, \"vkCreateInstance\"))\n" + " return (PFN_vkVoidFunction) vkCreateInstance;\n" + " if (!strcmp(funcName, \"vkCreateDevice\"))\n" + " return (PFN_vkVoidFunction) vkCreateDevice;\n" + ) if self.layer_name == 'generic': func_body.append("\n" - " /* loader uses this to force layer initialization; instance object is wrapped */\n" - " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n" - " initInstanceTable((const VkBaseLayerObject *) instance);\n" - " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n" - " }\n\n" " addr = layer_intercept_instance_proc(funcName);\n" " if (addr)\n" " return addr;") else: func_body.append( " loader_platform_thread_once(&initOnce, init%s);\n\n" - " /* loader uses this to force layer initialization; instance object is wrapped */\n" - " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n" - " initInstanceTable((const VkBaseLayerObject *) instance);\n" - " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n" - " }\n\n" " addr = layer_intercept_instance_proc(funcName);\n" " if (addr)\n" " return addr;" % self.layer_name) + func_body.append(" if (instance == VK_NULL_HANDLE) {\n" + " return NULL;\n" + " }\n") func_body.append("") - func_body.append(" VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);") + func_body.append(" VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);\n") if 0 != len(instance_extensions): extra_space = "" for (ext_enable, ext_list) in instance_extensions: @@ -837,20 +832,32 @@ class GenericLayerSubcommand(Subcommand): funcs.append('%s' % self.lineinfo.get()) funcs.append('%s%s\n' '{\n' + ' layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n' ' char str[1024];\n' - ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n' ' sprintf(str, "At start of Generic layered %s\\n");\n' - ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,' + ' log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,' ' (uint64_t)physicalDevice, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n' - ' %sdevice_dispatch_table(*pDevice)->%s;\n' - ' if (result == VK_SUCCESS) {\n' - ' my_data->report_data = layer_debug_report_create_device(my_data->report_data, *pDevice);\n' - ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n' + ' VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n' + ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n' + ' PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;\n' + ' PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");\n' + ' if (fpCreateDevice == NULL) {\n' + ' return VK_ERROR_INITIALIZATION_FAILED;\n' ' }\n' + ' // Advance the link info for the next element on the chain\n' + ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n' + ' VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);\n' + ' if (result != VK_SUCCESS) {\n' + ' return result;\n' + ' }\n' + ' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n' + ' initDeviceTable(*pDevice, fpGetDeviceProcAddr);\n' + ' my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n' + ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n' ' sprintf(str, "Completed generic layered %s\\n");\n' - ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, (uint64_t)physicalDevice, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n' + ' log_msg(my_device_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, (uint64_t)physicalDevice, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n' ' %s' - '}' % (qual, decl, proto.name, ret_val, proto.c_call(), proto.name, stmt)) + '}' % (qual, decl, proto.name, proto.name, stmt)) elif proto.name == "DestroyDevice": funcs.append('%s' % self.lineinfo.get()) funcs.append('%s%s\n' @@ -884,21 +891,31 @@ class GenericLayerSubcommand(Subcommand): funcs.append('%s%s\n' '{\n' ' char str[1024];\n' - ' %sinstance_dispatch_table(*pInstance)->%s;\n' - ' if (result == VK_SUCCESS) {\n' - ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n' - ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n' - ' my_data->report_data = debug_report_create_instance(\n' - ' instance_dispatch_table(*pInstance),\n' - ' *pInstance,\n' - ' pCreateInfo->enabledExtensionCount,\n' - ' pCreateInfo->ppEnabledExtensionNames);\n' - ' init_generic(my_data, pAllocator);\n' - ' sprintf(str, "Completed generic layered %s\\n");\n' - ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)*pInstance, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n' + ' VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n' + ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n' + ' PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");\n' + ' if (fpCreateInstance == NULL) {\n' + ' return VK_ERROR_INITIALIZATION_FAILED;\n' + ' }\n' + ' // Advance the link info for the next element on the chain\n' + ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n' + ' VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);\n' + ' if (result != VK_SUCCESS) {\n' + ' return result;\n' ' }\n' + ' VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr);\n' + ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n' + ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n' + ' my_data->report_data = debug_report_create_instance(\n' + ' pTable,\n' + ' *pInstance,\n' + ' pCreateInfo->enabledExtensionCount,\n' + ' pCreateInfo->ppEnabledExtensionNames);\n' + ' init_generic(my_data, pAllocator);\n' + ' sprintf(str, "Completed generic layered %s\\n");\n' + ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)*pInstance, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n' ' return result;\n' - '}\n' % (qual, decl, ret_val, proto.c_call(), proto.name)) + '}\n' % (qual, decl, proto.name)) else: if wsi_name(proto.name): funcs.append('%s' % wsi_ifdef(proto.name)) @@ -1248,25 +1265,34 @@ class APIDumpSubcommand(Subcommand): funcs.append('%s%s\n' '{\n' ' using namespace StreamControl;\n' - ' %sinstance_dispatch_table(*pInstance)->%s;\n' - ' if (result == VK_SUCCESS) {\n' - ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n' + ' loader_platform_thread_once(&initOnce, initapi_dump);\n' + ' VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n' + ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n' + ' PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");\n' + ' if (fpCreateInstance == NULL) {\n' + ' return VK_ERROR_INITIALIZATION_FAILED;\n' ' }\n' + ' // Advance the link info for the next element on the chain\n' + ' assert(chain_info->u.pLayerInfo);\n' + ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n' + ' VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);\n' + ' if (result != VK_SUCCESS)\n' + ' return result;\n' + ' initInstanceTable(*pInstance, fpGetInstanceProcAddr);\n' + ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n' ' %s%s%s\n' '%s' - '}\n' % (qual, decl, ret_val, proto.c_call(), f_open, log_func, f_close, stmt)) + '}\n' % (qual, decl, f_open, log_func, f_close, stmt)) elif proto.name == "CreateDevice": funcs.append('%s\n' % self.lineinfo.get()) funcs.append('%s%s\n' '{\n' ' using namespace StreamControl;\n' - ' %sdevice_dispatch_table(*pDevice)->%s;\n' - ' if (result == VK_SUCCESS)\n' - ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n' + ' %sexplicit_CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);\n' ' %s%s%s\n' '%s' - '}' % (qual, decl, ret_val, proto.c_call(), f_open, log_func, f_close, stmt)) + '}' % (qual, decl, ret_val, f_open, log_func, f_close, stmt)) elif proto.name == "DestroyDevice": funcs.append('%s%s\n' '{\n' @@ -2408,16 +2434,25 @@ class ThreadingSubcommand(Subcommand): funcs.append('%s' % self.lineinfo.get()) funcs.append('%s%s\n' % (qual, decl) + '{\n' - ' VkLayerDispatchTable *pDeviceTable = get_dispatch_table(threading_device_table_map, (void *) *pDevice);\n' - ' VkResult result = pDeviceTable->%s;\n' % (proto.c_call()) + - ' if (result == VK_SUCCESS) {\n' - ' layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(%s), layer_data_map);\n' % proto.params[0].name + - ' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n' - ' my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n' + ' VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n' + ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n' + ' PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;\n' + ' PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");\n' + ' if (fpCreateDevice == NULL) {\n' + ' return VK_ERROR_INITIALIZATION_FAILED;\n' ' }\n' - '\n' - ' return result;' - '}') + ' // Advance the link info for the next element on the chain\n' + ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n' + ' VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);\n' + ' if (result != VK_SUCCESS) {\n' + ' return result;\n' + ' }\n' + ' layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n' + ' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n' + ' initDeviceTable(*pDevice, fpGetDeviceProcAddr, threading_device_table_map);\n' + ' my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n' + ' return result;\n' + '}\n') return "\n".join(funcs) elif proto.params[0].ty == "VkPhysicalDevice": return None @@ -2473,18 +2508,26 @@ class ThreadingSubcommand(Subcommand): elif proto.name == "CreateInstance": funcs.append('%s%s\n' '{\n' - ' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(threading_instance_table_map, *pInstance);\n' - ' VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);\n' - '\n' - ' if (result == VK_SUCCESS) {\n' - ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n' - ' my_data->report_data = debug_report_create_instance(\n' - ' pInstanceTable,\n' - ' *pInstance,\n' - ' pCreateInfo->enabledExtensionCount,\n' - ' pCreateInfo->ppEnabledExtensionNames);\n' - ' init_threading(my_data, pAllocator);\n' + ' VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n' + ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n' + ' PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");\n' + ' if (fpCreateInstance == NULL) {\n' + ' return VK_ERROR_INITIALIZATION_FAILED;\n' + ' }\n' + ' // Advance the link info for the next element on the chain\n' + ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n' + ' VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);\n' + ' if (result != VK_SUCCESS) {\n' + ' return result;\n' ' }\n' + ' VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, threading_instance_table_map);\n' + ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n' + ' my_data->report_data = debug_report_create_instance(\n' + ' pTable,\n' + ' *pInstance,\n' + ' pCreateInfo->enabledExtensionCount,\n' + ' pCreateInfo->ppEnabledExtensionNames);\n' + ' init_threading(my_data, pAllocator);\n' ' return result;\n' '}\n' % (qual, decl)) return "\n".join(funcs); |
