diff --git a/loader/loader.c b/loader/loader.c index 507ec217..d82e269e 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -5214,7 +5214,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkLayerCreateDevice(VkInstance instance, VkPhysic assert(pCreateInfo->queueCreateInfoCount >= 1); - { + if(instance != NULL) { + inst = loader_get_instance(instance); + internal_device = physicalDevice; + } else { struct loader_physical_device_tramp *phys_dev = (struct loader_physical_device_tramp *)physicalDevice; internal_device = phys_dev->phys_dev; inst = (struct loader_instance *)phys_dev->this_instance; @@ -5229,7 +5232,13 @@ VKAPI_ATTR VkResult VKAPI_CALL vkLayerCreateDevice(VkInstance instance, VkPhysic goto out; } - res = loader_add_device_extensions(inst, inst->disp->layer_inst_disp.EnumerateDeviceExtensionProperties, internal_device, + PFN_vkEnumerateDeviceExtensionProperties enumDeviceExtensionProperties = NULL; + if(layerGIPA != NULL) { + enumDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) layerGIPA(instance, "vkEnumerateDeviceExtensionProperties"); + } else { + enumDeviceExtensionProperties = inst->disp->layer_inst_disp.EnumerateDeviceExtensionProperties; + } + res = loader_add_device_extensions(inst, enumDeviceExtensionProperties, internal_device, "Unknown", &icd_exts); if (res != VK_SUCCESS) { loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice: Failed to add extensions to list"); @@ -5291,7 +5300,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkLayerCreateDevice(VkInstance instance, VkPhysic dev->expanded_activated_layer_list.list = NULL; } - res = loader_create_device_chain(internal_device, pCreateInfo, pAllocator, inst, dev); + res = loader_create_device_chain(internal_device, pCreateInfo, pAllocator, inst, dev, layerGIPA, nextGDPA); if (res != VK_SUCCESS) { loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice: Failed to create device chain."); goto out; @@ -5322,7 +5331,23 @@ out: return res; } +VKAPI_ATTR void VKAPI_CALL vkLayerDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction){ + struct loader_device *dev; + if (device == VK_NULL_HANDLE) { + return; + } + + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, NULL); + const struct loader_instance *inst = icd_term->this_instance; + + destroyFunction(device, pAllocator); + dev->chain_device = NULL; + dev->icd_device = NULL; + loader_remove_logical_device(inst, icd_term, dev, pAllocator); +} + + // Given the list of layers to activate in the loader_instance // structure. This function will add a VkLayerInstanceCreateInfo // structure to the VkInstanceCreateInfo.pNext pointer. @@ -5480,7 +5505,19 @@ VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, c create_info_disp.pNext = loader_create_info.pNext; loader_create_info.pNext = &create_info_disp; - res = fpCreateInstance(&loader_create_info, pAllocator, created_instance); + + VkLayerInstanceCreateInfo create_info_disp2; + + create_info_disp2.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO; + create_info_disp2.function = VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK; + + create_info_disp2.u.layerDevice.pfnLayerCreateDevice = vkLayerCreateDevice; + create_info_disp2.u.layerDevice.pfnLayerDestroyDevice = vkLayerDestroyDevice; + + create_info_disp2.pNext = loader_create_info.pNext; + loader_create_info.pNext = &create_info_disp2; + + res = fpCreateInstance(&loader_create_info, pAllocator, created_instance); } else { loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_create_instance_chain: Failed to find " @@ -5504,7 +5541,7 @@ void loaderActivateInstanceLayerExtensions(struct loader_instance *inst, VkInsta VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, const struct loader_instance *inst, - struct loader_device *dev) { + struct loader_device *dev, PFN_vkGetInstanceProcAddr callingLayer, PFN_vkGetDeviceProcAddr *layerNextGDPA) { uint32_t activated_layers = 0; VkLayerDeviceLink *layer_device_link_info; VkLayerDeviceCreateInfo chain_info; @@ -5574,13 +5611,15 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre chain_info.pNext = loader_create_info.pNext; loader_create_info.pNext = &chain_info; + bool done = false; + // Create instance chain of enabled layers for (int32_t i = dev->expanded_activated_layer_list.count - 1; i >= 0; i--) { struct loader_layer_properties *layer_prop = &dev->expanded_activated_layer_list.list[i]; loader_platform_dl_handle lib_handle; lib_handle = loaderOpenLayerFile(inst, "device", layer_prop); - if (!lib_handle) { + if (!lib_handle || done) { continue; } @@ -5602,7 +5641,16 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre continue; } } - if ((fpGDPA = layer_prop->functions.get_device_proc_addr) == NULL) { + + if(fpGIPA == callingLayer){ + if(layerNextGDPA != NULL){ + *layerNextGDPA = nextGDPA; + } + done = true; + continue; + } + + if ((fpGDPA = layer_prop->functions.get_device_proc_addr) == NULL) { if (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; diff --git a/loader/loader.h b/loader/loader.h index 2a1a0ee1..af69800b 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -510,7 +510,7 @@ VkResult vkLayerCreateDevice(VkInstance instance, VkPhysicalDevice physicalDevic VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, const struct loader_instance *inst, - struct loader_device *dev); + struct loader_device *dev, PFN_vkGetInstanceProcAddr callingLayer, PFN_vkGetDeviceProcAddr *layerNextGDPA); VkResult loader_validate_device_extensions(struct loader_instance *this_instance, const struct loader_layer_list *activated_device_layers,