译者注

前几天,我在 Linux Graphics 知识星球中报道了《Vulkan-Docs 新增 VK_EXT_extended_dynamic_state》的消息,当时我对于该 extension 只知道大致的意思,却不了解其真正的含义及作用。直到几天后,我在 Ricardo García 的个人博客上读到这篇原文时,才对 VK_EXT_extended_dynamic_state 有了深刻的理解。

原文作者并不是一上来就讲解该 extension 是什么、怎么用,而是先介绍 vulkan pipeline 、shader、dynamic state 这些基本概念,然后通过问题来引出 VK_EXT_extended_dynamic_state 以及它的用法,最后还介绍了该 extension 产生的故事背景,整篇阅读起来十分顺畅。因此本人决定将其翻译成中文,分享给大家,方便大家阅读。

正文

几天前,Vulkan-Docs 发布了 VK_EXT_extended_dynamic_state 扩展(extension),并首次出现在 Vulkan 1.2.145 版本中。这是一个非常有趣的扩展,它让 Vulkan pipeline 在许多使用场景中,变得更加灵活和实用。在 Igalia 公司,我作为该扩展的 VK-GL-CTS 测试作者参与了该扩展的开发工作,并且以个人绵薄之力 review 了 spec 文档,同时还对其做了一些小的修改。

Vulkan pipelines

此 Vulkan 扩展的目的,是为了让 Vulkan pipeline 在使用时可以动态设置某些参数,而不是那些一成不变的值(它们通常在创建 pipeline 的时候就固定了下来),从而让 Vulkan pipeline 变得更加灵活。对于那些不太熟悉 Vulkan 的人来说,Vulkan pipeline 可谓是 API 中体量最大的一个 object。Vulkan 通常包含 Compute Pipeline 和 Graphics Pipeline。对于这个扩展而言,我们只讨论 Graphics Pipeline。一个 pipeline object,当它被创建时,它包含了大量有关场景渲染时 GPU 需要执行哪些操作的信息。例如,如何从内存中读取三角形的顶点,有多少个 texture、buffer 和 image,颜色混合(color blending)参数,深度和模板测试(depth and stencil test)参数,多重采样抗锯齿(multi-sample anti-aliasing)参数,视口(viewport)参数,等等。

Vulkan 是一个低开销(low-overhead)的 API,它能帮助你尽可能地榨取 GPU 的性能。它希望你能提前指定所有信息,以便 Vulkan 底层实现(即 GPU 和驱动程序)在 pipeline 创建和运行时都有更多的机会来优化应用程序。每当你 “bind 一个 pipeline” 时(例如,将其作为后续 command 的 active pipeline),你都是在告诉底层 GPU 驱动应该如何工作。接着通常会有一堆 commands 紧随其后,用来告诉 GPU 使用前面的参数来绘制大量的几何图形。

创建 pipeline 可能还涉及到将 shader (着色器)编译为 GPU 本地可执行指令。shader 是一些可以直接运行在 GPU 上的小程序,当渲染流程进行到可编程阶段时,就会执行这些 shader 程序。当使用 GPU 绘制图形时,绘制过程将被拆分成多个阶段,每个阶段都会有许多输入数据,这些数据既可以来自于上一阶段,也可以来自于外部资源(如 buffer、texture 等),然后会生成许多输出,以供下一个阶段直接使用,或作为外部资源的后处理使用。其中一些阶段是固定不变的,而另一些则是可编程的(通过用户提供的 shader 程序来实现)。而当这些 shader 程序不那么小的时候,将它们编译并优化成 GPU 可执行指令将花费更多时间。通常算不上很长的时间,但如果使用毫秒计数的话,你就只有 16.6 ms 的时间来画下一帧,以便能达到 60fps 的效果。也正是这个问题催生了 ACO Shader 编译器的产生(用于 Mesa 中的 RADV 驱动,即 amdgpu vulkan 驱动),这也是为什么有些驱动程序会对 shader 的内容进行 hash 处理,并通过 shader cache 来检查之前是否编译过该 shader 程序。这同样也是为什么 Vulkan 希望你能尽可能提前创建 pipeline 的原因,否则当你在为动作游戏准备下一帧的过程中,突然发现需要一个新的 pipeline 时,可能会因为新的 pipeline 创建过程需要额外的处理时间而导致整个游戏变得卡顿。

Vulkan 为我们提供了几种缓解上述问题的可行方案。第一种,你可以事先创建好所有你认为需要的 pipeline。这的确是一种有效的方法,但由于我们可能会使用不同的 pipeline 参数进行组合,因而可能会创建大量的 pipeline。假设你想分别修改7个不同的参数,每个参数都有2个可能的值。这也就意味着,你必须在应用程序中创建128个(2 的 7 次方)不同的 pipeline 并对它们进行管理维护。另一种方案则是使用 pipeline cache,如果我们创建的是一个与之前相同或相似的 pipeline 的话,它将加快创建 pipeline 的速度,这样你就只需关注在给定时间点所需的 pipeline 变量就可以了。最后,Vulkan 为我们提供了动态修改 pipeline 参数的能力,而不是在创建 pipeline 时为它们设置固定的值,那就是 pipeline 中的 dynamic state

dynamic state 和 VK_EXT_extended_dynamic_state

dynamic state 可以帮助我们解决前面提到的所有问题。它使你的应用程序逻辑变得更加简单,因为你不再需要处理这么多不同的变量。同时它也减少了创建新 pipeline 的次数,这样就可以缩短初始化时间,降低 pipeline cache 的大小和访问次数,减少 state 修改以及游戏卡顿。VK_EXT_extended_dynamic_state,当它被创建出来的时候,顾名思义,它扩展了 dynamic state 的 pipeline 元素的数量。它添加了如下 state:culling mode(剔除模式)、front face(正面)、primitive topology(图元拓扑)、带计数的 viewport、 带计数的 scissor(虽然以前的 viewport 和 scissor 也可以动态修改,但是我们无法修改它们的计数值)、顶点输入 binding stride、depth test(深度测试)激活与写入、depth comparison(深度比较)操作、depth bounds(深度边界)激活以及 stencil test(模板测试)激活等操作。这是一个相当大的新 dynamic 元素集合!

接下来的一个明显的问题是,使用这么多的 dynamic 元素是否会导致性能下降?因为 pipeline 的某些细节我们是无法提前预知的,从某种意义上讲这可能会减少 Vulkan 驱动实现的优化机会。我的回答是,这取决于 Vulkan 驱动的具体实现。例如,在某些 Vulkan 驱动的具体实现中,culling mode 或 front face 可以在绘图操作之前就设置到寄存器中,不管是在绑定 pipeline 的时候设置这些参数,还是在发送大量绘图命令之前动态的设置这些参数,就 Vulkan 驱动本身而言,这两种方式没有实际的差别。

我使用一个简单的 GPU-bound 的 Vulkan 程序测试了开启每个新的 dynamic state 对性能的影响,在屏幕上显示一个旋转的 3D 模型,结果我并没有发现它对 NVIDIA 专有驱动和 GTX 1070 显卡有任何性能上的影响,但你的测试结果可能会和我有所差异。和往常一样,在部署前请先进行测试。

当使用 Vukan 作为后端来实现其他更高级的 API 时,VK_EXT_extended_dynamic_state 也能派上用场。这些 API 不像 Vulkan 本身那样严格,其中一些绘图参数可以动态的修改,这全凭驱动程序来尽可能高效地完成这些修改。我说的其实是 OpenGL 或者 DirectX 11 之前的版本,正如你所猜想的,它对于 DXVK 这类项目而言是一个非常有意思的扩展接口,借助 Wine 和 Proton 它可以帮助改善 Linux 上的游戏现状。

VK_EXT_extended_dynamic_state 的起源

关于这个扩展的背景故事也是十分有意思的,这一切都源于 Eric Lengyel 的一条“愤怒”的推特,他在推特中抱怨道,在渲染反射时,他不得不创建两条独立的 pipeline,仅仅只是为了改变 front face 或者三角形的环绕顺序。这促使 NVIDIA 工程师 Piers Daniell 在 Khronos 组织内部启动了一项 multi-vendor 的工作,并最终形成了 VK_EXT_extended_dynamic_state 这个扩展。正如你在该扩展的 summary 中所看到的,有许多公司参与了该扩展的制定,它们是:AMD、Arm、Broadcom、Google、Imagination、Intel、NVIDIA 和 Valve。

因此,这个扩展也是 Khronos 组织的众多成功案例之一。Khronos 组织就像是一个论坛,在这个论坛里,大大小小的硬件和软件厂商为实现图形行业跨平台解决方案,都纷纷参与到该方案的设计和标准的制定中来。在设计这些解决方案时,它们采纳了许多不同的观点和意见。如果你看一眼成员名单,你会看到许多来自硬件制造商和软件开发商的知名 logo,甚至还包括一些非常流行的游戏引擎公司。

在这个案例中,一条愤怒的推特就可以碰撞出大家共同努力的火花,但我们不应该它当作典范来模仿。其实你可以通过 Vulkan-Docs Github 仓库来提交改进 Vulkan Spec 的建议、新的 extension 以及好的想法。提交一个 Issue 其实就足够了!对于一个小的修改,使用 Pull Request 可能会更好!

全文完。

原文链接

VK_EXT_extended_dynamic_state released for Vulkan

翻译:Vulkan VK_EXT_extended_dynamic_state 介绍相关推荐

  1. (翻译)《介绍 GENEVA Beta 1 白皮书》(3)

    有任何问题,可以查看 翻译预告 <介绍 GENEVA Beta 1 白皮书>或者直接在这里回复. A CLOSER LOOK AT THE "GENEVA" TECHN ...

  2. VS2017中自用部分插件的设置的翻译或功能介绍—— Viasfora设置(一)

    Viasfora 彩虹括号,关键字高亮,转义符.占位符特殊颜色 4.2.188版本 官网/GitHub 截图中的设置为本人正在使用的设置 2019年4月11日 16:08 说明 此篇为各项设置的翻译或 ...

  3. 大学生学计算机的自我介绍范文带翻译,大学英语自我介绍范文带翻译_大学带翻译英语自我介绍范文...

    大学英语自我介绍范文带翻译_大学带翻译英语自我介绍范文 发布时间:2020-03-19 大学生用英语做一个自我介绍,既可以展现你的英语水平,又可以让别人认识你.本文是第一范文网小编为大家整理的大学英语 ...

  4. gitee合并分支_使用Gitee进行协作翻译的简单介绍

    协作翻译的Gitee使用介绍 由于Github国内访问不稳定,加之大部分同学应该都在国内,所以我使用了Gitee进行协作.(github的操作也是完全一样的) 很多同学说不知道怎么创建分支,也不知道怎 ...

  5. [翻译]Telnet简单介绍及在windows 7中开启Telnet客户端

    文章翻译自 http://social.technet.microsoft.com/wiki/contents/articles/910.windows-7-enabling-telnet-clien ...

  6. 全国翻译资格考试 介绍

    "翻译专业资格(水平)考试"(China Aptitude Test for Translators and Interpreters -CATTI )是为适应社会主义市场经济和我 ...

  7. 计算机专业学生的自我介绍英语翻译,大学生自我介绍英文版带翻译.doc

    大学生自我介绍英文版带翻译 ★精品文档★2016全新精品资料-全新公文范文-全程指导写作 –独家原创 PAGE1 / NUMPAGES1 大学生自我介绍英文版带翻译 大学生英文自我介绍是怎样的呢在毫无 ...

  8. (翻译)Pachyderm介绍-建造一个现代的Hadoop

    背景 最近在调研时发现了Pachyderm这个项目,感觉他们做的工作挺有意思的.Pachyderm将Docker和Hadoop联合起来,旨在使得大数据分析的过程更加便捷,众多非Java语言的工具也可以 ...

  9. 励志短句在线翻译的方法介绍

    励志短句都是比较的简短,那么我们是怎么进行在线翻译的呢?下面就让小编简单的给大家介绍一下. 步骤一:首先我们需要将这些励志短句准备好,放在一个TXT中,或者是文档中进行: 步骤二:之后我们可以直接进入 ...

最新文章

  1. Python遍历字典的方法
  2. python和javascript详细对比_python与javascript 引入模块的方法对比
  3. 台式无线网卡管理服务器,台式电脑设置wifi上网
  4. jquery中如何实现一个li里面一排6张图片进行切换
  5. Directx11教程(65) 渲染到纹理
  6. 十个谈话技巧让你在IT职场出人头地
  7. 进入全屏 nodejs+express+mysql实现restful风格的增删改查示例
  8. typedef用法总结(一)
  9. python入门教程收藏_python入门教程:超详细保你2小时学会Python,快来收藏看看...
  10. java终止程序语句总结 System.exit(1)、System.exit(0)、return;break;continue;
  11. 2018年11月黑马java
  12. ffmpeg 图片合成视频黑屏 不兼容问题合成MP4
  13. R语言使用rbind函数将两个dataframe数据纵向合并起来(vertically)
  14. C++——队列应用——显示二项式系数
  15. html网页页面制作用到了什么技术,技术干货|常用的HTML5网页制作软件,这些你有在用吗?...
  16. POJ3349-Snowflake Snow Snowflakes
  17. Windows关于文件句柄数的限制
  18. VB文本框textbox的那点事
  19. 利用百度地图API接口自制地图
  20. react native关于FlatList的随手记

热门文章

  1. 本人的QQ群:有来的可以加。
  2. Oracle数据库培训渠道,你知道吗
  3. 异步编程初探:async和await
  4. ZBrush有多少版本?ZBrush下载集合
  5. 有趣的生活,有趣的比赛
  6. 最强 OSERDES IP核使用详解;FPGA 结构分析 —— IO 并串转换资源 OSERDES
  7. C# 创建PDF文档
  8. 产品销售好坏需要哪些方面分析原因-悟空软件与你一起探讨
  9. heic格式转化jpg,heic无损转jpg
  10. 你旅游过,但是你知道那些景点用英语怎么说吗?