其实到写这篇文章的时候,DXGI已经出1.5版了,但很多朋友实际上还在用1.2甚至1.1,所以现在谈1.4一点也不过时,而且1.4又是一次非常重大的更新,很值得仔细谈谈。

为了支持Direct3D 12(DXGI还处于1.4版本的时候,Direct3D还按照老命名方式叫Direct3D 12,现在已统一更名为DirectX 12),DXGI加入了一下这些新功能:

  • 更廉价的适配器枚举机制
  • 视频内存预算追踪
  • Direct3D 12Swapchain 改进
  • 相关话题

更廉价的适配器枚举机制

在Direct3D 12里已经不能从device反向追踪创建它的IDXGIAdapter适配器对象了。在调用D3D12CreateDevice的时候也不能指定D3D_DRIVER_TYPE_WARP了。但你可以用IDXFactory4去处理这些事。IDXGIFactory4::EnumAdapterByLuid可以在D3D 12环境下追踪创建device的adapter(与ID3D12Device::GetAdapterLuid结对使用)。如果想让D3D12CreateDevice使用WARP渲染器,要用到IDXGIFactory4::EnumWarpAdapter提供的适配器(Adapter)。

视频内存预算追踪

微软建议开发者在处理视频内存时使用他们设计的预约内存系统,这样能告知操作系统为开发者预留应用所需要的最低内存。(这是一种很好的机制,但也有些限制)

一个系统能为某个应用提供的物理内存数量叫做这个应用的“视频内存预算(video memory budget)”。当后台进程唤醒或睡眠的时候预算会出现极大的波动;当终端用户切换进程的时候预算会急剧变化。应用此时会被系统通知并进行统计当前消费内存和预算内存。应用如果觉得预算不够,就会休眠并允许其他应用执行,当时调用的创建类函数也有可能返回错误。IDXGIAdapter3就与此事有关,尤其是QueryVideoMemoryInfo和RegisterVideoMemoryBudgetChangeNotificationEvent。

更多相关信息查看这里:Residency

Direct3D 12Swapchain 改进

为了减小开销,在D3D12中,有些D3D11时代的swapchain功能不建议再使用了。为了更好地对应D3D12中的新概念以及为新功能服务,微软还对API做了其他一些调整,

恒定backbuffer一致

在D3D11,应用只能调用GetBUffer(0,…)一次。每次调用Present都隐含着修改了返回接口的一致性。由于CPU开销需求和弹性的资源描述符设计,D3D12不再支持这种隐性资源一致性变更。那么应用就需要为每块和swapchain一起创建的buffer手动调用GetBuffer。应用也得手动渲染在Present操作之后的队列中的buffer。微软也鼓励开发者不要每次Present就重建很多对象,而是给每个缓冲区(buffer)缓存(cache)。

多适配器支持

在多GPU适配器环境下,backbuffer只从节点1创建,并且只有一个命令队列(command queue,这在DirectX中是相当重要的概念,尤其是多线程多适配器多显示器的环境中)ResizeBuffer允许应用在其他节点创建backbuffer,还允许给每个backbuffer使用不同的命令队列。这些功能与swapchain一起构建了交替帧渲染(AFR)技术。更多请看Direct3D 12 Multi-Adapters

杂项

  • 命令队列不再传给D3D的device对象而一定要传给CreateSwapChain方法。
  • 只支持以下两个flip mode swap effects:
  • SetFullscreenState对显示不再具备排斥性,所以用户初始化的操作系统元素可以无缝显示在应用输出的前面。比如说体设定(Volume Settings)。

相关话题

Direct3D 12 Hardware Feature Levels
Programming Guide for DXGI
05-11 11:16