【译】Import Changes from Direct3D 11 to Direct3D 12

译者:林公子

出处:木木的二进制人生

转载请注明作者和出处,谢谢!

这是微软公布的Direct3D 12文档的其中一篇,此翻译留作学习记录备忘,水平有限,错漏难免,还望海涵。   

  原文链接是https://msdn.microsoft.com/en-us/library/windows/desktop/dn899194(v=vs.85).aspx

Direct3D 12到Direct3D 11的重大改变

Direct3D 12是对Direct3D 11编程模型的一个巨大颠覆。Direct3D 12让应用程序比以往更接近硬件底层。通过接近底层,Direct3D 12更加的快速和高效。不过你的应用程序使用Direct3D 12带来的速度和效率提升相应的代价是你要比使用Direct3D 11负责更多的工作。

Direct3D 12是底层编程的回归。通过引入这些新特性,它给予你对游戏和应用程序中图形元素的更多的控制: 用于代表管线整体状态的的对象,用于任务提交的command list和bundles,用于资源访问的descriptor heap/table。

Direct3D 12 vs Direct3D 11的取舍

使用Direct3D 12你的应用程序的速度和效率得到了提升,不过你要负责相对与Direct3D 11更多的工作。

l 在Direct3D 12中,CPU-GPU的同步明确由应用程序负责,不再像Direct3D 11中由运行时隐式执行。这也意味着Direct3D 12没有对pipeline hazard的自动检查,因此这也成为了应用程序的职责。

l 在Direct3D 12中,应用程序负责管线数据更新。也就是Direct3D 11中的"Map/Lock-Discard"模式在Direct3D 12中必须手动进行。在Direct3D 11中,当你使用D3D11_MAP_WRITE_DISCARD标识调用ID3D11DeviceContext::Map时,运行时返回一个新内存区块的指针代替旧的缓冲数据。这让GPU能够在应用程序往新缓冲填充数据的同时使用旧的数据。应用程序不需要额外的内存管理。旧的缓冲在GPU使用完后会自动销毁或重用。

l 在Direct3D 12中,所有的动态更新(包括constant buffer,dynamic vertex buffer,dynamic textures等等)明确由应用程序来控制。这些动态更新包括任何请求的GPU fence和buffer。应用程序有责任保证内存在使用完之前是有效的。

l Direct3D 12只将COM风格的引用计数用于interface的生命周期(通过Direct3D的弱引用模型关联到device的生命周期)。所有的resource和description内存生命周期由应用程序来负责保证适当的存活时间,而且它们都没有使用引用计数。Direct3D 11也使用引用计数来管理interface相关的对象。

管线状态对象

Direct3D11允许使用大量独立的对象的集合来操纵管线状态。例如,input assembler state,pixel shader state,rasterizer state和output merge state都能够独立的进行修改。这种设计提供了便利性和相对高层的图形管线表示。但是没有利用现代硬件的能力。主要是各种各样的state通常是互相关联的。例如,很多GPU将pixel shader和output merger state合并为一个硬件表示。然而因为Direct3D 11 API这些管线阶段状态被分别设置,显示驱动不能决议管线状态直到状态最后确定下来,而这要等到绘制的时候。这种规划延迟了硬件的状态设置,也就意味着额外的开销和更少的每帧DP。

Direct3D 12通过将大部分管线状态统一到不可变的管线状态对象(PSOs)来解决这个问题,PSOs在创建的时间就决定了。硬件和驱动能够立即将PSO转换为用来驱动GPU工作的硬件本地指令和状态。你仍然可以动态切换使用的PSO。这么做硬件只需要直接拷贝最少的预计算状态到硬件寄存器,而不是实时计算硬件状态。通过使用PSOs,DP的开销显著的减少,然后每帧可以有更多的DP。更多关于PSOs的信息见Managing graphics pipeline state in Direct3D 12. 。

命令列表和集合(bundle)

在Direct3D 11中,所有的任务提交都通过immediate context完成,immediate context代表了一条送往GPU的指令流。要实现多线程,游戏还有deferred context可以使用。Direct3D 11中的Deferred Context不能完美的映射到硬件,所以它们能做的事情有限。

Direct3D 12引入了给予命令列表的任务提交模型。命令列表包含了在GPU上执行一个具体工作所需的所有信息。每个命令列表包含的信息有使用哪个PSO,需要什么纹理和缓冲资源和所有DP的参数。因为每个命令列表是自包含的并且没有状态继承。驱动能够预先计算所有需要的GPU命令,并且是以一种自由线程化(free-threaded)的方式。接下来唯一需要进行的处理是通过命令队列将命令列表最终提交到GPU。

除了命令列表,Direct3D 12还引入了一个二级的任务预计算方式:bundle。不像命令列表,完全的自包含,一般性的被构造,提交一次然后丢弃,bundle提供了某种形式的状态继承来允许复用。例如,如果游戏想要用不同的纹理绘制两个角色模型。一种方法是用一个命令列表记录两组完整一样的DP。另一种方法是记录一个绘制单一角色模型的bundle,然后用不同的资源在命令列表上“回放”bundle两次。在后一种情况下,显示驱动只需要计算相应的指令一次,而创建命令列表本质上相当于两个低开销的函数调用。

更多关于命令列表和bundle的信息,见Work Submission in Direct3D 12。

描述符堆和表(Descriptor Heap and Table)

Direct3D 11中的资源绑定高度抽象和便利,却留下很多现代硬件能力没有被利用到。在Direct3D 11中,游戏创建资源的视图对象,然后绑定这些视图到管线中不同shader阶段的slot中。然后Shader从显式绑定的 slot读取数据,这些绑定slot在绘制时是固定的。这个模型意味着每当游戏使用不同的资源绘制,它必须重新绑定不同的视图到不同的slot,然后再次调用绘制函数。这种情况也表现出额外的开销能够通过完全利用硬件能力来消除。

Direct3D 12改变了绑定模型来匹配现代硬件并显著的提升了性能。和需要独立的资源视图和显式的绑定到slot相反,Direct3D 12提供了一个descriptor heap用来创建游戏中不同的资源。这个方案提供了一种机制让GPU预先直接写入硬件本地资源描述(descriptor)到内存。因为descriptor heap已经被恰当的特定于硬件的descriptor数据填充,改变descriptor table是消耗相当低的操作

除了由descriptor heap和table带来的性能提升。Direct3D 12还允许资源在shader里被动态的索引,这提供了空前的灵活性并开启了新渲染技术的大门。举例来说,现代延迟渲染引擎一般将一个某种形式的材质或物体标识符编码到中间的G-Buffer。在Direct3D 11中,这些引擎必须小心的避免使用太多的材质,因为在一个G-Buffer中包含太多会极大的影响最终渲染pass的速度。有了能动态索引的资源,一个有上千材质的场景能够最终和只有十个材质的场景一样快。

更多关于descriptor head和table的信息,见Resource Binding

时间: 2024-10-11 10:44:53

【译】Import Changes from Direct3D 11 to Direct3D 12的相关文章

[转]Direct3D 11 Tessellation Tutorial

The new hardware tessellation feature available on Direct3D 11 video cards has great potential, but using it effectively currently requires understanding higher-order surfaces as well as a myriad of performance implications. In addition to the Window

Direct3D 11第四节 3D Spaces

引言 3D 坐标系 Object Space对象坐标系 World Space世界坐标系 View Space视坐标系 坐标系转换 World Transformation世界变换 View Transformation视变换 Projection Transformation投影变换 使用变换 修改顶点缓存 修改顶点着色器 设置矩阵 更新常量缓存 引言 这节,我们将深入研究3D位置和转换.这节的目标就是将一个3D物体绘制到屏幕上. 3D 坐标系 为了在世界中的某个位置放一个物体,我们需要使用坐

03. Initializing Direct3D 11

全局变量 IDXGISwapChain* SwapChain; ID3D11Device* d3d11Device; ID3D11DeviceContext* d3d11DevCon; ID3D11RenderTargetView* renderTargetView; float red = 0.0f; float green = 0.0f; float blue = 0.0f; int colormodr = 1; int colormodg = 1; int colormodb = 1; 函

Direct3D 11 Tutorial 2: Rendering a Triangle_Direct3D 11 教程2:渲染一个三角形

概要 在之前的教程中,我们建立了一个最小的Direct3D 11的应用程序,它用来在窗口上输出一个单一颜色.在本次教程中,我们将扩展这个应用程序,在屏幕上渲染出一个单一颜色的三角形.我们将通过设置数据机构的过程关联到三角形. 这个教程的输出结果是在窗口中央渲染出一个三角形. 资源目录 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial02 Github-LearnDirectX-DX3D11 tutorial02 (源码已上传至Github)

Direct3D 11 Tutorial 3: Shaders and Effect System_Direct3D 11 教程3:着色器和效果系统

概述 在上一个教程中,我们设置了一个顶点缓冲区并将一个三角形传递给GPU. 现在,我们将逐步完成图形管道并查看每个阶段的工作原理. 将解释着色器和效果系统的概念. 请注意,本教程与前一个源代码共享相同的源代码,但将强调不同的部分. 资源目录 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial03 Github仓库 图形管道 在上一个教程中,我们设置顶点缓冲区,然后将顶点布局与顶点着色器相关联. 现在,我们将解释着色器是什么以及它是如何工作的.

Direct3D 11 Tutorial 4: 3D Spaces_Direct3D 11 教程4:3D空间

概述 在上一个教程中,我们在应用程序窗口的中心成功渲染了一个三角形. 我们没有太注意我们在顶点缓冲区中拾取的顶点位置. 在本教程中,我们将深入研究3D位置和转换的细节. 本教程的结果将是渲染到屏幕的3D对象. 虽然之前的教程侧重于将2D对象渲染到3D世界,但在这里我们展示了一个3D对象. 资源目录 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial04 Github仓库 3D空间 在上一个教程中,三角形的顶点被有策略地放置,以在屏幕上完美地对

Direct3D 11 Tutorial 5: 3D Transformation_Direct3D 11 教程5:3D转型

概述 在上一个教程中,我们从模型空间到屏幕渲染了一个立方体. 在本教程中,我们将扩展转换的概念并演示可以通过这些转换实现的简单动画. 本教程的结果将是围绕另一个轨道运行的对象. 展示转换以及如何将它们组合以实现期望的效果将是有用的. 在我们介绍新概念时,未来的教程将在此基础上构建. 资源目录 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial05 Github 转型 在3D图形中,变换通常用于对顶点和矢量进行操作. 它还用于将它们在一个空间中

【译】 AWK教程指南 11递归程序

awk 中除了函数的参数列表(Argument List)上的参数(Arguments)外,所有变量不管于何处出现,全被视为全局变量.其生命持续至程序结束--该变量不论在function外或 function内皆可使用,只要变量名称相同所使用的就是同一个变量,直到程序结束.因递归函数内部的变量,会因它调用子函数(本身)而重复使用,故编写该类函数时应特别留心. 例如:执行 awk ' BEGIN { x = 35 y = 45 test_variable( x ) printf("Return t

Direct3D 11 Tutorial 6:Lighting_Direct3D 11 教程6:灯光

概述 在之前的教程中,世界看起来很无聊,因为所有对象都以相同的方式点亮. 本教程将介绍简单照明的概念及其应用方法. 使用的技术将是朗伯照明. 本教程的结果将修改前面的示例以包含光源. 该光源将附在轨道上的立方体上. 可以在中心立方体上看到光的影响. 资源目录 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial06 Github 灯光 在本教程中,将介绍最基本的照明类型:朗伯照明. 无论距离光线的距离如何,朗伯照明都具有均匀的强度. 当光照射到