Direct3D 12 Preview

<span style="font-size:12px;">    在上半年举办的GDC2014大会上,微软提供了一个DirectX12的Preview,同时通过这个preview和稍后的Direct3D 12的API介绍,可以大概看出D3D API所采用的新的tips和technique。主要有以下几点,供大家参考:</span>
<span style="font-size:12px;">一、采用Pipeline State Object(PSO)</span>

    在D3D11及其以前的版本,图形渲染Pipelin中的各个stage都是可以分开设定的,这意味着driver管理这些对应于各stage的binding resource,跟踪这些resource的state和lifetime,并在APP进行Get*命令时提供正在pipeline中的State。这对CPU来说是个巨大的开销,说成是整个D3D的瓶颈也不为过。

    新的D3D12则采用了一种新的PSO的方式,即将整个pileline stages 整合成一个stage

 

这样做的好处在于仅仅需要设置一次PSO的state,就可以将整个pipeline的状态设置完成。表面上这有点返回到Fix-Function的时代,不过实质上这是一个很聪明的选择。根据Max McMullen(chief of Direct3D development team of MS)的介绍,在游戏开发和其他应用程序中,通常stage仅有12种组合,也就是说, 通常IA+VS+Rast+PS是一种组合A,而A+tessellation又是一种组合B,一次类推。因此在设置PSO的状态的时候,也顺带将12种state 组合的硬件状态也设置了,这将带来非常大的好处。

    在硬件条件下,APP的每一次改动对将对应着HW state的reprogram,以及resource的rebinding。而这12种combine state则充分涵盖了绝大部分的app修改,因此不再需要HW的reprogram,不再需要resource的rebinding,只需要更换一个hw state就可以了。由此,CPU的开销将小很多,可以说PSO是D3D12的一个极其重要的tip。在后续介绍的AMD Mantle和Apple Metal中依旧会看到PSO或者换来个马甲的PSO。

二、Descriptor Table & Heaps

    resource binding和switch binding总是一个非常头疼的问题,binding问题已经成为了程序开发人员和架构师最需要考虑的问题。传统方法是: resource想要bind到pipeline,需要创建一个device和一个device context。 而采用HLSL编写的shader需要调用资源时,则需要通过自身的slot和context进行绑定,相当于(本来也是)slot成为resource的传递通道。这带来的问题是,如果frame A和frame B之间享有共同的resource,那该怎么做,如何提高CPU的效率。

   传统的方法是:frame A release binding,frame B 重新bingding,然后通过driver将binding传递给GPU,即使相同的resource也是如此。D3D12当然不会干这种费力不讨好的事情,相对于binding—submit—release—binding,D12采用Descriptor的方式,将resource采用index的方式映射到Descriptor中,比如Vertex映射到Descriptor A1, Vertex Index映射到Descriptor A2中, Texture映射到Descriptor B1中。则A1, A2, B1等的集合就是heap,而GPU中需要采用哪些Descriptor,比如A1,A2而不需要A3则是GPU中的Descriptor Table。这样,frame与frame之间通过转换Table就可以共享resource了,多么简单明了!

三、Bundle

    Bundle是D3D12中最为重要(到目前为止)的一个技术。Descriptor Table & Heaps解决的是resource share的问题,而bundle解决的是command reuse的问题。我们可以将Bundle看成可以构成小的功能模块的command组合。当编写几乎相同的两个渲染命令时,可以适当改变参数而不需要重新编写command。这不仅仅节约空间,更是对CPU效率的大幅度提升。因为app生成命令时,需要对命令进行编译,编译过程中需要跟踪命令执行状态和对条用的资源allocate memory以及命令传递等各种内容。而bundle很好的解决了这个问题,bundle的宗旨是:Recorded once,Reused multiple times!

未使用bundle的代码:

<span style="font-size:12px;">pContext->SetPipelineState(pPSO);
pContext->SetRenderTargetViewTable(0, 1, FALSE, 0);
pContext->SetVertexBufferTable(0, 1);
pContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

// Draw 1
pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1);
pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1);
pContext->DrawInstanced(6, 1, 0, 0);
pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1);
pContext->DrawInstanced(6, 1, 6, 0);

// Draw 2
pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1);
pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1);
pContext->DrawInstanced(6, 1, 0, 0);
pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1);
pContext->DrawInstanced(6, 1, 6, 0);</span>

采用bundle执行Draw1 和Draw2:

<span style="font-size:12px;">// Setup
pContext->SetRenderTargetViewTable(0, 1, FALSE, 0);
pContext->SetVertexBufferTable(0, 1);

// Draw 1 and 2
pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1);
pContext->ExecuteBundle(pBundle);
pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1);
pContext->ExecuteBundle(pBundle);</span>

简单明了清晰~

四、other Tips

 D3D12中也包含了其他的技术,比如Command Buffer& command Queue 等,用于消除更好的执行command,同时让app更为底层。D3D12中也采用了resource barrier的东西,用于避免resource hazard的问题。这些内容将会在后续的Apple Metal中介绍。

五、summary

 D3D12的推出,传言是继承了AMD Mantle的优良品质。通过分析AMD Mantle的new techniques,我几乎可以确定D3D12确实很大程度上依靠了Mantle,他们是如此相像两款sdk。而对于Metal,他也采用了很多的相似的技术,从而获得了30%的性能提高。而Mantle和D3D12则相比于D3D11,获得了近50%的性能提高,这简直不可思议。因此,现在披露的很多技术都将是未来的主流,值得大家好好学习借鉴。

下面是一些链接,可以让大家更了解D3D12:

gdc2014: http://www.gdconf.com/

http://i.isvoc.com/201403243372-direct-12-update-imminent-substantial-increase-in-the-efficiency-of-pc-game-development.html#.U7be40qS3cs

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Direct3D是由Microsoft开发的一种图形API,用于在Windows平台上实现图形渲染功能。Direct3D的源代码是指Direct3D库的实现源代码,这些源代码涵盖了Direct3D的各种功能和算法。Direct3D源码是机密的,并且不可公开,只有经过授权的开发人员才能访问和使用。 Direct3D的源代码提供了对图形硬件的底层访问,开发人员可以使用这些源代码构建图形应用程序,并实现图形渲染、投影、纹理映射、光照等各种图形效果。Direct3D源代码包括了底层的图形操作、纹理管理、三维空间计算等算法,以及与硬件交互的接口。 Direct3D源代码的访问受到严格的控制,只有合作伙伴或授权的开发人员才能查看和修改它。这样可以保护Direct3D的安全性,防止源代码被滥用或恶意利用。通过合理授权和许可,开发人员可以获得Direct3D源代码的访问权,并根据自己的需要进行定制和优化。 Direct3D源代码的使用需要一定的专业知识和经验,开发人员需要熟悉图形编程和底层硬件操作的相关知识。通过研究和理解Direct3D源代码,开发人员可以深入了解Direct3D的工作原理,并开发出更高效、更强大的图形应用程序。 总之,Direct3D源代码是实现Direct3D功能的基础,它提供了底层的图形操作和算法实现。通过合法的授权和许可,开发人员可以使用Direct3D源代码进行图形应用程序的开发和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值