MiniEngine中的命令隊列、命令列表、命令分配器

命令隊列

類名: CommandQueue
GPU會不斷的執行命令隊列中的指令,根據d3dx12.h能夠看到一個GPU維護多種類型的命令隊列ui

命令分配器

類名:CommandAllocatorPool
記錄命令列表插入的GPU指令this

命令列表

類名:CommandListManager
插入GPU指令到命令分配器中3d

圍欄

能夠理解爲特殊的GPU指令,GPU執行到圍欄指令時,會更新圍欄的值,用於判斷GPU執行到了哪一步code

基本流程:

  1. 建立命令隊列、圍欄
  2. 建立命令列表、命令分配器
  3. 命令列表插入須要執行的指令
  4. 命令列表插入圍欄值
  5. 調用ExecuteCommandLists,使GPU開始執行命令列表中記錄的指令。
  6. 此時命令列表已經能夠重置了,可是命令分配器不能夠重置,由於不知道GPU是否是執行完畢了
  7. 命令分配器的重置,能夠選擇死等圍欄值更新,或者新建一個命令分配器開始下一輪的指令插入

MiniEngine:

1. CommandAllocatorPool

命令分配器池子。用於管理生成並複用命令分配器。隊列

2. CommandQueue

命令隊列。根據類型維護一個命令分配器池子、獨立賦值的圍欄string

3. CommandListManager

維護命令隊列。it

MiniEngine基本渲染流程:

1.初始化 CommandListManager::Create

直接生成了3個命令隊列。命令隊列內部有本身的分配器池子、圍欄。
這個會在程序啓動時初始化。io

2.開啓一個繪製 CommandContext::Begin

CommandContext& CommandContext::Begin( const std::wstring ID )
{
    CommandContext* NewContext = g_ContextManager.AllocateContext(D3D12_COMMAND_LIST_TYPE_DIRECT);
    NewContext->SetID(ID);
    if (ID.length() > 0)
        EngineProfiling::BeginBlock(ID, NewContext);
    return *NewContext;
}

AllocateContext中初始化或重置一個命令列表 CommandListManager::CreateNewCommandListclass

3.結束一個繪製 CommandContext::Finish

uint64_t CommandContext::Finish( bool WaitForCompletion )
{
    ...

    CommandQueue& Queue = g_CommandManager.GetQueue(m_Type);

    // 返回本次命令隊列的圍欄值
    uint64_t FenceValue = Queue.ExecuteCommandList(m_CommandList);
    // 這裏面會把命令分配器與圍欄值關聯起來,存到等待隊列中
    // 等下次再想分配一個命令分配器時,會根據已經執行完的圍欄值,來判斷等待隊列中的分配器是否能夠複用
    Queue.DiscardAllocator(FenceValue, m_CurrentAllocator);
    m_CurrentAllocator = nullptr;

    ...

    if (WaitForCompletion)
        g_CommandManager.WaitForFence(FenceValue);

    g_ContextManager.FreeContext(this);

    return FenceValue;
}
相關文章
相關標籤/搜索