mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
Use flip model for swapchain, render to intermediate target then copy
This commit is contained in:
@@ -93,12 +93,53 @@ D3D12DebugManager::~D3D12DebugManager()
|
||||
RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this);
|
||||
}
|
||||
|
||||
void D3D12DebugManager::OutputWindow::MakeRTV(bool multisampled)
|
||||
{
|
||||
SAFE_RELEASE(col);
|
||||
|
||||
D3D12_RESOURCE_DESC texDesc = bb[0]->GetDesc();
|
||||
|
||||
texDesc.SampleDesc.Count = multisampled ? 4 : 1;
|
||||
texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps;
|
||||
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
heapProps.CreationNodeMask = 1;
|
||||
heapProps.VisibleNodeMask = 1;
|
||||
|
||||
HRESULT hr = dev->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &texDesc,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET, NULL,
|
||||
__uuidof(ID3D12Resource), (void **)&col);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create colour texture for window, HRESULT: 0x%08x", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
dev->CreateRenderTargetView(col, NULL, rtv);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create RTV for main window, HRESULT: 0x%08x", hr);
|
||||
SAFE_RELEASE(swap);
|
||||
SAFE_RELEASE(col);
|
||||
SAFE_RELEASE(depth);
|
||||
SAFE_RELEASE(bb[0]);
|
||||
SAFE_RELEASE(bb[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12DebugManager::OutputWindow::MakeDSV()
|
||||
{
|
||||
SAFE_RELEASE(depth);
|
||||
|
||||
D3D12_RESOURCE_DESC texDesc = bb->GetDesc();
|
||||
D3D12_RESOURCE_DESC texDesc = bb[0]->GetDesc();
|
||||
|
||||
texDesc.SampleDesc.Count = 4;
|
||||
texDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
|
||||
@@ -110,13 +151,13 @@ void D3D12DebugManager::OutputWindow::MakeDSV()
|
||||
heapProps.VisibleNodeMask = 1;
|
||||
|
||||
HRESULT hr = dev->CreateCommittedResource(
|
||||
&heapProps, D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, &texDesc,
|
||||
&heapProps, D3D12_HEAP_FLAG_NONE, &texDesc,
|
||||
D3D12_RESOURCE_STATE_DEPTH_WRITE | D3D12_RESOURCE_STATE_DEPTH_READ, NULL,
|
||||
__uuidof(ID3D12Resource), (void **)&depth);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create DSV texture for main output, HRESULT: 0x%08x", hr);
|
||||
RDCERR("Failed to create DSV texture for output window, HRESULT: 0x%08x", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,10 +165,12 @@ void D3D12DebugManager::OutputWindow::MakeDSV()
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create DSV for main output, HRESULT: 0x%08x", hr);
|
||||
RDCERR("Failed to create DSV for output window, HRESULT: 0x%08x", hr);
|
||||
SAFE_RELEASE(swap);
|
||||
SAFE_RELEASE(col);
|
||||
SAFE_RELEASE(depth);
|
||||
SAFE_RELEASE(bb);
|
||||
SAFE_RELEASE(bb[0]);
|
||||
SAFE_RELEASE(bb[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -145,15 +188,15 @@ uint64_t D3D12DebugManager::MakeOutputWindow(void *w, bool depth)
|
||||
GetClientRect(outw.wnd, &rect);
|
||||
|
||||
swapDesc.BufferCount = 2;
|
||||
swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||
swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
outw.width = swapDesc.BufferDesc.Width = rect.right - rect.left;
|
||||
outw.height = swapDesc.BufferDesc.Height = rect.bottom - rect.top;
|
||||
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapDesc.SampleDesc.Count = depth ? 4 : 1;
|
||||
swapDesc.SampleDesc.Count = 1;
|
||||
swapDesc.SampleDesc.Quality = 0;
|
||||
swapDesc.OutputWindow = outw.wnd;
|
||||
swapDesc.Windowed = TRUE;
|
||||
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapDesc.Flags = 0;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
@@ -166,7 +209,10 @@ uint64_t D3D12DebugManager::MakeOutputWindow(void *w, bool depth)
|
||||
return 0;
|
||||
}
|
||||
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb);
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb[0]);
|
||||
outw.swap->GetBuffer(1, __uuidof(ID3D12Resource), (void **)&outw.bb[1]);
|
||||
|
||||
outw.bbIdx = 0;
|
||||
|
||||
outw.rtv = rtvHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
outw.rtv.ptr += m_OutputWindowID *
|
||||
@@ -176,7 +222,9 @@ uint64_t D3D12DebugManager::MakeOutputWindow(void *w, bool depth)
|
||||
outw.dsv.ptr += m_OutputWindowID *
|
||||
m_WrappedDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
|
||||
|
||||
m_WrappedDevice->CreateRenderTargetView(outw.bb, NULL, outw.rtv);
|
||||
outw.col = NULL;
|
||||
outw.MakeRTV(depth);
|
||||
m_WrappedDevice->CreateRenderTargetView(outw.col, NULL, outw.rtv);
|
||||
|
||||
outw.depth = NULL;
|
||||
if(depth)
|
||||
@@ -196,7 +244,9 @@ void D3D12DebugManager::DestroyOutputWindow(uint64_t id)
|
||||
OutputWindow &outw = it->second;
|
||||
|
||||
SAFE_RELEASE(outw.swap);
|
||||
SAFE_RELEASE(outw.bb);
|
||||
SAFE_RELEASE(outw.bb[0]);
|
||||
SAFE_RELEASE(outw.bb[1]);
|
||||
SAFE_RELEASE(outw.col);
|
||||
SAFE_RELEASE(outw.depth);
|
||||
|
||||
m_OutputWindows.erase(it);
|
||||
@@ -226,7 +276,8 @@ bool D3D12DebugManager::CheckResizeOutputWindow(uint64_t id)
|
||||
|
||||
if(outw.width > 0 && outw.height > 0)
|
||||
{
|
||||
SAFE_RELEASE(outw.bb);
|
||||
SAFE_RELEASE(outw.bb[0]);
|
||||
SAFE_RELEASE(outw.bb[1]);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
outw.swap->GetDesc(&desc);
|
||||
@@ -240,11 +291,20 @@ bool D3D12DebugManager::CheckResizeOutputWindow(uint64_t id)
|
||||
return true;
|
||||
}
|
||||
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb);
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb[0]);
|
||||
outw.swap->GetBuffer(1, __uuidof(ID3D12Resource), (void **)&outw.bb[1]);
|
||||
|
||||
outw.bbIdx = 0;
|
||||
|
||||
m_WrappedDevice->CreateRenderTargetView(outw.bb, NULL, outw.rtv);
|
||||
if(outw.depth)
|
||||
{
|
||||
outw.MakeRTV(true);
|
||||
outw.MakeDSV();
|
||||
}
|
||||
else
|
||||
{
|
||||
outw.MakeRTV(false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -301,27 +361,11 @@ void D3D12DebugManager::BindOutputWindow(uint64_t id, bool depth)
|
||||
|
||||
OutputWindow &outw = m_OutputWindows[id];
|
||||
|
||||
if(outw.bb == NULL)
|
||||
if(outw.bb[0] == NULL)
|
||||
return;
|
||||
|
||||
m_width = (int32_t)outw.width;
|
||||
m_height = (int32_t)outw.height;
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = Unwrap(m_OutputWindows[id].bb);
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
|
||||
m_WrappedDevice->GetList()->Reset(m_WrappedDevice->GetAlloc(), NULL);
|
||||
|
||||
m_WrappedDevice->GetList()->ResourceBarrier(1, &barrier);
|
||||
|
||||
m_WrappedDevice->GetList()->Close();
|
||||
|
||||
ID3D12CommandList *list = (ID3D12CommandList *)m_WrappedDevice->GetList();
|
||||
m_WrappedDevice->GetQueue()->GetReal()->ExecuteCommandLists(1, &list);
|
||||
}
|
||||
|
||||
bool D3D12DebugManager::IsOutputWindowVisible(uint64_t id)
|
||||
@@ -337,24 +381,49 @@ void D3D12DebugManager::FlipOutputWindow(uint64_t id)
|
||||
if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end())
|
||||
return;
|
||||
|
||||
if(m_OutputWindows[id].swap)
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier;
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = Unwrap(m_OutputWindows[id].bb);
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
OutputWindow &outw = m_OutputWindows[id];
|
||||
|
||||
m_WrappedDevice->GetList()->Reset(m_WrappedDevice->GetAlloc(), NULL);
|
||||
if(m_OutputWindows[id].bb[0] == NULL)
|
||||
return;
|
||||
|
||||
m_WrappedDevice->GetList()->ResourceBarrier(1, &barrier);
|
||||
D3D12_RESOURCE_BARRIER barriers[2];
|
||||
RDCEraseEl(barriers);
|
||||
|
||||
m_WrappedDevice->GetList()->Close();
|
||||
barriers[0].Transition.pResource = Unwrap(outw.col);
|
||||
barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
|
||||
ID3D12CommandList *list = (ID3D12CommandList *)m_WrappedDevice->GetList();
|
||||
m_WrappedDevice->GetQueue()->GetReal()->ExecuteCommandLists(1, &list);
|
||||
barriers[1].Transition.pResource = Unwrap(outw.bb[outw.bbIdx]);
|
||||
barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
|
||||
m_OutputWindows[id].swap->Present(0, 0);
|
||||
}
|
||||
m_WrappedDevice->GetList()->Reset(m_WrappedDevice->GetAlloc(), NULL);
|
||||
|
||||
// transition colour to copy source, backbuffer to copy test
|
||||
m_WrappedDevice->GetList()->ResourceBarrier(2, barriers);
|
||||
|
||||
// resolve or copy from colour to backbuffer
|
||||
if(outw.depth)
|
||||
m_WrappedDevice->GetList()->ResolveSubresource(barriers[1].Transition.pResource, 0,
|
||||
barriers[0].Transition.pResource, 0,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
||||
else
|
||||
m_WrappedDevice->GetList()->CopyResource(barriers[1].Transition.pResource,
|
||||
barriers[0].Transition.pResource);
|
||||
|
||||
std::swap(barriers[0].Transition.StateBefore, barriers[0].Transition.StateAfter);
|
||||
std::swap(barriers[1].Transition.StateBefore, barriers[1].Transition.StateAfter);
|
||||
|
||||
// transition colour back to render target, and backbuffer back to present
|
||||
m_WrappedDevice->GetList()->ResourceBarrier(2, barriers);
|
||||
|
||||
m_WrappedDevice->GetList()->Close();
|
||||
|
||||
ID3D12CommandList *list = (ID3D12CommandList *)m_WrappedDevice->GetList();
|
||||
m_WrappedDevice->GetQueue()->GetReal()->ExecuteCommandLists(1, &list);
|
||||
|
||||
outw.swap->Present(0, 0);
|
||||
|
||||
outw.bbIdx++;
|
||||
outw.bbIdx %= 2;
|
||||
}
|
||||
|
||||
@@ -60,13 +60,16 @@ private:
|
||||
{
|
||||
HWND wnd;
|
||||
IDXGISwapChain *swap;
|
||||
ID3D12Resource *bb;
|
||||
ID3D12Resource *bb[2];
|
||||
uint32_t bbIdx;
|
||||
ID3D12Resource *col;
|
||||
ID3D12Resource *depth;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsv;
|
||||
|
||||
WrappedID3D12Device *dev;
|
||||
|
||||
void MakeRTV(bool multisampled);
|
||||
void MakeDSV();
|
||||
|
||||
int width, height;
|
||||
|
||||
Reference in New Issue
Block a user