VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(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; } layer_data *my_device_data = GetLayerDataPtr(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); // store the loader callback for initializing created dispatchable objects chain_info = get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK); if (chain_info) { my_device_data->pfn_dev_init = chain_info->u.pfnSetDeviceLoaderData; } else { my_device_data->pfn_dev_init = NULL; } uint32_t queue_family_count; layer_data *my_data = GetLayerDataPtr(get_dispatch_key(gpu), layer_data_map); my_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, NULL); VkQueueFamilyProperties *queue_props = (VkQueueFamilyProperties *)malloc(queue_family_count * sizeof(VkQueueFamilyProperties)); if (queue_props == NULL) { return VK_ERROR_INITIALIZATION_FAILED; } my_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, queue_props); my_device_data->graphicsQueueFamilyIndex = 0; for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { if (queue_props[pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) { my_device_data->graphicsQueueFamilyIndex = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex; break; } } free(queue_props); after_device_create(gpu, *pDevice, my_device_data); return result; }
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(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; } 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); after_device_create(gpu, *pDevice, my_device_data); return result; }