深圳网站建设服务找哪家,宣传片视频创意,seo优化工具软件,哪些网站可以免费看剧1. Overview of Vulkan1.1 计算机图形软件图形软件有两个大类#xff1a;专用软件包#xff08;special-purpose packages#xff09;和通用编程软件包#xff08;general programming packages#xff09;。专用软件包通常提供一种UI设计语言#xff0c;让用户直接生成想…1. Overview of Vulkan1.1 计算机图形软件图形软件有两个大类专用软件包special-purpose packages和通用编程软件包general programming packages。专用软件包通常提供一种UI设计语言让用户直接生成想要的图形不用关心内部实现。这类软件例子是PS、CAD等等。相反通用编程软件包提供一个可使用C、C或Java等高级语言编程的图形函数库。图形函数库中提供几何图元、矩阵变换等操作提供了间接操作硬件的软件接口所以这组图形函数又被称为计算机图形应用编程接口computer-graphics application programming interfaceCG API。OpenGL、Vulkan、DirectX、Metal皆在此列。1.2 Vulkan多线程的设计理念Vulkan不仅仅是图形graphicsAPI而是一个面向图形和计算的编程接口graphics and compute。支持Vulkan的设备可以是GPU也可以是DSP或者固定功能的硬件。Vulkan中的计算模型主要基于并行计算因此支持多线程是Vulkan设计的核心理念之一。为了较少Vulkan内部因为互斥同步等操作造成的卡顿问题Vulkan内部默认认为对任何资源的访问不存在多线程竞争所有的资源同步操作由应用开发者去负责因为对资源的访问和使用没有人比应用开发者自己更加清楚。Vulkan称之为外部同步external synchronization。因为这个原因资源管理和线程同步工作成为编写Vulkan程序的最大难点之一。想要让Vulkan多线程正常运行你需要做大量的工作。当然换来的是Vulkan有了更加干净的线程模型以及比其它CG API高得多的性能。image-20200730105359314.png1.3. Instances, Devices, and Queues在正式研究Vulkan多线程之前有三个重要的基础概念需要了解—Instances, Devices, and Queues。Instances可以看做是应用的子系统从逻辑上把Vulkan与应用程序上下文中的其他逻辑隔开。Instances可以看做是Vulkan的上下文它会跟踪所有状态从逻辑上把所有支持Vulkan的设备整合在一起。Devices有两个概念Physical devices和Logical device。Physical devices通常代表一个或者多个支持Vulkan的硬件设备这些设备具有特定功能可以提供一系列Queues。图形显卡、加速器、DSP等都可以是Vulkan的Physical devices。Logical device是Physical devices的软件抽象用于预订一些硬件资源。Queues可以理解为一个“GPU线程”它是实现Vulkan多线程的关键元素之一用于响应应用的请求大部分时间应用都在与其交互。Vulkan功能的层次结构图如下image-20200730105801733.png2. Queues and Command Buffer2.1 QueuesQueue代表一个GPU线程Vulkan设备执行的就是提交到Queues中的工作。物理设备中Queue可能不止一个每一个Queue都被包含在Queue Families中。Queue Families是一个有相同功能的Queues的集合它们的性能水平和对系统资源的访问是相同的并且在它们之间数据传输工作没有任何成本同步之外。一个物理设备中可以存在多个Queue Families不同的Queue Families有不同的特性。相同Queue Families中的Queues的功能相同并且可以并行运行。按照Queue的能力可以将其划分为Graphics图形该系列中的Queues支持图形操作例如绘制点线和三角形。Compute计算该系列中的Queues支持诸如computer shader之类的计算操作。Transfer传输拷贝该系列中的Queues支持传输操作例如复制缓冲区和图像内容。Sparse binding稀疏绑定该系列中的队列支持用于更新稀疏资源sparse resource的内存绑定操作。image-20200730112126405.png2.2 Command Buffer2.2.1 单线程的性能瓶颈传统CG API是单线程的性能的提升只能依赖于CPU主频的提高。能有的优化方案也不外乎主线程和渲染线程分开或者某些资源的异步加载、离线处理。image-20200730114946379.png但是在实际应用中我们还是经常遇到传统CG API导致的性能瓶颈。以手机终端为例CPU主频提升有限各大芯片厂商开始向多核多线程发展考虑到功耗温控问题又不能把CPU频率升的太高越来越高的刷新率对实时渲染的速度要求越来越苛刻。image-20200730115516772.pngVulkan为了充分发挥CPU多核多线程的作用引入了command buffer的概念。多个线程可以同时协作每个CPU线程都可以往自己的command buffer中提交渲染命令然后统一提交到对应的Queue中大大提高了CPU的利用率。image-20200730115609709.png2.2.2 Command Buffer的作用应用在绘制时会提交一系列绘制命令给GPU驱动但是这些绘制命令不会立刻被执行而是被简单的添加到Command Buffer的末尾。在其他CG APIs中驱动程序在应用不感知的情况下把API调用翻译成GPU command并储存在command buffer中最终提交给GPU处理。command buffer的创建和销毁都由驱动负责。在Vulkan中你需要自己从Command Buffer Pool中申请command buffer将想要记录的命令放入command buffer中。Command Buffer Poolimage-20200730142932026.png2.2.3 Recording commandCommand Buffer可以记录Record很多命令比如设置状态、绘制操作、数据拷贝...image-20200730142958943.pngimage-20200730142302468.png理论上一个线程可以把Command记录到多个Command Buffer中多个线程也可以共享同一个Command Buffer但是一般不鼓励多个线程共享一个Command Buffer。Vulkan的关键设计原则之一就是做到高效的多线程。想实现这一点应用程序要注意因为资源竞争导致的多线程彼此阻塞。因此每个线程最好有一个或者对个Command Buffer不要尝试共享一个。另外Command Buffer由Command Buffer Pool分配应用可以为每一个线程创建一个Command Buffer Pool让各个工作线程从Command Buffer Pool中分配Command Buffer无需参与竞争。image-20200730144149412.png2.2.4 Submitting Command Buffers提交过程使用示意图更加好理解一点。单线程Command Buffer提交过程submit cb1.PNGsubmit cb5.PNGsubmit cb2.PNG多线程Command Buffer提交过程submit cb3.PNGsubmit cb4.PNG整体流程如下image-20200730144906368.png3. Synchronization3.1 显示同步操作Vulkan把同步的操作交给了应用external synchronization绝大多数的Vulkan命令根本不提供同步需要应用自己负责。Vulkan给应用提供了同步原语帮助应用进行同步操作。Vulkan中主要有四种同步原语synchronization primitivesFences最大颗粒度的同步原语目的是给CPU端提供一种方法可以知道GPU或者其他Vulkan Device什么时候把提交的工作全部做完。如果你熟悉Android显示机制的话acquire fence或者retire fence就是类似的作用Semaphores颗粒度比Fences更小一点通常用于不同Queue之间的数据同步操作Events颗粒度更小可以用于Command Buffer之间的同步工作BarriersVulkan流水线Pipeline阶段内用于内存访问管理和资源状态移动的同步机制下面这张图取自NVIDIA公司Vulkan 多线程讲解的PPTimage-20200730145823767.png3.2 隐藏的执行顺序Vulkan是显式的API没错号称是“没有秘密的API”。但是在多线程同步时还是存在一些潜规则。以下面这张图为例同一个Queue中Command Buffer1 和Command Buffer2 谁先执行Command Buffer中记录的一堆命令是如何执行的image-20200730144906368.pngVulkan的执行顺序其实是有一定的潜规则的在没有同步原语的情况下Command Buffer中的Command先记录的先执行先提交的Command Buffer先执行同一个Queue中一起提交的Command Buffer1 和Command Buffer2 按照下标的顺序执行Command Buffer1 先执行3.3 Barriers所有的同步原语中Barriers使用起来最为困难。Barriers用于显式的控制buffer或者image的访问范围避免hazardsRaW,WaR,and WaW保证数据一致性。Barriers需要开发者了解渲染管线的各个阶段能清晰的把握管线中每个步骤对资源的读写顺序。Vulkan中将Pipeline的各个阶段定义为TOP_OF_PIPE_BITDRAW_INDIRECT_BITVERTEX_INPUT_BITVERTEX_SHADER_BITTESSELLATION_CONTROL_SHADER_BITTESSELLATION_EVALUATION_SHADER_BITGEOMETRY_SHADER_BITFRAGMENT_SHADER_BITEARLY_FRAGMENT_TESTS_BITLATE_FRAGMENT_TESTS_BITCOLOR_ATTACHMENT_OUTPUT_BITTRANSFER_BITCOMPUTE_SHADER_BITBOTTOM_OF_PIPE_BIT对应image-20200730152820973.png假设我们有个两个渲染管线P1 和 P2P1会通过Vertex Shader往buffer写入顶点数据P2需要在Compute Shader中使用这些数据。如果使用fence去同步你的流程应该是这样P1的Command提交后P2通过fence确保P1的操作已经被全部执行完再开始工作。image-20200730153109052.png但是这种大颗粒度的同步操作无疑造成了耗时操作P1的数据在Vertex Shader阶段就已经准备好了我们为什么要等到它所有操作执行完再开始P2平白多等待了很长时间而且在这个期间P2的其他阶段并没有使用到P1的数据也是可以执行的啊。Barriers的引入完全解决了这个问题我们只需要告诉Vulkan我们在P2的Compute Shader阶段才会等待P1 Vertex Shader里面的数据其他阶段并不关心可以同步进行。image-20200730152521195.png使用方法image-20200730153743130.png参考文档Vulkan OverviewAndroid and Vulkan - GDD China.pdfVulkan Programming GuideVulkan CookbookLearning VulkanVulkan Multi-ThreadingVulkan中的同步机制Vulkan® 1.1.148 - A SpecificationVULKAN BARRIERS EXPLAINEDvulkan中的同步和缓存控制之二barrier和eventXinzhaovulkan中的同步和缓存控制之一fence和semaphore本系列文章汇总Vulkan 简介Vulkan 多线程渲染Vulkan 内存管理Vulkan 绘制与显示Vulkan 资源绑定和状态管理