Vulkan 开发(十一):Vulkan 交换链

Vulkan 教程(1)开篇 Vulkan 系列教程 阅读详情

Vulkan 系列文章:

1. 开篇,Vulkan 概述

2. Vulkan 实例

3. Vulkan 物理设备

4. Vulkan 设备队列

5. Vulkan 逻辑设备

6. Vulkan 内存管理

7. Vulkan 缓存

8. Vulkan 图像

9. Vulkan 图像视图

10. Vulkan 窗口表面(Surface)


什么是交换链

图片

FIFO 呈现模式的交换链

Vulkan 交换链(Swapchain)是 Vulkan 应用程序与窗口系统之间的一座桥梁,负责将渲染结果呈现给用户。

换个说法,交换链是一种图元绘制结果呈现的机制,它可以将绘制结果渲染到平台相关的展示窗口/展示层当中。

交换链包含一组图像(一般作为渲染目标),这些图像被用于在屏幕上显示渲染的帧。

交换链中的图像个数与驱动层的实现是密切相关的。如果交换链中有两幅图像,那么称为双缓存,如果有三幅图像,那么称作三缓存。

在这些图像中,如果有一幅图像在后台已经完成了绘制过程,那么它会被交换到前台的展示窗口。

为了充分利用GPU的性能,此时另一幅图像会交换作为后台的缓存来执行下一帧的绘制过程。

这个过程往复执行,图像的交换过程也就持续进行。使用多幅图像可以保持GPU始终处于渲染某一帧图像的忙碌状态,从而降低总体的等待时间,改善输出帧速率。

交换链的作用

  1. 图像管理: 交换链维护了一组用于显示的图像,称为交换链图像(Swapchain Images)。交换链图像通常至少有两个,这样就可以实现双缓冲或多缓冲,从而避免屏幕闪烁。

  2. 同步: 管理 CPU 和 GPU 之间的同步,确保渲染操作不会在显示更新之前完成,这有助于防止撕裂(tearing)现象,即在同一帧内看到两个不同图像的一部分。

  3. 图像呈现:

  • 应用程序首先在一个缓冲区上进行渲染,完成渲染后,该缓冲区会被提交给交换链,然后交换链会将这个缓冲区的内容显示到屏幕上。

  • 当一个缓冲区正在显示时,另一个缓冲区可以用于下一轮的渲染,这样就形成了一个循环。

创建交换链

创建交换链之前,我们需要利用上一节创建的 VkSurfaceKHR  对象来获取创建交换链所需的尺寸、格式、颜色空间等信息。

 1VkSurfaceKHR surface;
 2
 3//获取表面的特性
 4VkSurfaceCapabilitiesKHR surfaceCapabilities;
 5vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface,
 6                                        &surfaceCapabilities);
 7uint32_t formatCount = 0;
 8vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
 9                                   &formatCount, nullptr);
10
11//获取表面所支持的格式
12VkSurfaceFormatKHR* formats = new VkSurfaceFormatKHR[formatCount];
13vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
14                                   &formatCount, formats);

获取上述信息之后,我们来填充 VkSwapchainCreateInfoKHR 结构体。

创建交换链的函数 vkCreateSwapchainKHR :

1VkResult vkCreateSwapchainKHR(
2    VkDevice                        device,                  // Vulkan 设备句柄
3    const VkSwapchainCreateInfoKHR* pCreateInfo,             // 指向 VkSwapchainCreateInfoKHR 结构体的指针,描述交换链的创建参数
4    const VkAllocationCallbacks*    pAllocator,              // 自定义的内存分配器回调函数指针,可以为 NULL 表示使用默认分配器
5    VkSwapchainKHR*                 pSwapchain               // 指向 VkSwapchainKHR 句柄的指针,函数成功返回时,包含创建的交换链
6)
7

VkSwapchainCreateInfoKHR 是一个用于描述交换链创建信息的结构体。它包含了创建交换链所需的所有参数,如表面、图像数量、格式、分辨率等。

以下是 VkSwapchainCreateInfoKHR 结构体的定义:

 1typedef struct VkSwapchainCreateInfoKHR {
 2VkStructureType                  sType;              // 必须是 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR
 3const void*                      pNext;              // 指向扩展结构的指针,通常为 nullptr
 4VkSwapchainCreateFlagsKHR        flags;              // 交换链创建标志,当前版本 Vulkan 中未使用,设置为 0
 5VkSurfaceKHR                     surface;            // 渲染表面(窗口或显示设备)
 6uint32_t                         minImageCount;      // 交换链中图像的最小数量
 7VkFormat                         imageFormat;        // 交换链图像的格式(颜色格式)
 8VkColorSpaceKHR                  imageColorSpace;    // 交换链图像的颜色空间
 9VkExtent2D                       imageExtent;        // 交换链图像的宽度和高度
10uint32_t                         imageArrayLayers;   // 交换链图像的数组层数(通常为 1)
11VkImageUsageFlags                imageUsage;         // 交换链图像的用途标志(如颜色附件)
12VkSharingMode                    imageSharingMode;   // 图像共享模式(独占模式或并发模式)
13uint32_t                         queueFamilyIndexCount; // 队列家族索引数量(imageSharingMode 为 VK_SHARING_MODE_CONCURRENT 时使用)
14const uint32_t*                  pQueueFamilyIndices;  // 指向队列家族索引数组的指针(imageSharingMode 为 VK_SHARING_MODE_CONCURRENT 时使用)
15VkSurfaceTransformFlagBitsKHR    preTransform;       // 表面变换(如旋转或翻转)
16VkCompositeAlphaFlagBitsKHR      compositeAlpha;     // 复合 Alpha 混合模式
17VkPresentModeKHR                 presentMode;        // 交换链的呈现模式(如 FIFO、Mailbox 等)
18VkBool32                         clipped;            // 指定剪裁窗口外的像素(VK_TRUE 为剪裁)
19VkSwapchainKHR                   oldSwapchain;       // 旧的交换链(用于重新创建交换链时),否则为 VK_NULL_HANDLE
20} VkSwapchainCreateInfoKHR;

VkSwapchainCreateInfoKHR结构体的属性看起来很多,实际上绝大部分情况下都是固定写死的,所以只需要简单了解下即可。

其中 VkColorSpaceKHR 、VkImageUsageFlags、VkSurfaceTransformFlagBitsKHR、VkPresentModeKHR 这个几个稍微关注下。

VkColorSpaceKHR

VkColorSpaceKHR 定义了交换链图像的颜色空间。

颜色空间表示图像数据如何转换为颜色信息,以在显示设备上正确显示,处理 HDR 图像的时候需要重点关注。

 1typedef enum VkColorSpaceKHR {
 2    VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,                // sRGB 颜色空间,带非线性伽马校正。常用于标准显示器。
 3    VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, // Display-P3 色域,带非线性伽马校正。用于支持 P3 色域显示器。
 4    VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002, // 扩展 sRGB 颜色空间,线性校正。
 5    VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT = 1000104003,    // Display-P3 色域,线性校正。
 6    VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004,     // DCI-P3 色域,带非线性伽马校正。
 7    VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005,         // BT.709 颜色空间,线性校正。
 8    VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006,      // BT.709 颜色空间,非线性校正。
 9    VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007,        // BT.2020 颜色空间,线性校正。
10    VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008,         // HDR10,使用 SMPTE ST 2084 EOTF。
11    VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009,          // Dolby Vision。
12    VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010,            // HDR10,使用 Hybrid Log-Gamma。
13    VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011,      // Adobe RGB 颜色空间,线性校正。
14    VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012,   // Adobe RGB 颜色空间,非线性校正。
15    VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013,         // 颜色空间通过,不做任何校正。
16    VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, // 扩展 sRGB 颜色空间,非线性校正。
17    VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000,       // 原生显示颜色空间,AMD 扩展。
18    // 更多颜色空间可以通过扩展添加
19} VkColorSpaceKHR;

VkImageUsageFlags

VkImageUsageFlags 表示图像的用途标志,例如 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT 表示图像将用作颜色附件。

可以组合多个用途标志,以表明图像的多种使用方式。

 1typedef enum VkImageUsageFlagBits {
 2    VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001,                     // 图像可以作为传输操作的源。
 3    VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002,                     // 图像可以作为传输操作的目标。
 4    VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004,                          // 图像可以被采样器访问。
 5    VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008,                          // 图像可以作为存储图像使用。
 6    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010,                 // 图像可以作为颜色附件使用。
 7    VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,         // 图像可以作为深度/模板附件使用。
 8    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,             // 图像内容是暂时的,并不会在帧之间保留。
 9    VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,                 // 图像可以作为输入附件使用。
10    VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100,            // 图像可以作为着色率图像使用(NVIDIA 扩展)。
11    VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200,         // 图像可以作为片段密度图使用(EXT 扩展)。
12    VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR =         // 图像可以作为片段着色率附件使用(KHR 扩展)。
13        VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV,
14    VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF                    // 枚举类型的最大值。
15} VkImageUsageFlagBits;

VkSurfaceTransformFlagBitsKHR

VkSurfaceTransformFlagBitsKHR 枚举类型定义了交换链图像在显示之前可以应用的变换操作。

 1typedef enum VkSurfaceTransformFlagBitsKHR {
 2    VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001,                    // 不进行任何变换。
 3    VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002,                   // 顺时针旋转 90 度。
 4    VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004,                  // 顺时针旋转 180 度。
 5    VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008,                  // 顺时针旋转 270 度。
 6    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010,           // 水平翻转。
 7    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, // 水平翻转后顺时针旋转 90 度。
 8    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040,// 水平翻转后顺时针旋转 180 度。
 9    VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080,// 水平翻转后顺时针旋转 270 度。
10    VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100                      // 继承当前变换。
11} VkSurfaceTransformFlagBitsKHR;

VkPresentModeKHR

VkPresentModeKHR 枚举类型定义了交换链的呈现模式。呈现模式决定了图像交换和显示的策略。

1typedef enum VkPresentModeKHR {
2    VK_PRESENT_MODE_IMMEDIATE_KHR = 0,           // 图像立即提交到显示设备,可能导致撕裂。
3    VK_PRESENT_MODE_MAILBOX_KHR = 1,             // 使用邮箱模式,提交图像时如果显示队列满了,会覆盖旧的图像。
4    VK_PRESENT_MODE_FIFO_KHR = 2,                // 先进先出模式,提交的图像进入队列,显示设备按顺序显示。
5    VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3,        // 类似于 FIFO 模式,但如果显示设备空闲,立即显示图像,减少延迟。
6    VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, // 共享刷新模式,在显示设备需要时刷新。
7    VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001 // 持续刷新模式,持续刷新图像。
8} VkPresentModeKHR;

创建交换链、获取交换链图像示例

 1VkSurfaceKHR surface;//上一节获取的表面
 2
 3// 获取表面的特性
 4VkSurfaceCapabilitiesKHR surfaceCapabilities;
 5vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfaceCapabilities);
 6
 7uint32_t formatCount = 0;
 8vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, nullptr);
 9
10// 获取表面所支持的格式
11VkSurfaceFormatKHR* formats = new VkSurfaceFormatKHR[formatCount];
12vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, formats);
13
14// 查找 VK_FORMAT_R8G8B8A8_UNORM 格式
15uint32_t targetFormatIdx;
16for (targetFormatIdx = 0; targetFormatIdx < formatCount; targetFormatIdx++) {
17    if (formats[targetFormatIdx].format == VK_FORMAT_R8G8B8A8_UNORM) break;
18}
19assert(targetFormatIdx < formatCount); // 确保找到目标格式
20
21VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
22swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; // 设置结构体类型
23swapchainCreateInfo.surface = surface; // 设置表面句柄
24swapchainCreateInfo.minImageCount = surfaceCapabilities.minImageCount; // 最小图像数量(修正:minImageCoun 改为 minImageCount)
25swapchainCreateInfo.imageFormat = formats[targetFormatIdx].format; // 图像格式
26swapchainCreateInfo.imageColorSpace = formats[targetFormatIdx].colorSpace; // 颜色空间
27swapchainCreateInfo.imageExtent = surfaceCapabilities.currentExtent; // 图像范围
28swapchainCreateInfo.imageArrayLayers = 1; // 图像数组层数
29swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; // 图像用途
30swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; // 图像共享模式
31swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; // 表面变换
32swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; // 复合 alpha 模式
33swapchainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; // 显示模式
34swapchainCreateInfo.clipped = VK_FALSE; // 是否剪辑
35swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE; // 旧交换链句柄
36
37VkSwapchainKHR swapchain;
38VkResult result = vkCreateSwapchainKHR(device, &swapchainCreateInfo, nullptr, &swapchain); // 创建交换链
39if (result != VK_SUCCESS) {
40    // 错误处理
41}
42
43// 获取交换链中的图像
44uint32_t imageCount;
45vkGetSwapchainImagesKHR(device, swapchain, &imageCount, nullptr);
46std::vector<VkImage> swapChainImages(imageCount);
47vkGetSwapchainImagesKHR(device, swapchain, &imageCount, swapChainImages.data());
48
49// 为每个交换链图像创建图像视图,这些图像视图将会作为帧缓冲区的 attachments
50std::vector<VkImageView> swapChainImageViews(swapChainImages.size());
51for (size_t i = 0; i < swapChainImages.size(); i++) {
52    VkImageViewCreateInfo createInfo = {};
53    createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; // 设置结构体类型
54    createInfo.image = swapChainImages[i]; // 图像句柄
55    createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; // 视图类型
56    createInfo.format = formats[targetFormatIdx].format; // 图像格式
57    createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; // 组件重映射
58    createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
59    createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
60    createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
61    createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; // 子资源范围
62    createInfo.subresourceRange.baseMipLevel = 0;
63    createInfo.subresourceRange.levelCount = 1;
64    createInfo.subresourceRange.baseArrayLayer = 0;
65    createInfo.subresourceRange.layerCount = 1;
66
67    if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
68        throw std::runtime_error("failed to create image views!"); // 错误处理
69    }
70}
71
72// 销毁交换链、释放资源
73for (size_t i = 0; i < swapChainImages.size(); i++) {
74    vkDestroyImageView(device, swapChainImageViews[i], nullptr); // 销毁图像视图
75}
76vkDestroySwapchainKHR(device, swapchain, nullptr); // 销毁交换链
77delete[] formats; // 释放格式数组内存

参考

《Vulkan学习指南》 — [新加坡] 帕敏德·辛格(Parminder Singh)
https://www.intel.com/content/www/us/en/developer/articles/training/api-without-secrets-introduction-to-vulkan-part-2.html

技术交流

进技术交流群/获取源码,添加我的微信:Byte-Flow

 

Vulkan与OpenGL对比——Vulkan的全新渲染架构 OpenGL是KhronosGroup组织发布的跨平台图像渲染引擎。在这里科普一下Khronos组织,由Intel、Nvidia等公司共同创立,致力于创建开放标准的应用程序API。大名鼎鼎的OpenGL、OpenGLES、WebGL、Vulkan都是来自Khronos。而vulkan称为“下一版本的OpenGL”,旨在提供更低的CPU开销和更多GPU控制。AndroidAPI24以后支持vulkan,iOS在WWDC2014也推出Metal图像渲染。本文主要探讨Vulkan的全新渲染架构。... 阅读详情

相关推荐

Vulkan教程(10): Swap chain(交换链)

Vulkan swap chain 教程

vily_lei的专栏 2102

Vulkan教程 - 01 环境搭建

根据工作需要,开始学习Vulkan了。由于以前没有太接触图形的知识,感觉Vulkan学习任重道远啊。毕竟是很底层,很核心的技术,而且要用C或者C++,难是肯定的。就像之前学习shader,感到涉及了很多东西。那些光照和贴图等各种不同设置,分别能实现什么样的效果,看着就很高深了。没办法,雄关漫道真如铁,而今迈步从头越。 先从这个教程看: https://vulkan-tutorial.com/ ...

捉不住的鼬鼠的足迹 1万+

Vulkan进阶系列6 - 创建交换链(完整代码)

Vulkan 的设计目标是:最大程度减少驱动对开发者行为的“猜测和干预”,把一切都交给开发者来决定。所以Vulkan没有默认帧缓冲区,需要我们自己创建交换链(swapchain);Vulkan 中的 swapchain 是一组图像缓冲区(images),这些图像按顺序被绘制并最终显示到屏幕上。当我们使用 Vulkan 渲染时,不是直接画到屏幕上,而是画到这些 swapchain image 上,然后再“交换”到前台去显示。

GPU全栈博主 439

Vulkan 简介

序言 Vulkan 的设计理念 开放性 和 轻量化 Vulkan 将 “绘制物体” 描述成为多个不同缓存和多组不同的流水线之间的关联和组合。 Vulkan 将实现引擎在底层接口兼容性测试和调试工作部分转移到了算法封装和框架设计上。 vulkan 的介绍 概念 术语 ,与 openGL 的不同点 vulkan 的原始概念由AMD 的 Mantle API 设计和实现的, AMD将 Mantle 的源码贡献给 khronos 组织, 而后 khronos 组织发布了vulkan。..

fatcat123的博客 1万+

数字IC后端实战:如何用ICC搞定复杂模块的floorplan与powerplan(附避坑指南)

本文深入解析数字IC后端设计中复杂模块的floorplan与powerplan实战技巧,重点介绍多边形模块边界处理、MTCMOS电源网络优化及存储器摆放陷阱规避。通过Synopsys ICC工具的具体操作示例和项目实战经验,帮助工程师高效解决设计难题,提升芯片性能与可靠性。

weixin_29213525的博客 350

2025红队实战:Win11环境下ZAP、CobaltStrike与免杀套件深度评测

在网络安全领域,渗透测试与红队行动是评估系统防御能力的关键手段。其核心原理在于模拟真实攻击者的技术与流程,以发现潜在的安全漏洞。这项技术的价值在于主动识别风险,提升整体安全防护水平,广泛应用于企业安全评估、漏洞挖掘和攻防演练等场景。随着Windows 11系统普及,其增强的安全机制(如内存完整性、基于虚拟化的安全)对传统攻击工具链提出了新的挑战。本文聚焦于**CobaltStrike二开版**与**免杀套件**在Win11环境下的实战应用与深度对抗,探讨如何优化工具链以应对现代端点检测与响应(EDR)和高级

weixin_29315091的博客 308

Vulkan 交换链详解

大家好,接下来将为大家介绍Vulkan 交换链详解。 在这一章节,我们了解一下将渲染图像提交到屏幕的基本机制。这种机制称为交换链,并且需要在Vulkan上下文中被明确创建。从屏幕的角度观察,交换链本质上是一个图像队列。应用程序作为生产者会获取图像进行绘制,然后将其返还给交换链图像队列,等待屏幕消费。交换链的具体配置信息决定了应用程序提交绘制图像到队列的条件以及图像队列表现的效果,但交换链的通常使...

sy_liao的专栏 3414

【TCAX相关】Python 官方手册下载页面(中文+英文)

Python 官方手册下载页面(中文+英文) 中文: https://docs.python.org/zh-cn/3.8/archives/ https://docs.python.org/zh-cn/3.6/archives/ 英文: https://www.python.org/doc/versions/ https://docs.python.org/3/archives/ https://www.python.org/ftp/python/doc/ ...

Seekladoom的博客 1012

Vulkan教程 - 06 交换链

Swap chain(交换链) 现在到了Vulkan教程第十章了,学习交换链。Vulkan没有默认帧缓冲的概念,因此它需要一个基础设施,能够在我们通过屏幕看到内容之前,持有我们想要渲染的东西的缓冲。该基础设施就是交换链了,必须显式创建。交换链本质上是一个图像队列,等待显示到屏幕上。我们的应用将会获取这样的一个图片来向其进行绘制,然后将它返回给队列。队列究竟怎么工作的,以及从队列中呈现一个图像的条...

捉不住的鼬鼠的足迹 2483

手把手教你用Silvaco Atlas复现GaN蓝光LED仿真:从网格划分到光谱分析全流程避坑

本文详细介绍了如何使用Silvaco Atlas进行GaN蓝光LED仿真,从网格划分到光谱分析的全流程避坑指南。重点讲解了网格划分技巧、材料参数设置、极化效应处理以及结果分析方法,帮助用户快速掌握半导体器件仿真技术,提升研发效率。

weixin_42552716的博客 223

【Flutter 问题系列第 85 篇】Xcode 运行 Flutter 提示 The Dart VM Service was not discovered after 60 seconds.

在 Xcode 上运行 Flutter 时提示 `The Dart VM Service was not discovered after 60 seconds. This is taking much longer than expected...`,意思是 `60秒后未发现Dart虚拟机服务。这比预期的要长得多`

“Allen Su”的博客 2235

Vulkan填坑学习Day06—交换链

Vulkan 交换链 Vulkan 交换链,在这一章节,我们了解一下将渲染图像提交到屏幕的基本机制。这种机制称为交换链,并且需要在Vulkan上下文中被明确创建。从屏幕的角度观察,交换链本质上是一个图像队列。应用程序作为生产者会获取图像进行绘制,然后将其返还给交换链图像队列,等待屏幕消费。交换链的具体配置信息决定了应用程序提交绘制图像到队列的条件以及图像队列表现的效果,但交换链的通常使用目的是使绘...

qq_35312463的博客 1510

Android 13 RK3588 编译烧写实录全程

本文详细记录了RK3588主板在Android 13系统下的各项功能测试与编译过程。主要内容包括:1)网络功能测试(以太网、WiFi、蓝牙连接);2)外设接口测试(耳机、麦克风、USB、TF卡);3)硬件功能验证(RTC时钟、ADC采样、MIPI摄像头);4)系统设置(手势导航、开发者选项);5)Android 13 SDK编译环境搭建与源码获取方法。通过图文并茂的方式展示了各功能的配置方法、操作步骤和测试结果,为开发者提供了全面的参考指南。

hnjzfwy的博客 238

交换链创建全攻略:解决Vulkan图像呈现的核心难题

想要在Vulkan中实现高效的图形渲染和流畅的图像呈现吗?🔥 交换链(Swap Chain)是Vulkan图像呈现系统的核心组件,它负责管理渲染目标队列,确保图形渲染与屏幕显示的无缝衔接。本文将为您提供完整的Vulkan交换链创建指南,帮助您掌握这一关键技术,解决图像呈现的核心难题!🚀 在Vulkan图形编程中,交换链是一个必不可少的组件。与OpenGL不同,Vulkan没有默认的帧缓冲概念

gitblog_00473的博客 901

RK3568适配MIPI屏幕触摸,触摸延时很大

我用的是系统,接了一个,设备树已经正确配置,evtest测试坐标值和触摸位置都是准确的。但是出现了一个:我在屏幕上点一下,要等大约 2 秒才能在evtest里看到坐标事件打印。这种现象在 Goodix 系列触摸驱动里比较少见,一般意味着。

小灰灰的博客 1363

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Vulkan教程 - 13 重建交换链

现在我们的程序能成功绘制三角形了,但是还有一些情况,它还不能很好地处理。窗口表面可能会改变,导致交换链与其不兼容。这种事情发生的可能原因之一是窗口的大小改变了。我们要能抓取这些事件,然后重建交换链。 创建一个recreateSwapChain方法,它会调用createSwapChain以及为依赖交换链或者窗口大小的对象调用所有创建方法。 void recreateSwapChain() { ...

捉不住的鼬鼠的足迹 1664

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

教程 12 - Vulkan 逻辑设备和交换链

在上一篇教程中,我们成功创建了 Vulkan 表面并选择了合适的物理设备。从选定的物理设备创建逻辑设备获取设备队列句柄理解交换链(Swapchain)的概念和作用创建和配置 Vulkan 交换链管理交换链图像和深度附件实现交换链的重建机制// 物理设备// 逻辑设备// 交换链支持信息// 队列族索引// 队列句柄// 设备属性// 深度格式// 图像句柄// 图像内存// 图像视图u32 width;// 宽度u32 height;

feiduoge的博客 1024

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Vulkan入门(四)-Surface和交换链.md

文章目录参考资料简述一. Window Surface1.1 创建窗口Surface二. Swap Chain-交换链2.1 检查GPU是否支持交换链2.2 使能设备扩展2.3 获取关于swap chain更多支持细节2.4 为swap chain-交换链选择合适的设置2.4.1 Surface格式2.4.2 呈现模式(Presentation Mode)2.4.3 交换范围(Swap exten...

SwallowJoe的博客 2557

【Vulkan 入门系列】创建交换链、图像视图和渲染通道(四)

Vulkan 没有“默认帧缓冲”的概念,因此它需要一个基础设施来拥有我们将要渲染的缓冲,然后我们才能在屏幕上可视化它们。这个基础设施被称为交换链,必须在 Vulkan 中显式创建。交换链本质上是一个等待呈现到屏幕的图像队列。我们的应用程序将获取这样的图像来绘制它,然后将其返回到队列。队列的确切工作方式以及从队列中呈现图像的条件取决于交换链的设置方式,但交换链的总体目的是将图像的呈现与屏幕的刷新率同步。

洪伟的专栏 1990

Vulkan填坑学习Day17—重建交换链

Vulkan 重建交换链 我们已经成功地编写代码使用 Vulkan 在屏幕上绘制出了一个三角形,但这个程序还有许多细节问题我们没有处理。比如,窗口大小改变会导致交换链和窗口不再适配,我们需要重新对交换链进行处理。 一、重新创建交换链 添加新的函数recreateSwapChain并调用createSwapChain及依赖于交换链或者窗体大小的对象相关的所有创建函数。 void recreateSw...

qq_35312463的博客 908

Flutter Impeller 引擎 Vulkan Swapchain 详解:面向多平台 WSI 的交换链实现

本文以 Flutter 引擎中 Impeller 渲染器的 Vulkan 后端为对象,深入讲解其交换链(Swapchain)实现——这是 Impeller 在 Vulkan 上完成窗口系统集成(WSI,Window System Integration)的核心模块。文章围绕 [swapchain 目录](https://link.gitcode.com/i/3372b02d53dd9c31f8a1

gitblog_00421的博客 864

[译]Vulkan教程(20)重建交换链

[译]Vulkan教程(20)重建交换链 Swap chain recreation 重建交换链 Introduction 入门 The application we have now successfully draws a triangle, but there are some circumstances that it isn't handling properly yet. It ...

weixin_30888027的博客 380

[译]Vulkan教程(10)交换链

[译]Vulkan教程(10)交换链 Vulkan does not have the concept of a "default framebuffer", hence it requires an infrastructure that will own the buffers we will render to before we visualize them on the scre...

weixin_30802273的博客 550

Vulkan入门(10)-重建交换链.md

文章目录参考资料简述一. 重建交换链1.1 cleanupSwapChain1.2 获取窗口最新大小1.3 次优或过时的交换链1.3.1 fence1.3.2 vkQueuePresentKHR1.4 主动处理窗口变化1.4.1 监听窗口变化1.5 窗口最小化 参考资料 简述 在上一篇里,我们已经成功绘制了一个颜色渐变的三角形,并将其显示在窗口上了。但是窗口Surface可能会发生变化,从而使交换链不再与之兼容,比如是窗口大小的变化。所以我们必须捕获这些事件并重新创建交换链。 一. 重建交换链 创建一个新的

SwallowJoe的博客 1134

没有任何秘密的 API: Vulkan* 简介第 2 部分: 交换链

教程 2: 交换链 — 集成 Vulkan 和操作系统欢迎观看第 2 节 Vulkan 教程。 在第 1 节教程中,我们介绍了 Vulkan 基本设置:功能加载、实例创建、选择物理设备和队列,以及逻辑设备创建。 现在您一定希望绘制一些图像! 很遗憾,我们需要等到下一节。 为什么? 因为如果我们绘图,肯定希望能够看见它。 与 OpenGL* 类似,我们必须将 Vulkan 管道与操作系统提供的应用和...

intel_news的博客 615
上一篇: Vulkan 开发(十):Vulkan 窗口表面(Surface)
下一篇: 简历怎么写?这些问题不可忽视(附简历模版)
字节流动
字节流动 优质创作者: 编程框架技术领域 优质创作者: 编程框架技术领域 领域专家: 嵌入式与硬件开发技术领域 领域专家: 嵌入式与硬件开发技术领域
博客等级 码龄11年 1912粉丝 168原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

字节流动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值