c++ - 在交换链中为每个 renderTarget 创建一个分配器是否有意义?

标签 c++ directx-12

The HelloWorld examples from Microsoft大多数情况下使用单个 CommandAllocator,然后等到前一帧完全完成。然而,他们也说(全部大写)这不是应该做的。

所以我的想法是在交换链中为每个帧创建一个分配器,并在循环缓冲区中保留要等待的栅栏值:

struct frame_resources{
    ID3D12Resource* renderTarget;
    ID3D12CommandAllocator* allocator;
    uint64 fenceValue;
} resources[FRAME_COUNT];


uint frameIndex = swapChain->GetCurrentBackBufferIndex();
UINT64 lastFence;
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
    if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        continue;
    }

    if (fence->GetCompletedValue() < resources[frameIndex].fenceValue)
    {
        fence->SetEventOnCompletion(resources[frameIndex].fenceValue, fenceEvent);

        DWORD result = MsgWaitForMultipleObjects(1, &fenceEvent, FALSE, INFINITE, QS_ALLEVENTS);
        if(result == WAIT_OBJECT_0 + 1)
            continue; //message in the queue
    }

    resources[frameIndex].allocator->Reset();

    commandList->Reset(resources[frameIndex].allocator, 0);

    //...

    commandList->Close();
    commandQueue->ExecuteCommandLists(1, &CommandList);

    lastFence++;
    resources[frameIndex].fenceValue = lastFence;
    commandQueue->Signal(fence, lastFence);

    swapChain->Present(0, DXGI_PRESENT_RESTART);
    frameIndex = swapChain->GetCurrentBackBufferIndex();
}

这是明智的做法吗?或者有更好的方法吗?

最佳答案

您现在可能已经找到了答案,但我还是会回答以防万一。当 GPU 可能正在执行存储在与命令分配器关联的内存中的命令列表时,您无法重置命令分配器,因此您的方法是正确的,您需要为每个帧缓冲区设置一个单独的命令分配器。

另一方面,命令列表可以在调用 ExecuteCommandLists() 后立即重置。这意味着虽然每个帧必须有一个命令分配器,但每个“线程”只需要一个命令列表。

命令列表一次只能由一个线程填充,这意味着您需要每个线程有一个命令列表来填充一个命令列表。

所以,你需要有 numFrames*numThreads 命令分配器和 numThreads 命令列表

关于c++ - 在交换链中为每个 renderTarget 创建一个分配器是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34991725/

相关文章:

hlsl - DXR : How to identify the geometry instance of the bottom level AS inside the closest hit shader

c++ - Win32 窗口不显示

c++ - gcc 警告“没有声明任何东西

c++ - 在派生类中初始化基于 C 的 API 提供的基于 C 的 typedef 结构?

c++ - 更新顶点缓冲区会导致调试层错误

DirectX 12 中的多线程

c++ - DirectX 12 开发现在对公众开放了吗?

c++ - conservativeResize() 新值的值为零

C++ STL数据结构对齐,算法向量化

c++ - 如何将指向类方法的指针传递给 boost 线程