VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { instance_layer_data *my_instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map); 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(my_instance_data->instance, "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); my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); // Setup layer's device dispatch table layer_init_device_dispatch_table(*pDevice, &my_device_data->dispatch_table, fpGetDeviceProcAddr); DeviceExtensionWhitelist(pCreateInfo, *pDevice); // Set gpu for this device in order to get at any objects mapped at instance level my_device_data->instance_data = my_instance_data; return result; }
VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map); 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(my_instance_data->instance, "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); my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); 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 = 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; }
VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map) { VkLayerDispatchTable *pTable; dispatch_key key = get_dispatch_key(device); device_table_map::const_iterator it = map.find((void *)key); if (it == map.end()) { pTable = new VkLayerDispatchTable; map[(void *)key] = pTable; } else { return it->second; } layer_init_device_dispatch_table(device, pTable, gpa); return pTable; }
VkLayerDispatchTable *initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map) { VkLayerDispatchTable *pTable; dispatch_key key = get_dispatch_key(device); device_table_map::const_iterator it = map.find((void *)key); if (it == map.end()) { pTable = new VkLayerDispatchTable; map[(void *)key] = pTable; #if DISPATCH_MAP_DEBUG fprintf(stderr, "New, Device: map: 0x%p, key: 0x%p, table: 0x%p\n", &map, key, pTable); #endif } else { #if DISPATCH_MAP_DEBUG fprintf(stderr, "Device: map: 0x%p, key: 0x%p, table: 0x%p\n", &map, key, it->second); #endif return it->second; } layer_init_device_dispatch_table(device, pTable, gpa); return pTable; }
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { bool skipCall = false; layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map); // First check is app has actually requested queueFamilyProperties if (!phy_dev_data->physicalDeviceState) { skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices()."); } else if (QUERY_DETAILS != phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) { // TODO: This is not called out as an invalid use in the spec so make more informative recommendation. skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties()."); } else { // Check that the requested queue properties are valid for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { uint32_t requestedIndex = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex; if (phy_dev_data->queueFamilyProperties.size() <= requestedIndex) { // requested index is out of bounds for this physical device skipCall |= log_msg( phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL", "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex); } else if (pCreateInfo->pQueueCreateInfos[i].queueCount > phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount) { skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL", "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but " "requested queueCount is %u.", requestedIndex, phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount, pCreateInfo->pQueueCreateInfos[i].queueCount); } } } // Check that any requested features are available if (pCreateInfo->pEnabledFeatures) { phy_dev_data->requestedPhysicalDeviceFeatures = *(pCreateInfo->pEnabledFeatures); skipCall |= validate_features_request(phy_dev_data); } if (skipCall) return VK_ERROR_VALIDATION_FAILED_EXT; 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); 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(phy_dev_data->report_data, *pDevice); my_device_data->physicalDevice = gpu; // Get physical device properties for this device phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->physicalDeviceProperties)); return result; }