1

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

  1. D3D12_DESCRIPTOR_HEAP_DESC 与 D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_RTV
  2. ID3D12Device::CreateDescriptorHeap
  3. 带有 ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart 的 D3D12_CPU_DESCRIPTOR_HANDLE(可能还有 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 很重要?)

4

1 回答 1

5

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

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

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

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

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

Present如果您不需要用户查看结果,则不必使用您的渲染目标。

内存管理策略

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

Direct3D 12 入门

如果您是 DirectX 12 的新手,您应该看到DirectX Tool Kit for DirectX 12教程。如果您还不熟悉 DirectX 11,您应该等待 DirectX 12 并从DirectX Tool Kit for DirectX 11开始。

于 2017-02-04T18:43:58.723 回答