bool checkDeviceExtensionSupport(VkPhysicalDevice device) {
        uint32_t extensionCount;
        vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);

        std::vector<VkExtensionProperties> availableExtensions(extensionCount);
        vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());

        std::set<std::string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());

        for (const auto& extension : availableExtensions) {
            requiredExtensions.erase(extension.extensionName);
        }

        return requiredExtensions.empty();
    }
Пример #2
0
			bool Device::Create()
			{
				// Application info structure
				VkApplicationInfo appInfo = {};
				appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
				appInfo.pApplicationName = "Shard Application";
				appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
				appInfo.pEngineName = "Shard Engine";
				appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
				appInfo.apiVersion = VK_API_VERSION_1_0;

				// Instance info structure
				VkInstanceCreateInfo createInfo = {};
				createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
				createInfo.pApplicationInfo = &appInfo;

				// Load validation layers
				const std::vector<const char*> validationLayers =
				{
					"VK_LAYER_LUNARG_standard_validation"
				};
				const bool enableValidationLayers = true;	// TODO: only in debug

				if (enableValidationLayers)
				{
					uint32 layerCount = 0;
					vkEnumerateInstanceLayerProperties(&layerCount, NULL);
					std::vector<VkLayerProperties> availableLayers(layerCount);
					vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());

					for (const char* layerName : validationLayers)
					{
						bool layerFound = false;
						for (const auto& layerProp : availableLayers)
						{
							if (std::strcmp(layerName, layerProp.layerName) == 0)
							{
								layerFound = true;
								break;
							}
						}

						if (!layerFound)
						{
							Debugging::Logger::d() << "Could not find VK validation layer: " << layerName << std::endl;
							return false;
						}
					}

					// Write layers in create info
					createInfo.enabledLayerCount = validationLayers.size();
					createInfo.ppEnabledLayerNames = validationLayers.data();
				}
				else
				{
					// No layers are enabled
					createInfo.enabledLayerCount = 0;
				}

				// Load extensions
				std::vector<const char*> extensionsNeeded =
				{
					VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME
				};
				if (enableValidationLayers)
				{
					extensionsNeeded.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
				}

				uint32 extensionCount = 0;
				vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL);
				std::vector<VkExtensionProperties> availableExtensions(extensionCount);
				vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, availableExtensions.data());
				for (const char* extName : extensionsNeeded)
				{
					bool extFound = false;
					for (const auto& extProp : availableExtensions)
					{
						if (std::strcmp(extName, extProp.extensionName) == 0)
						{
							extFound = true;
							break;
						}
					}

					if (!extFound)
					{
						Debugging::Logger::d() << "Could not find VK extension: " << extName << std::endl;
						return false;
					}
				}

				// Write extensions in create info
				createInfo.enabledExtensionCount = extensionsNeeded.size();
				createInfo.ppEnabledExtensionNames = extensionsNeeded.data();

				// Create the instance
				VkInstance instance;
				if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
				{
					Debugging::Logger::d() << "Could not create VK device" << std::endl;
					return false;
				}

				return true;
			}
Пример #3
-27
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
}