From a1de4b2dffb98222ca59f4a70c301d22bb4c089e Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Fri, 8 Jan 2016 12:18:43 -0700 Subject: loader: implement new layer init method New layer init method requires the construction of Link information for CreateInstance and CreateDevice that is accessible to layers via the CreateInfo.pNext pointer. The layer can then use the Get*ProcAddr from the Link structure to initialize their dispatch table if the call down the chain returns successfully. This removes the need to do special initialization work at Get*ProcAddr time. Layer Get*ProcAddr now return their internal function pointers regardless of the value of instance or device. Only need to have valid instance & device when looking up extensions or when passing the request down the chain. This mechanism allows us to remove object wrapping used by the loader previously. Also simplifies the dispatch table setup. Conflicts: layers/device_limits.cpp layers/draw_state.cpp loader/loader.c loader/trampoline.c --- layers/swapchain.cpp | 179 +++++++++++++++++++++++---------------------------- 1 file changed, 80 insertions(+), 99 deletions(-) (limited to 'layers/swapchain.cpp') 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(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); -- cgit v1.2.3