在 D3D12 中,渲染目标视图可以是任何缓冲区吗?

Emi*_*mil 1 directx-12

到目前为止,在我查看的示例中,一些命令类似于:

  1. D3D12_DESCRIPTOR_HEAP_DESC 和 D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_RTV
  2. ID3D12Device::CreateDescriptorHeap
  3. D3D12_CPU_DESCRIPTOR_HANDLE 带有 ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart(可能还有 ID3D12Device::GetDescriptorHandleIncrementSize)
  4. (可选?)ID3D12Device::CreateRenderTargetView
    1. (可选?)IDXGISwapChain3::GetBuffer
  5. 将渲染内容安排到命令列表,注意 OMSetRenderTargets 和 DrawInstanced,然后关闭命令列表。
  6. ID3D12CommandQueue::ExecuteCommandLists
    1. (可选?)IDXGISwapChain3::Present
  7. 在栅栏上使用 ID3D12CommandQueue::Signal 调度信号
  8. 等待 GPU 完成 ID3D12Fence::SetEventOnCompletion 和 WaitForSingleObjectEx

如果可能,如何用选择的缓冲区替换步骤 4.1?即如何创建一个 ID3D12Resource* 并呈现给它,然后从中读取到 std::vector 中?(我假设如果这可能,步骤 6.1 可以被忽略,因为交换链没有呈现目标视图。在这种情况下,也许步骤 4 也是不必要的?也许只有 OMSetRenderTargets 重要?)

Chu*_*urn 5

渲染目标的确切位置取决于视频内存架构。在某些系统上,它位于只有视频卡可以访问的专用视频内存中。在某些系统中,它位于 CPU 和 GPU 都可以访问的总线上共享的视频内存中。在统一内存架构中,一切都在系统内存中。

因此,您对渲染目标的确切位置有限制。这就是为什么在创建计划绑定为渲染目标的 ID3D12Resource 时必须使用D3D12_HEAP_TYPE_DEFAULT和指定D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET的原因(这也是在创建交换链渲染目标时由 DXGI 隐式完成的)。

一般来说,您不能也不应该使用低级 DXGI 表面创建 API 来创建 Direct3D 资源。它们主要供系统使用而不是由应用程序使用。

除非您碰巧在 UMA 系统上,否则您应该尽量减少对渲染目标的 CPU 访问,否则它将需要昂贵的副本。即使在 UMA 系统上,也需要去平铺以将结果转化为线性形式。

Direct3D 12 还提供了“放置资源”方法,它可以更好地控制分配内存的确切位置(或更具体地说,分配虚拟内存地址的位置),但您仍然必须遵守底层架构限制。根据内存架构,您可以“别名”多个不同的 ID3D12Resource 实例,它们都使用相同的内存(例如渲染目标被别名为无序访问资源),但您负责将所需的资源屏障插入命令列表(并对其进行测试)以确保它在所有 DX12 硬件上可靠运行。请参阅MSDN

您不必到Present您的渲染目标,如果你不需要用户看到的结果。

内存管理策略

UMA 优化:CPU 可访问纹理和标准 Swizzle

Direct3D 12 入门

如果您不熟悉 DirectX 12,您应该查看DirectX 12教程的DirectX 工具包。如果您还不熟悉 DirectX 11,您应该等待 DirectX 12 并开始使用DirectX Tool Kit for DirectX 11