什么是 ID3D12GraphicsCommandList::DiscardResource?

What is ID3D12GraphicsCommandList::DiscardResource?

使用 DiscardResource 时我究竟应该期待发生什么?

丢弃和 destroying/deleting 资源有什么区别。

什么时候是丢弃资源的好time/use-case?

不幸的是,除了它 "discards a resource"。

微软似乎并没有多说它

TL;DR: 是一个很少使用的函数,它提供与处理清晰压缩结构相关的驱动程序提示。除非基于特定的性能建议,否则您不太可能使用它。

DiscardResource是Direct3D 11.1方法的DirectX 12版本。参见 Microsoft Docs

这些方法的主要用途是通过在出现后丢弃渲染目标来优化 tiled-based 延迟光栅化图形部件的性能。这是给driver的一个提示,render target的内容已经和程序的运行无关了,可以避免下次使用时进行一些内部清空操作。

对于 DirectX 11,这是在 DirectX 11 应用程序模板中使用 DiscardView 因为它使用了 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL:

void DX::DeviceResources::Present() 
{
    // The first argument instructs DXGI to block until VSync, putting the application
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
    // frames that will never be displayed to the screen.
    DXGI_PRESENT_PARAMETERS parameters = { 0 };
    HRESULT hr = m_swapChain->Present1(1, 0, &parameters);

    // Discard the contents of the render target.
    // This is a valid operation only when the existing contents will be entirely
    // overwritten. If dirty or scroll rects are used, this call should be removed.
    m_d3dContext->DiscardView1(m_d3dRenderTargetView.Get(), nullptr, 0);

    // Discard the contents of the depth stencil.
    m_d3dContext->DiscardView1(m_d3dDepthStencilView.Get(), nullptr, 0);

    // If the device was removed either by a disconnection or a driver upgrade, we 
    // must recreate all device resources.
    if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
    {
        HandleDeviceLost();
    }
    else
    {
        DX::ThrowIfFailed(hr);
    }
}

DirectX 12 应用程序模板不需要这些显式调用,因为它使用 DXGI_SWAP_EFFECT_FLIP_DISCARD

If you are wondering why the DirectX 11 app doesn't just use DXGI_SWAP_EFFECT_FLIP_DISCARD, it probably should. The DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL swap effect was the only one supported by Windows 8.x for Windows Store apps, which is when DiscardView was introduced. For Windows 10 / DirectX 12 / UWP, it's probably better to always use DXGI_SWAP_EFFECT_FLIP_DISCARD unless you specifically don't want the backbuffer discarded.

它对于 multi-GPU SLI / Crossfire 配置也很有用,因为清除操作可能需要 GPU 之间的同步。参见 this GDC 2015 talk

还有其他scenario-specific用法。例如,如果对 G-buffer 进行延迟渲染,您知道每个像素都将被覆盖,则可以使用 DiscardResource 而不是 ClearRenderTargetView / ClearDepthStencilView.