交换链

交换链控制反向缓冲区轮转,构成图形动画的基础。

概述

Direct3D 12 中交换链的编程模型与早期版本的 D3D 中的编程模型不同。 例如,不再支持 D3D10 和 D3D11 中存在的支持自动资源轮换的编程便利性。 自动资源旋转确保应用能够呈现相同的 API 对象,而实际呈现的表面会改变每一帧。 Direct3D 12 更改交换链的行为,使 Direct3D 12 的其他功能能够降低 CPU 开销。 不支持自动颜色键和多重采样,尽管仍支持拉伸和旋转。

缓冲区生存期

应用可以存储引用后台缓冲区的预创建描述符。其实现方式为确保交换链拥有的缓冲区集在交换链的生存期内不会更改。 IDXGISwapChain::GetBuffer 返回的缓冲区集在调用某些 API 之前不会更改:

GetBuffer 返回的缓冲区顺序永远不会更改

IDXGISwapChain3::GetCurrentBackBufferIndex 将当前后台缓冲区的索引返回给应用

交换效果

唯一支持的交换效果是 DXGI_SWAP_EFFECT_FLIP_SEQUENTIALDXGI_SWAP_EFFECT_FLIP_DISCARD,这要求缓冲区计数大于 1。

窗口模式和全屏模式之间转换

Direct3D 12 不支持 FSE) (全屏独占模式。 相反,当游戏是屏幕上唯一可见的应用程序时,OS 会使用称为全屏优化 (FSO) 的策略来实现与 FSE 类似的效果,而不会造成性能缺陷。 有关 FSO 的详细信息,请参阅 揭秘全屏优化

Direct3D 12 保留了在窗口模式和全屏模式之间转换后应用程序必须调用 ResizeBuffers 的限制, (D3D11 翻转模型交换链) 具有相同的限制。

IDXGISwapChain::SetFullscreenState 切换不会更改交换链中的应用可见缓冲区集合。 仅 ResizeBuffersResizeTarget 调用可创建或销毁应用可见缓冲区。 但是,在 Direct3D 12 IDXGISwapChain::SetFullscreenState 中,不会进入全屏独占模式,只是更改分辨率和刷新率以允许全屏优化。 应用可以在不使用此方法的情况下进行这些更改

调用或 IDXGISwapChain::P resentIDXGISwapChain1::P resent 时,要显示的后台缓冲区必须处于 D3D12_RESOURCE_STATE_PRESENT 状态。 如果不是这样,则存在将失败并 DXGI_ERROR_INVALID_CALL

全屏交换链仍具有这样的限制:必须在交换链最终发布之前调用 SetFullscreenState (FALSE、NULL)SetFullscreenState (FALSE) 在 Direct3D 12 设备上运行的交换链上成功。

演示操作发生在交换链创建时提供的 3D 队列上,应用可以自由地同时呈现多个交换链,并记录和执行命令列表。

例如,当图形的最后一部分工作 (帧后处理) 在计算队列上完成,或者不涉及设备的图形队列时,创建要呈现的第二个 3D 队列会很有用,并防止延迟下一帧开始的呈现延迟。

示例

以下示例代码将在主渲染循环中显示:

void Present()
{
    m_swapChain->Present(0, m_presentFlags);
    m_backBufferIndex = (m_backBufferIndex + 1) % m_backBufferCount;
}

创建交换链

使用 CreateSwapChainForHwndCreateSwapChainForCoreWindowCreateSwapChainForComposition 调用时,请注意,pDevice 参数实际上需要指向 Direct3D 12 中直接命令队列(而不是设备)的指针

在 Windows 7 上演示

在 Windows 7 上面向 Direct3D 12 时,不存在 Direct3D 12 所需的 DXGI 类型,因此必须使用 D3D12On7 提供的 ID3D12CommandQueueDownLevel (从直接命令队列) 进行查询。

你向 Windows 7 演示方法提供一个打开的命令列表,然后,该方法将被使用、关闭并自动提交到设备。 必须提供一个后台缓冲区,该缓冲区必须是应用创建、必须是已提交的资源、必须单采样,并且必须是以下格式之一。

  • DXGI_FORMAT_R16G16B16A16_FLOAT
  • DXGI_FORMAT_R10G10B10A2_UNORM
  • DXGI_FORMAT_R8G8B8A8_UNORM
  • DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
  • DXGI_FORMAT_B8G8R8X8_UNORM
  • DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
  • DXGI_FORMAT_B8G8R8A8_UNORM
  • DXGI_FORMAT_B8G8R8A8_UNORM_SRGB