QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) { QueueFamilyIndices indices; uint32_t queueFamilyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); int i = 0; for (const auto& queueFamily : queueFamilies) { if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { indices.graphicsFamily = i; } VkBool32 presentSupport = false; vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); if (queueFamily.queueCount > 0 && presentSupport) { indices.presentFamily = i; } if (indices.isComplete()) { break; } i++; } return indices; }
static uint32_t getComputeQueueFamilyIndex() { uint32_t queueFamilyCount; vkGetPhysicalDeviceQueueFamilyProperties(kPhysicalDevice, &queueFamilyCount, NULL); std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(kPhysicalDevice, &queueFamilyCount, queueFamilies.data()); uint32_t i = 0; for (; i < queueFamilies.size(); ++i) { VkQueueFamilyProperties props = queueFamilies[i]; if (props.queueCount > 0 && (props.queueFlags & VK_QUEUE_COMPUTE_BIT)) { break; } } if (i == queueFamilies.size()) { throw std::runtime_error("could not find a queue family that supports operations"); } return i; }
bool select_device(std::vector<VkPhysicalDevice> &devices, VkPhysicalDevice &chosen_device) { bool suitable_dev_found = false; unsigned int best_score = 0; for (const auto& device : devices) { unsigned int score = 0; VkPhysicalDeviceProperties deviceProperties; VkPhysicalDeviceFeatures deviceFeatures; vkGetPhysicalDeviceProperties(device, &deviceProperties); vkGetPhysicalDeviceFeatures(device, &deviceFeatures); if(deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU){score+= 1000;} if(!deviceFeatures.geometryShader){score-= 1000000;} uint32_t queueFamilyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); /*checks that all the needed queue families are supported */ bool graphics_found = false, present_found = false; int i = 0; for(const auto& queueFamily : queueFamilies) { if (!graphics_found && queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { graphics_found = true; graphics_queue_family_index = i; } VkBool32 presentSupport = false; vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); if (!present_found && queueFamily.queueCount > 0 && presentSupport) { present_found = true; present_queue_family_index = i; } if(present_found && graphics_found){break;}//if it finds both there is no point in keeping looking for queue families i++; } if(!(graphics_found && present_found)){continue;}//if it didn't find both cues go to next device /*checking for device specific extnsions support*/ uint32_t extensionCount; vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); std::vector<VkExtensionProperties> availableExtensions(extensionCount); vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); std::set<std::string> requiredExtensions(device_extensions.begin(), device_extensions.end()); for (const auto& extension : availableExtensions) { requiredExtensions.erase(extension.extensionName); } if(!requiredExtensions.empty()){continue;} /*checks that swap chains are supported*/ bool swapChainAdequate = false; SwapChainSupportDetails swapChainSupport = query_swap_chain_support(device); swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty(); if(score >= best_score) { chosen_device = device; suitable_dev_found = true; best_score = score; } if(!swapChainAdequate){continue;} } return suitable_dev_found; //if no device is found }