转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2833

[上周GDC,微软正式宣布了DX12和一些细节,这里放个中文翻译的版本]

有什么神奇之处?

这次的DirectX 12引入了新版本的Direct3D:位于DirectX核心地位的图形API。Direct3D是游戏或游戏引擎中最重要的组成部分之一,我们对其进行了重新设计使其比以前更快更高效。由此,Direct3D 12可以渲染更丰富的场景、更多物体,并能更好地利用当前的GPU硬件。而且Direct3D 12不但能用于高端游戏PC,也可以在所有微软的设备上运行。从手机和平板,到笔记本和台式机,当然,还有Xbox One。Direct3D 12就是你期待已久的API。

是什么让Direct3D 12独树一帜?首先,也是最重要的,它提供了一个比以前更底层的硬件抽象,让游戏可以明显改善多线程能力和CPU利用率。另外描述表(descriptor table)和简洁的流水线状态对象(pipeline state object,PSO)等新特性都可以降低GPU的开销,从而加速游戏。另外, Direct3D 12也引入了一系列新的渲染流水线功能,可以显著提升一些算法的效率,比如顺序无关透明、碰撞检测和几何剔除。

当然,每个API都需要工具来助你一臂之力。DirectX 12将会包含一些好用的Direct3D工具,伴随Direct3D 12一起发布。

你可能会对这个感兴趣:DirectX 12可以在很多已有的卡上运行。详细请见后面的FAQ。

这只是噱头吗?

我们(产品组)从twitter和游戏开发/玩家论坛中得到了很多反馈意见。很多人问了DirectX 12是确有其事,还是营销部门突然得到了一笔资金。实际上,你看到的所有东西都直接来自于近20年来一直兢兢业业开发DirectX的团队。

我们的任务是建立一个更好的API。同时,我们和软硬件伙伴紧密合作,以保证Direct3D 12上能有明显的性能提升。我们没有自己设计一些小的评测软件来跑分,而是在我们的alpha版本上直接运行已经发行的商业游戏引擎或评测软件。下面的截图来自于真实的Direct3D12程序代码、运行在真实的Direct3D 12运行库和驱动上。

3DMark——多线程能力 + CPU利用率提升50%

如果你是个玩家,你一定知道什么是3DMark——在硬件和设备上进行游戏性能评测的好方式。在这里,我们要用3DMark来检验Direct3D 12能给游戏带来多少性能提升。3DMark的Direct3D 11版本虽然广泛地使用了多线程,但因为运行库和驱动都有开销,每个核上仍然有很多空闲时间。当移植到Direct3D 12之后,我们看到了两个大的改善——CPU利用率提高了50%,以及任务更好地在线程之间分布。

Direct3D 11

Direct3D 12

Forza Motorsport 5技术演示——让PC达到游戏机级别的效率

Forza Motorsport 5是一个用快节奏的真实赛车体验把Xbox One发挥到极限的游戏。在内部,Forza是通过调用Xbox One上高效的底层API来做到这一点。传统上,这样的高效性只会在游戏机上出现。而现在,即便只是alpha版的Direct3D 12,也能把这种高效带到PC和手机平台。通过把Xbox One上的Direct3D 11.X核心渲染引擎移植到PC上的Direct3D 12,Turn 10工作室已经让PC的技术演示也能有游戏机级别的效率。

性能来自何处?

Direct3D 12和Direct3D 11的编程模型很不同,允许程序比以前更接近硬件。我们因此大幅修改了API的很多地方。这里提供了一个概述,总结了三个关键部分:流水线状态的表达、任务提交和资源访问。

流水线状态对象

在Direct3D 11中,流水线状态通过一大堆独立无关的对象来操控。比如, input assembler状态、pixel shader状态、rasterizer状态、以及output merger状态都是可以独立修改的。这给图形流水线提供了一个方便而相对高层的表达。但是,这不能很好地映射到现代的硬件上。这主要是因为不同的状态之间经常有相互依赖。比如,很多GPU把pixel shader和output merger状态合并成了单个硬件,但因为Direct3D 11允许分开设置,驱动在状态最终确定前,也就是draw call的时候,是无法提前设置硬件状态的。这会让硬件状态设置产生延迟,也就是额外的开销,造成每帧的draw call变少。

Direct3D 12通过把多个流水线状态统一成一个流水线状态对象(PSO)来解决这个问题。这个对象在建立后就不可改变,表达了所有状态的最终取值。这让硬件和驱动可以立刻把PSO转化成GPU执行所需的硬件原生指令和状态。动态切换PSO的时候,硬件只需要把少量预计算的状态直接拷贝到硬件寄存器,而不用每次都重新计算硬件状态。这意味着可以明显减少draw call的开销,以提高每帧的draw call数量。

命令列表和命令包

在Direct3D 11里,所有的任务提交都是通过immediate context来完成的,它代表了一个通向GPU的命令流。游戏也经常用deferred context来充分利用多线程,但和PSO一样, deferred context也不能完美地映射到硬件,所以deferred context能帮忙的事情也相对较少。

Direct3D 12引入了一种新的任务提交模型。它的基础是新的命令列表(command list),包含了需要在GPU上执行一个特定工作的所有信息。每个命令列表都包含了用哪个PSO,需要哪些texture和buffer资源,以及所有draw call的参数。因为每个命令列表都是自我包含的,而且不继承任何状态,所以驱动可以在多个独立线程里提前预计算好所有需要的GPU指令。唯一需要顺序操作的只有最终通过命令队列(command queue)把命令列表提交给GPU的时候,这部分本身就已经相当高效。

除了命令列表之外,Direct3D 12也引入了第二层任务预计算机制,命令包(bundle)。命令列表是完全自我包含的,典型用法是构造、提交一次、丢弃。与之不同的是,命令包允许状态继承,更方便重用。比如,如果一个游戏要画两个纹理不同的人物模型,方法之一是记录一个命令列表,包含两组相同的draw call。另一种方法是把画单个人物模型命令“记录”到一个命令包里,然后在命令列表上用不同的资源“播放”这个命令包两次。对后者来说,驱动仅需要计算一次相应的指令,然后建立一个只包含两次低开销函数调用的命令列表。

描述库和描述表

Direct3D 11中的资源绑定非常抽象和方便,但很多现代硬件的能力都被浪费了。在Direct3D 11里,游戏建立出资源的“view”对象,然后把这些view绑到流水线中不同shader的“slot”上。Shader在draw的时候就从显式绑定的slot中读取数据。这个模型意味着只要游戏想要换个资源绘制,就必须重新把不同的view绑定到不同的slot上,然后才能绘制。这个开销也可以通过充分利用现代硬件的能力来去除。

Direct3D 12把绑定模型改成符合现代硬件的样子,从而显著提高性能。Direct3D 12不再需要独立的资源view并显式映射到slot,而是提供了一个描述库(descriptor heap),让游戏可以在里面建立各种资源view。这个机制让GPU可以提前把硬件原生的资源描述直接写入内存。要声明哪个资源被某个draw call的流水线用到了,游戏需要在描述库的某个区域设立一个或多个描述表。因为描述库中已经被提前写入硬件相关的描述数据,所以更改描述表来引用不同描述数据的开销相当低。

除了用描述库和表提高性能之外,Direct3D 12还允许资源在shader中动态索引,由此带来了空前的灵活性,并使新的渲染技术成为可能。比如,现代的延迟渲染引擎往往把材质和物体ID编码到某个中间g-buffer上。在Direct3D 11中,引擎必须避免使用太多材质,因为在一个g-buffer中包含太多材质会显著低降慢最终的渲染。如果有了动态索引资源,渲染包含上千种材质的场景可以和渲染只包含十种材质的场景一样快。

想了解更多?

订阅这个blog http://blogs.msdn.com/b/directx/rss.aspx

关注我们@DirectX12

参加//build

AMD发布会 – DirectX12

NVIDIA的blog – DirectX 12

想要第一批尝鲜?

你是专业游戏开发人员吗?你是否认为Direct3D 12有助于改善你的游戏的性能?点击这里申请加入DirectX 12抢先体验项目。

隐私条款

FAQ

Q:是否应该等一等再买新的PC或者显卡
A:不需要。你的新PC包含支持DirectX 12的图形硬件(包括市面上超过80%的游戏PC),就可以享受所有DirectX 12游戏。

Q:DirectX 12是否包含了Direct3D 12之外的其他东西?
A:同时还有给开发人员准备的最前沿的图形工具。目前的DirectX 12只是个预览,仅专注于Direct3D 12,其他技术会在以后揭示。

Q:什么时候能用上DirectX 12?
A:我们的目标是2015年年底的游戏。

Q:什么硬件能支持Direct3D 12 /现有的硬件是否可以支持Direct3D 12?
A:这需要访问硬件合作伙伴的网站,他们会宣布能支持Direct3D 12的硬件。