大学生网页设计心得体会百度关键词优化曝光行者seo
前言
在 VulkanSceneGraph(VSG)中,vsg::Window 类对窗口进行了高层次的封装,为开发者提供了便捷的窗口管理接口。在上一篇文章中,我们探讨了 VkInstance、VkSurfaceKHR、VkPhysicalDevice 和 VkDevice 的创建过程,以及它们在 VSG 中的封装方式及其相互关系。本章将继续深入探讨与窗口创建密切相关的另一个核心对象——交换链 VkSwapchainKHR,并分析其与上述四个 Vulkan 对象之间的关系,同时探讨 VSG 如何对 VkSwapchainKHR 进行封装。
目录
- 1 VkSwapchainKHR的创建
- 2 vsg中对VkSwapchainKHR的封装
1 VkSwapchainKHR的创建
在Vulkan中,Swapchain是用于管理图像的核心机制,它允许应用程序将渲染结果展示到屏幕上。Swapchain本质上是一个图像队列,包含多个图像缓冲区(也可称为"交换图像"),应用程序将内容渲染到这些图像中,然后将其提交给显示设备进行呈现。VkSwapchainKHR与VkSurfaceKHR、VkPhysicalDevice联系紧密,VkSwapchainKHR的创建依赖于VkSurfaceKHR,在创建VkSwapchainKHR前必须确保VkSurfaceKHR已经创建,并且物理设备VkPhysicalDevice支持此VkSurfaceKHR。
VkSwapchainKHR包含查询表面支持、选择表面格式和呈现模式、Swapchain的创建与销毁三个步骤。
1.1 查询表面支持
VkSurfaceCapabilitiesKHR caps;VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(app.getPhysicalDevice(), app.getSurface(), &caps);if (result != VK_SUCCESS){printf("Failed to get surface capabilities.\n");return 1;}
通过vkGetPhysicalDeviceSurfaceCapabilitiesKHR查询物理设备对表面的支持能力,从中可获取最小最大图象数、图像最大分辨率,代码如下:
caps.maxImageExtent.width;//最大分辨率//宽度
caps.maxImageExtent.height;//最大分辨率//高度
caps.minImageCount;//最小影像数
caps.maxImageCount;//最打影像数
1.2 选择表面格式和呈现模式
uint32_t formatCount = 0, presentModeCount = 0;result = vkGetPhysicalDeviceSurfaceFormatsKHR(app.getPhysicalDevice(), app.getSurface(), &formatCount, nullptr);if (result != VK_SUCCESS || formatCount == 0){return 1;}result = vkGetPhysicalDeviceSurfacePresentModesKHR(app.getPhysicalDevice(), app.getSurface(), &presentModeCount, nullptr);if (result != VK_SUCCESS || presentModeCount == 0){return 1;}uint32_t formatIndex = 0, presentModeIndex = 0;std::vector<VkSurfaceFormatKHR> formats(formatCount);std::vector<VkPresentModeKHR> presentModes(presentModeCount);vkGetPhysicalDeviceSurfaceFormatsKHR(app.getPhysicalDevice(), app.getSurface(), &formatCount, formats.data());for (uint32_t i = 0; i < formatCount; ++i){if (formats[i].format == VK_FORMAT_B8G8R8A8_SRGB &&formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) formatIndex = i;}vkGetPhysicalDeviceSurfacePresentModesKHR(app.getPhysicalDevice(), app.getSurface(), &presentModeCount, presentModes.data());for (uint32_t i = 0; i < presentModeCount; ++i){if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) presentModeIndex = i;}
通过vkGetPhysicalDeviceSurfaceFormatsKHR获取表面格式,以上代码中vkGetPhysicalDeviceSurfaceFormatsKHR共调用两次,第一次第四个参数传入nullptr,可获取表面格式的个数,第二次调用可获取所有表面模式。同时通过vkGetPhysicalDeviceSurfacePresentModesKHR获取呈现模式,函数共调用两次,第一次第四个参数传入nullptr,可获取呈现模式的个数,第二次调用可获取所有呈现模式。
1.3 Swapchain的创建与销毁
VkSwapchainCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,nullptr, 0,app.getSurface(),std::max(caps.minImageCount + caps.maxImageCount),VK_FORMAT_B8G8R8A8_SRGB,VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,caps.maxImageExtent,1, // imageArrayLayersVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,VK_SHARING_MODE_EXCLUSIVE, 0, nullptr,caps.currentTransform,VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,VK_PRESENT_MODE_MAILBOX_KHR,VK_TRUE,nullptr};VkSwapchainKHR swapChain = nullptr;result = vkCreateSwapchainKHR(app.getDevice(), &createInfo, nullptr, &swapChain);if (result != VK_SUCCESS){printf("Failed to create swap chain.\n");return 1;}uint32_t imageCount = 0;vkGetSwapchainImagesKHR(app.getDevice(), swapChain, &imageCount, nullptr);std::vector<VkImage> swapChainImages(imageCount);vkGetSwapchainImagesKHR(app.getDevice(), swapChain, &imageCount, swapChainImages.data());if (swapChain != nullptr) {vkDestroySwapchainKHR(app.getDevice(), swapChain, nullptr);}
在 Vulkan 中,交换链(VkSwapchainKHR)通过 vkCreateSwapchainKHR 函数创建,可配置表面格式为 VK_FORMAT_B8G8R8A8_SRGB、颜色空间为 VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,并选择呈现模式为 VK_PRESENT_MODE_MAILBOX_KHR。创建后,使用 vkGetSwapchainImagesKHR 查询交换链的图像缓冲区,并通过 vkDestroySwapchainKHR 销毁交换链以释放资源。
2 vsg中对VkSwapchainKHR的封装
在 VulkanSceneGraph (VSG) 中,VkSwapchainKHR 的功能被封装在 vsg::Swapchain 类中,该类提供了对 Vulkan 交换链的高层次抽象,简化了交换链的创建、管理和使用。本章主要深入探讨vsg中交换链的创建过程,并与上篇文章提及的vsg::WindowTraits关联,暂时不深入其它如图像缓冲区管理、动态重建支持等功能,这些留待后续剖析。
auto windowTraits = vsg::WindowTraits::create();
windowTraits->width = 800;
windowTraits->height = 600;
windowTraits->swapchainPreferences.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;auto window = vsg::Window::create(windowTraits);
if (!window) {std::cerr << "Failed to create window and swapchain." << std::endl;return -1;
}
通过vsg::WindowTraits创建窗口的属性,窗口的宽和长分别设置为800和600。传入创建vsg::Window对象,在windows系统下创建vsg::Win32_Window,在vsg::Win32_Window对象
if (_swapchain){// make sure all operations on the device have stopped before we go on deleting associated resourcesvkDeviceWaitIdle(*_device);// clean up previous swap chain before we begin creating a new one._frames.clear();_indices.clear();_depthImageView.reset();_depthImage.reset();_multisampleImage.reset();_multisampleImageView.reset();}// is width and height even required here as the surface appears to control it?_swapchain = Swapchain::create(_physicalDevice, _device, _surface, _extent2D.width, _extent2D.height, _traits->swapchainPreferences, _swapchain);// pass back the extents used by the swap chain._extent2D = _swapchain->getExtent();
vsg::Swapchain的创建传入宽高参数_extent2D.width和_extent2D.height,而变量_extent2D的初始化在vsg::Win32_Window对象的构造函数中由传入的vsg::WindowTraits对象经过一系列的转换得到。
文末:本章在上一篇文章的基础上,继续深入探讨与窗口创建密切相关的另一个核心对象——交换链 VkSwapchainKHR,并分析其与 Vulkan 核心对象之间的关系。具体而言,VkSwapchainKHR 的创建依赖于 VkSurfaceKHR,并且在创建交换链之前,必须确保 VkSurfaceKHR 已经成功创建,同时物理设备 VkPhysicalDevice 支持该表面。本章内容分为两部分:交换链的创建与销毁 和 VSG 对 VkSwapchainKHR 的封装。至此,关于 vsg::Window 创建的介绍告一段落,下一章将接着探讨 vsg::Camera 的创建与赋值过程。