Vlukan基础教程 - 05.逻辑设备
作者:Sun zi chao     发布时间:2022-05-01 08:00:00    阅读次数:49
本系列文章介绍Vlukan编程。Vlukan是一个跨平台的2D和3D绘图应用程序接口(API),是OpenGL的“继任者”。学习本教程的同学需要有GLFW以及C++的编程经验。有OpenGL或DirectX经验更好。

我们不能直接对物理设备进行操作,必须给物理设备创建相应的逻辑设备。这就有点像我们的硬盘,你必须通过逻辑盘符对其操作一样。

这节有两个步骤:一个是创建物理设备中支持图形绘制的队列。二是创建物理设备。

1.创建队列的数据结构

	struct QueueFamilyIndices {
    std::optional<uint32_t> graphicsFamily;

    bool isComplete() {
        return graphicsFamily.has_value();
    }
};

2.检索支持图形绘制的队列函数

	//查找物理设备中支持图形工作的队列
    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.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                indices.graphicsFamily = i;
            }

            //如果队列是完整有效的,则返回该队列
            if (indices.isComplete()) {
                break;
            }

            i++;
        }

        return indices;
    }

3.创建逻辑设备函数

	//创建逻辑设备
    void createLogicalDevice() {
        QueueFamilyIndices indices = findQueueFamilies(physicalDevice);

        VkDeviceQueueCreateInfo queueCreateInfo{};
        queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
        queueCreateInfo.queueCount = 1;

        //设置队列使用优先级别
        float queuePriority = 1.0f;
        queueCreateInfo.pQueuePriorities = &queuePriority;

        VkPhysicalDeviceFeatures deviceFeatures{};

        VkDeviceCreateInfo createInfo{};
        createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;

        createInfo.pQueueCreateInfos = &queueCreateInfo;
        createInfo.queueCreateInfoCount = 1;

        createInfo.pEnabledFeatures = &deviceFeatures;

        createInfo.enabledExtensionCount = 0;

        if (enableValidationLayers) {
            createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
            createInfo.ppEnabledLayerNames = validationLayers.data();
        } else {
            createInfo.enabledLayerCount = 0;
        }

        //创建逻辑设备
        if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
            throw std::runtime_error("failed to create logical device!");
        }

        //创建逻辑设备的图形队列
        vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);

    }

4.initVulkan()和cleanup()函数修改

	void initVulkan() {
        createInstance();
        setupDebugMessenger();
        pickPhysicalDevice();
        createLogicalDevice();
    }
	
	void cleanup() {

        vkDestroyDevice(device, nullptr);

        if (enableValidationLayers && !checkValidationLayerSupport()) {
            throw std::runtime_error("validation layers requested, but not available!");
        }

        vkDestroyInstance(instance, nullptr);

        glfwDestroyWindow(window);

        glfwTerminate();
    }

运行结果和上节一样。只要不报错就可以了。


桂ICP备11003301号-1 公安备案号:45040302000027 Copyright @ 2021- 2022 By Sun zi chao

阅读统计: 1.93W 文章数量: 76 运行天数: 416天 返回cmnsoft