Vulkan 绘制显示设计

2023-11-19

背景

众所周知,Vulkan是个跨平台的图形渲染API,为了友好地支持跨平台,Vulkan自然也抽象出了很多接口层去对接各个操作系统,抹平系统间的差异,Swap Chains即为WSI。

其本质上是一种图像队列,此队列会按顺序依次将队列中的若干图形显示在屏幕上。我们的应用程序需要获得这个队列中的图像,并在此图像中执行绘制操作,绘制完毕以后,将它重新放置到原来的队列中,类似Android的Graphic Buffer Queue。

swap chain 的常规作用是保障图形显示与幕刷新率同步。

Swap Chain Support

Vulkan支持的平台众多,也不是所有的平台都具备将(渲染出来的)图像直接显示在屏幕上的功能,有些以计算为目的应用是不需要把绘制的结果呈现给用户。所以显示相关的API并不是Vulkan核心API的一部分,而是通过扩展(extensions)的方式提供。

因此在查询到当前运行环境对 swap chain 的支持情况之后,你需要明确启用 VK_KHR_swapchain 所代表的设备扩展功能。注意,Vulkan头文件中提供了宏定义 VK_KHR_SWAPCHAIN_EXTENSION_NAME ,它定义了 VK_KHR_swapchain(一种swap chain的实现)。使用这个宏定义的优势在于,编译或(编辑)过程中编译器可以直接检查出拼写错误(如果直接使用字符串 "VK_KHR_swapchain" 则无法让编译器去检查拼写错误)。

Enabling device extensions

启动一个swap chain对象首先要启用 VK_KHR_swapchain 扩展。需要在设备创建过程中开启:

Querying details of swap chain support

前面我们检测了当前设备是否支持swap chain,但由于设备对Vulkan支持的碎片化导致了我们还需要更多的检查才能保证正常的绘制显示。有三种基础属性,我们需要检查:

  • 基本的对象能力(swap chain 中图像数量的最大最小值,图像宽或高的最大最小值)
  • 表面格式(像素数据格式,色彩空间)

  • 显示模式

每个属性都有各自的特点,今天重点分析下显示模式这一方面,其他的后续有机会再详说。

显示模式

显示模式是 swap chain 功能中最核心的特性,也是设计swap chain的初衷,因为它直接关系到图像如何送显。

在OpenGL中当完成对缓冲区的渲染后,需要使用前缓冲区切换图像,可以将渲染好的图像显示在计算机屏幕上。我们只能决定是否在空白间隔显示图像(在启用了垂直同步的情况下)。

在Vulkan中我们不会受限于只能渲染一幅图像(存储在后备缓冲区中的),而且也不会受限于只能在两种显示模式(启用或禁用垂直同步)中进行选择。我们可以在多种显示模式中进行选择,但我们需要在创建交换链的过程中设定该显示模式。

在Vulcan中获取所需场景的显示模式流程如下:

  1. 调用vkEnumeratePhysicalDevices()函数获取物理句柄
  2. 获取已创建的显示曲面,将该显示曲面的句柄存储在一个VkSurfaceKHR类型的变量中

  3. 创建一个VkPresentModeKHR类型的变量,将其命名为desired_present_mode。将想要使用的显示模式存储在这个变量中,用于存储显示模式

  4. 创建一个uint32_t类型的变量,用于存储设备支持的显示模式。

  5. 调用vkGetPhysicalDeviceSurfacePresentModesKHR,如果成功则获得该设备支持的显示模式数量

  6. 创建std::vector<VkPresentModeKHR>,再调vkGetPhysicalDeviceSurfacePresentModesKHR,若返回VK_SUCCESS表示集合里包含了设备支持的显示模式类型

  7. 匹配需要的显示模式,未匹配则可选用FIFO显示模式,因其是必备选项。

IMMEDIATE

应用提交的图像(数据) 立即被转移到屏幕,因该模式下无缓冲队列,也不会等待Vsync的触发,所以可能会产生显示屏幕中的画面撕裂现象。

FIFO 

每个Vulkan API的实现都必须支持FIFO模式。在使用这种模式的情况下,当显示图像时,该图像会被添加到FIFO队列,该队列的长度等于交换链中图像的总数减一。通过使用这种队列,图像能够以与空白时间同步的方式(垂直同步)在计算机屏幕上显示,其被显示的次序永远会与其被添加到队列中的次序相同,刷新显示的时刻叫做"垂直空白"。这种显示模式中不会出现画面撕裂,因为启用了垂直同步功能。这种模式与OpenGL中将交换间隔设置为1的缓冲区交换模式类似。

FIFO Relax

在FIFO上做了修改,当图像的显示时长超过一个vsync周期时,下一个图像不会再等待下一次vsync的到来,而是立刻显示。如果显示速度足够快,就不会出现画面撕裂,但如果我们编写的应用程序的绘图速度低于显示器的刷新频率,就会出现画面撕裂。该行为与OpenGL中EXT_swap_control_tear扩展设置的行为类似。

MAILBOX

可以将其视为三缓冲区显示模式。这种显示模式会使用一个队列,但该队列仅会含有一个元素。该队列中的图像会通过与空白间隔同步的方式在屏幕上显示(在启用了垂直同步的情况下)。但是当应用程序显示图像时,新图像会替换队列中的图像。因此,显示引擎总是会显示最后一个、最新的可用图像,而这种显示模式不会出现画面撕裂。

总结

本文主要分析了Vulkan绘制显示部分的基础架构--swap chain的设计、兼容性,并分析了其中重要的属性-显示模式的各种特性,至于其他的特性后续有机会再分析。我们可以看到Vulkan在显示部分也有更丰富的场景支持和更自由的选择权供应用选择。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vulkan 绘制显示设计 的相关文章

  • 如何获取每个StorageVolume的可用大小和总大小?

    背景 谷歌 悲伤 计划破坏存储权限 https www xda developers com android q storage access framework scoped storage 这样应用程序将无法使用标准文件 API 和文件
  • 从响应中获取标头(Retrofit / OkHttp 客户端)

    我正在使用 Retrofit 与 OkHttp 客户端和 Jackson 进行 Json 序列化 并希望获取响应的标头 我知道我可以扩展 OkClient 并拦截它 但这发生在反序列化过程开始之前 我基本上需要的是获取标头以及反序列化的 J
  • Android Q:file.mkdirs() 返回 false

    我们有一个应用程序 使用外部存储来存储一些临时文件 图像 二进制数据 该代码已经运行了几年 直到最近才发生重大变化 在 Android Q 上它不起作用 File f new File Environment getExternalStor
  • fetchUuidsWithSdp 的奇怪 UUID 逆转

    我有一个在树莓派上运行的 python 蓝牙服务器 使用 PyBluez 我在服务器中使用的uuid是 8f86d132 4ab8 4c15 b8df 0b70cf10ea56 我正在打电话device fetchUuidsWithSdp
  • 如何在 Linux 内核中定义并触发我自己的新软中断?

    我想在 Linux 内核中创建自己的软中断 这是正确的方法吗 In the init我想触发该模块的softirq我将添加一个调用 394 void open softirq int nr void action struct softir
  • 将现有 VARCHAR 列与 Room 结合使用

    我正在尝试将现有的数据库与 Android Room 一起使用 但是 我的一个表有一个 VARCHAR 列 Room 似乎只支持 TEXT 不支持 VARCHAR 而且 sqlite 不允许修改列类型 那么 有没有办法使用Room中现有的带
  • 通过 WhatsApp 发送消息

    由于我发现了一些较旧的帖子 表明 Whatsapp 不支持此功能 我想知道是否发生了变化 以及是否有办法打开与我通过意图发送的号码进行 Whatsapp 聊天 UPDATE请参阅https faq whatsapp com en andro
  • Dialog.setTitle 不显示标题

    我正在尝试向我的对话框添加自定义标题 但是每当我运行我的应用程序时 它都不会显示标题 我创建对话框的代码是 final Dialog passwordDialog new Dialog this passwordDialog setCont
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • 从 BroadcastReceiver 类调用活动方法

    我知道我可以做一个内部接收器类来调用接收器中的任何方法 但我的主要活动太大了 要做的事情也很多 因此 我需要一个扩展广播接收器的类 但它不是内部类 并且可以从我的主要活动中调用一种方法 我不知道是否可能 但我的活动是家庭活动和 single
  • Android 中如何通过彩信发送图片?

    我正在开发多媒体应用程序 我正在通过相机捕获一张图像 并希望将该图像和文本发送到其他号码 但我不知道如何通过彩信发送图像 MMS 只是一个 http post 请求 您应该使用执行请求额外的网络功能 final ConnectivityMa
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • Android 如何将总天数准确更改为年、月、日?

    我正在做一个应用程序 该应用程序与根据给定的生日日期输入获取一个人的年龄有关 为此 我从下面的代码中获取从该日期到当前日期的总天数 String strThatDay 1991 05 10 SimpleDateFormat formatte
  • Android - 以编程方式选择菜单选项

    有没有办法以编程方式选择菜单选项 基本上 我希望视图中的按钮能够执行与按特定菜单选项相同的操作 我正在考虑尝试调用 onOptionsItemSelected MenuItem item 但我不知道要为菜单项添加什么 是的 有一种方法可以选
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • 通过电子邮件发送文本文件附件

    我正在尝试附加一个文本文件以便通过电子邮件发送 但每当我打开电子邮件应用程序时 它都会说该文件不存在 请帮助 Intent i new Intent Intent ACTION SEND i setType text plain i put
  • Android:如何从网络异步获取搜索建议?

    我创建了一个可搜索的活动 现在 我想添加从网络服务获取的搜索建议 我想异步获取这些建议 根据添加自定义建议 http developer android com guide topics search adding custom sugge
  • 如何使用 AccessibilityService 在 Android 中模拟按键

    我正在编写一个辅助服务 我一直在尝试在应用程序上进行一些自动搜索 我使用accessibilityservice action paste来填充EditText 然后我需要模拟软键盘上的按键 但我不知道如何做 你们能帮我一下吗 你可以尝试A
  • Android 后台倒计时器

    我有一个 Android 应用程序 它管理一个倒计时器 类 CountDownTimer 它显示在应用程序屏幕中 以显示到达 00 00 还剩多少时间 我现在的问题是 当我按主页按钮或启动另一个应用程序时 应用程序 计时器不会在后台运行 所
  • 发布的 Android apk 出现错误“包文件未正确签名”

    我最近将我的应用程序上传到 Android 市场 但是由于错误 下载时它拒绝运行 包文件未正确签名 我首先使用 eclipse 发布了数据包 右键单击导出 创建密钥库然后发布 但它拒绝工作 然后我下载了 keytool 和 jarsigne

随机推荐

  • Android面试题最新整理,2022年最新版

    每年的9月和10月 是互联网大厂疯狂招人的时期 也是程序员们跳槽的黄金期 不知道你有没有幻想过这样一个场景 大厂的面试官说 恭喜你通过面试 明天来办理入职吧 今天 为大家整理了2022年Android大厂面试真题 刷企业历年真题 助你轻松搞
  • 大话西游手游有双系统服务器吗,大话西游手游有几个版本_大话西游手游官服和混服怎么区分_玩游戏网...

    大话西游 手游时间服点卡是互通的吗 点卡有两种 一种是大话西游手游内部的点卡 这种点数是在游戏里面购买道具或者计时用的 分为绑定点和交易点 这种是不能通用的 比如我在时间服有两个号 一个是绝代佳人区 另外一个是勿忘初心区 绝代佳人的点卡是不
  • 基于Matlab实现图像融合技术(附上多个仿真源码+数据)

    图像融合技术是一种将多幅图像融合为一幅图像的方法 使得这幅融合图像包含原始图像的所有信息 近年来 图像融合技术已经广泛应用于图像分割 变换和裁剪等领域 本文将介绍如何使用Matlab实现图像融合技术 实现步骤 首先 我们需要了解图像融合的基
  • linux下c语言实现tail -f功能---实时读取变化文件中的增量内容

    最近由于项目需要 需要对文件中实时新增的数据进行处理 结合tail f的逻辑 用c语言实现了这一功能 代码如下 cpp view plain copy include
  • jquery获取select值

  • ARM架构学习(二)——流水线

    本期主题 ARM流水线 往期地址 ARMv7架构学习 ARM流水线 1 流水线概念 2 指令的分解步骤 1 流水线概念 硬件资源总是有限的 有一个明显的方法能改善硬件资源的利用率 这就是pipeline 流水线 技术 其实就是在当前指令结束
  • std::nth_element bug引起的crash问题

    1 源码 auto less compare const MirroringGroup mg1 const MirroringGroup mg2 gt bool return mg1 usage lt mg2 usage std nth e
  • 腾讯云服务器配置选择方法

    腾讯云服务器配置如何选择 CPU内存 带宽和系统盘怎么选择合适 个人用户可以选择轻量应用服务器 企业用户可以选择云服务器CVM 2核2G3M带宽轻量服务器95元一年 2核4G5M服务器168元一年 企业用户可以选择标准型S5云服务器 可以一
  • idea 生成类图

    选中类 ctrl alt u或者ctrl alt shift u 生成类图
  • ArcGIS GraphicsLayer层的特殊要求

    如果你要使用GraphicsLayer这个绘图层 那么你需要注意自己的布局的模式不可以使用 layout absolute 如果你使用了这个布局 那么你的GraphicsLayer层可能会无法使用 比如下面的程序就是因为设置了 layout
  • java 最大公约数和最小公倍数

    题目 题目 输入两个正整数m和n 求其最大公约数和最小公倍数 比如 12和20的最大公约数是4 最小公倍数是60 说明 break关键字的使用 代码一 package l2 for 题目 输入两个正整数m和n 求其最大公约数和最小公倍数 比
  • Counter统计列表中元素出现次数

    使用Counter方法 统计元素在列表中出现的次数 from collections import Counter k labels 1 1 0 1 0 0 1 1 2 2 3 2 2 2 2 Counter返回的是字典 key为列表中元素
  • TVM系列---1.开始使用Tensor Expression

    Author Tianqi Chen https docs tvm ai tutorials tensor expr get started html Tensor Expression入门 这是TVM中Tensor表达语言的入门教程 TV
  • Unity动画系统详解5:BlendTree混合树是什么?

    摘要 Animator中有一个功能 用来解决多个动画之间的混合 经常用于移动动画之间的混合 这个功能叫做BlendTree 混合树 洪流学堂 让你快人几步 你好 我是跟着大智学Unity的萌新 我叫小新 这几周一起来复 yu 习 xi 动画
  • cl : 命令行 warning D9002:忽略未知选项“ /NODEFAULTLIB:library ”

    前言 cl 命令行 warning D9002 忽略未知选项 NODEFAULTLIB library 原因 一下引用 連結器工具警告 LNK4098 执行运行时程序库现在包含指示词 以防止混合不同的类型 如果您尝试在相同的程序中使用不同类
  • leetcode刷题(7)二叉树(1)

    哈喽大家好 这是我leetcode刷题的第七篇 这两天我将更新leetcode上关于二叉树方面的题目 如果大家对这方面感兴趣的话 欢迎大家持续关注 谢谢大家 那么我们就进入今天的主题 文章目录 1 二叉树的前序遍历 题目要求 示例 做题思路
  • RESTful-RESTful GET,如果存在大量参数,是否有必要变通一下?

    问题 比如设计一个GET接口 用来获取满足条件的商品 GET shop 1 goods 参数可能是五花八门的 name create time description status owner 通常这种情况 如果不考虑RESTful 就会设
  • C++工程师复习题

    一 auto ptr 类使用必须满足下列限制 1 不要使用 auto ptr 对象保存指向静态分配对象的指针 2 不要使用两个 auto ptrs 对象指向同一对象 3 不要使用 auto ptr 对象保存指向动态分配数组的指针 4 不要将
  • Vulkan再探(7):纹理贴图

    08 20 2020 文章目录 纹理贴图 Texture Mapping 纹理属性 加载图片 临时缓冲区储存图片信息 生成贴图等级 生成图像和存储空间 难点 传输数据 图解 拷贝缓冲区到图像 创建采样器 创建图像视图 创建组合图像采样器描述
  • Vulkan 绘制显示设计

    背景 众所周知 Vulkan是个跨平台的图形渲染API 为了友好地支持跨平台 Vulkan自然也抽象出了很多接口层去对接各个操作系统 抹平系统间的差异 Swap Chains即为WSI 其本质上是一种图像队列 此队列会按顺序依次将队列中的若