在PowerVR GPU上试用新Vulkan图形处理API

Vulkan™是Khronos Group研发的新一代高性能图像处理和计算API。Vulkan没出来以前,人们都称它为glNext,它的设计弥补了22年前的OpenGL® API 的短板。

以下是Vulkan官方新闻发布会的摘要:

• API底层的重新设计:确保了在现代GPU上图形处理和计算的高效。

• 直观的:应用可直接的、可预见地控制GPU操作。

第一个使用Vulkan API的演示

Imagination是Khronos Group的一名成员,它一直致力于为我们PowerVR Rogue GPUs研发Vulkan的概念验证。我们的PowerVR demo团队在最后两个月里把我们的新OpenGL ES 3.0传送到新API中,所以今天我们能为您展示我们工作的一个快照。

The Library demo最初用OpenGL ES 3.0 API创造,而且几乎在Vulkan API设计出来的同时我们就想把它传送到API上。由于时间限制,相比于OpenGL ES 3.0 version 我们需要更改一些效果,但是演示仍然保留了许多初代app的特点。以下是视频内容的总结:

• 高质量,基于实物的阴影

• HDR(高动态范围)渲染

• 20个特别的2K PVRTC密度

• 通过使用Imagination的PVRTC密度压缩标准,2 GiB的密度数据能压缩到266MiB

• 4 x MSAA(多采样反走样)

• 16 x 各向异性纹理过渡

• 物理规律的材料参数

• 低CPU使用率,高CPU效率

• 修正反射材料上的镜面反射

• 超过250,000个三角形

• 后期处理效果:饱和度,曝光和色调映射

请注意这是一个透明度驱动,并且现在的展示不代表最终的产品表现。

CPU工作量降低

新Vulkan界面的设计尽可能地接近现代CPU的设计。这意味着两者的代码长度和用户的工作量和Vulkan驱动的内核空间非常小,因此它要比OpenGL ES更高效。

比如,在Vulkan上没有glUniform*()等价的入口点;然而,把数据写入GPU存储是把数据传递到着色器唯一的方式。

当你调用glUniform时,OpenGL ES驱动通常需要分配一个驱动,管理缓冲区,并复制数据到其中,位于CPU上部驱动CPU的管理器。用Vulkan,你可以简单的映射内存地址并直接写入存储区。

这是一个我们库demo的Vulkan和OpenGL ES 3.0 CPU占用差异的展示图表。

CPU占用:Vulkan vs OpenGL ES

CPU占用:Vulkan vs OpenGL ES

更简洁、更直观的驱动器

硬件上API设计的结果意味着前端部分的驱动程序的指令数量显著降低,相比较OpenGL ES。复杂性的降低使开发者能提交更多绘制指令,同时硬件供应商能实现更好的稳定性和更快的驱动节省时间。

即使这里使用的驱动是一个alpha(又先行版)版本,我们仍希望Vulkan最终能非常稳定,因为编码变少使错误更难产生。

Vulkan

在Vulkan里,GPU高水平的控制需要通过应用表现(例如:资源寿命)。驱动器几乎完全撒手不管,只做应用让它做的事。它导致应用更复杂的同时,又该被驱动器工作的需要抵消(例:OpenGL ES的阴影预热)

如果你的应用使用引擎做渲染,引擎很可能已经在着手这个了,并且Vulkan能提供一个几乎无拘束的加速。

Vulkan设计的方式和基于缓冲基础的现代命令API很像,所以如果应用或架构已经使用了这些编程界面,这应该是个容易的工作。

更加一致的表现

人们可能会说这个API的主要优势是在提交绘制指令时减少了CPU相关工作-并且的确如此。

然而我认为主要优势是这个API将使设计3D图像更加可预见。让我解释一下:比如,当你在OpenGL ES上用glBlendFunc()时,根据运行编码的底层图形架构能发生不同的事情。

API

一些GPU能延迟设置混合,直到第一次使用绑定着色器;其他的可能不行。这使通过不同的GPU经销商实现一致的性能非常困难。

Vulkan让解决这个问题更简单,因为API的切入点的设计允许了驱动器在一个相同的的地方工作。

当你使用Vulkan描述一些情形补充了一个结构,你知道没有没有驱动器在工作;这个编码是所有应用使用的编码。该API的设计尽量满足GPU经销商的架构,所以更不可能出现未知的性能问题。

glBlendFunc()问题变得陈旧,因为管道设置时一个结构里的混合函数已确定。当用函数创造管道,驱动器早早开始工作,,而不是在渲染时断断续续地工作。

Vulkan API

事实上,大量的Vulkan API旨在能够预先列举所有东西,如果可能的话。比如你能记录一列渲染指令和状态设置指令到指令缓冲器里,并只用一个指令就能重放每一帧。驱动器有更多机会优化这个使用案例,因为它知道它能做更多工作,在创造命令缓冲而不是执行的时候。

另一个Vulkan明确性质的结果就是没有资源重命名(或者重影),多重缓冲需要准确表现。多重缓冲是一个借助显卡驱动的过程,同时可能有正在处理的大量框架。

附属于那些框架的数据(例:标准数据和附加纹理)需要在周围保持直到它依附的框架结束;这需要应用来表现。有利的一方面是,在框架之间不会被修改的,你所已知的数据(例:对比度和亮度),为了尽可能的最优化可作为常数列举。

PowerVR GPUs是一等公民

Vulkan增加的一个关键特点就是渲染路径,它能重定义一个应用能多大程度控制我们的硬件,并且能让在不影响应用的情况下暗中减少我们的工作量。

一个渲染路径包含framebuffer情形(除了实际渲染目标地址),和每段渲染开始和结束时渲染目标在GPU上应该怎么装载和卸载。这个结构是允许平铺架构的关键对象,比如PowerVR,并且及其高效。

OpenGL ES

在OpenGL ES上渲染时,几件事情可以导致瓦片缓冲的隐形流到主内存上;一个带宽繁重的操作通常是不必要的。我们的OpenGL ES驱动器作出了许多努力来解决应用该做什么来避免产生这些冲洗,并且避免将所有的渲染目标冲到主内存中。在Vulkan中,唯一可能发生的冲洗会发生在渲染路径之间,让它对应用和驱动器来说都很明显。更重要的是-它准确的告诉了GPU对每个渲染目标应用想做什么。

渲染指令能被平行创造

命令缓冲物能在不同的线程产生并移动到到它们被递交的线程上。这意味着所有的CPU内核都能创造渲染指令。

做这个不要求额外的工作或互斥锁-对OpenGL ES来说是不可能有的一个特点。这可能是由于游戏的使用过程需要他们大量重建渲染指令(例如:我的世界)

更多的直觉设计

Vulkan给予你能清楚了解你设置的情形的优势。拿OpenGL ES 上的glActiveTexture()函数举例:对所有的着色器来说,这个函数能否改变全局情形或者可能改变情形仅仅为了当前的着色程序,是很明显的。

在Vulkan中,这清楚的被定义:当你绑定资源时,它处于解除绑定命令缓存区的状态,因为这是函数的第一个参数。

Vulkan一个习惯是把所有入口点的中的第一个参数,作为你要改变函数调用的代表情形。比如:
vkCmdBindDescriptorSet(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
textureDescriptorSet[0], 0);
vkQueueSubmit(graphicsQueue, 1, &cmdBuffer, 0, 0, fence);
vkMapMemory(staticUniformBufferMemory, 0, (void **)&data);
// ...
vkUnmapMemory(staticUniformBufferMemory);

显式的内存管理

当你在OpenGL上调用glTexStorage时,驱动器需要分配内存给二维或一维排列纹理。函数和内存分配过程代表了一个黑箱。

然而在Vulkan里,内存分配由应用决定。这意味着应用更了解它使用的是哪种类型的内存,更重要的是了解使用了多少内存,这对有存储器限制的应用很有用。这与在OpenGL ES上接收“内存溢出”错误,并且需要通过未知量减少资源使用成对比。

Vulkan的显式内存管理允许应用使用自定义分配方式。比如分配所有的主内存并避免渲染期间的任何分配。

其它细节

当Vulkan API 变得更加成熟,Imagination会告诉你更多关于它的信息并且在不远的将来发布示例源代码。

编者的话

PowerVR Rogue. GPUs基于已发布的Khronos规范,并且很有可能通过Khronos的一致性测试。上一代PowerVR GPU 编码已经达到了OpenGL的一致性。你可以在 www.khronos.org/conformance 找到当前的一致性情况。

原文链接:
http://blog.imgtec.com/powervr/trying-out-the-new-vulkan-graphics-api-on...

声明:
本文为原创文章,转载需注明作者、出处及原文链接,否则,本网站将保留追究其法律责任的权利

--电子创新网--
粤ICP备12070055号