我設置了一個DX12應用程序,它只在每一幀清除backbuffer。DXGI Waitable SwapChain不等待
它確實是準系統:沒有PSO,沒有根... 唯一的特殊性是它在開始一個新幀之前等待swapChain與Present()完成(我設置了幀等待時間1以及只有2個緩衝區)。
第一幀運行良好,但立即開始繪製第二幀,當然,命令分配器會抱怨它在GPU上仍然執行命令時被重置。
我當然可以設置一個圍欄來等待gpu完成,然後再移動到一個新的框架,但我認爲這是等待交換鏈對象的工作。
這裏是渲染程序:這個程序有一個可等待的對象至極我從swapchain得到
if (m_command_allocator->Reset() == E_FAIL) { throw; }
HRESULT res = S_OK;
res = m_command_list->Reset(m_command_allocator.Get(), nullptr);
if (res == E_FAIL || res == E_OUTOFMEMORY) { throw; }
m_command_list->ResourceBarrier(1,
&CD3DX12_RESOURCE_BARRIER::Transition(m_render_targets[m_frame_index].Get(),
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
m_command_list->RSSetViewports(1, &m_screen_viewport);
m_command_list->RSSetScissorRects(1, &m_scissor_rect);
m_command_list->ClearRenderTargetView(get_rtv_handle(),
DirectX::Colors::BlueViolet, 0, nullptr);
m_command_list->OMSetRenderTargets(1, &get_rtv_handle(), true, nullptr);
m_command_list->ResourceBarrier(1,
&CD3DX12_RESOURCE_BARRIER::Transition(m_render_targets[m_frame_index].Get(),
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
tools::throw_if_failed(m_command_list->Close());
ID3D12CommandList* ppCommandLists[] = { m_command_list.Get() };
m_command_queue->ExecuteCommandLists(_countof(ppCommandLists),
ppCommandLists);
if (m_swap_chain->Present(1, 0) != S_OK) { throw; }
m_frame_index = m_swap_chain->GetCurrentBackBufferIndex();
我循環:
while (WAIT_OBJECT_0 == WaitForSingleObjectEx(waitable_renderer, INFINITE, TRUE) && m_alive == true)
{
m_graphics.render();
}
,我和可等待初始化swapchain標記:
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
swap_chain_desc.BufferCount = s_frame_count;
swap_chain_desc.Width = window_width;
swap_chain_desc.Height = window_height;
swap_chain_desc.Format = m_back_buffer_format;
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swap_chain_desc.SampleDesc.Count = 1;
swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
ComPtr<IDXGISwapChain1> swap_chain;
tools::throw_if_failed(
factory->CreateSwapChainForHwnd(m_command_queue.Get(), window_handle, &swap_chain_desc, nullptr, nullptr, &swap_chain));
我所說的SetFrameLatency創建swapChain之後:
ComPtr<IDXGISwapChain2> swap_chain2;
tools::throw_if_failed(m_swap_chain.As(&swap_chain2));
tools::throw_if_failed(swap_chain2->SetMaximumFrameLatency(1));
m_waitable_renderer = swap_chain2->GetFrameLatencyWaitableObject();
而且swapChain調整是去與它:
tools::throw_if_failed(
m_swap_chain->ResizeBuffers(s_frame_count, window_width, window_height, m_back_buffer_format, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT));
我的問題是:難道我設置的東西了不正確的?或者這是等待交換鏈工作的方式(也就是說,在等待交換鏈變得可用之前,您還需要用隔離與gpu同步)?
編輯:添加SetFrameLatency呼叫+ C++着色
你的代碼似乎要被罰款,但目前尚不清楚是否確實叫'GetFrameLatencyWaitableObject '獲得'waitable_renderer'。 – VTT
我根據您的建議和評論編輯了我的問題。 –