Fix regression in D3D12 on multiple swap chains in use
This commit is contained in:
@@ -32,7 +32,6 @@
|
||||
#include "Engine/Graphics/GPUResourceAccess.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
|
||||
#define DX12_ENABLE_RESOURCE_BARRIERS_BATCHING 1
|
||||
#define DX12_ENABLE_RESOURCE_BARRIERS_DEBUGGING (0 && LOG_ENABLE)
|
||||
@@ -88,6 +87,44 @@ FORCE_INLINE D3D12_RESOURCE_STATES GetResourceState(GPUResourceAccess access)
|
||||
return D3D12_RESOURCE_STATE_COMMON;
|
||||
}
|
||||
|
||||
#if DX12_ENABLE_RESOURCE_BARRIERS_DEBUGGING
|
||||
|
||||
String ResourceStateToString(D3D12_RESOURCE_STATES state)
|
||||
{
|
||||
if (state == D3D12_RESOURCE_STATE_COMMON)
|
||||
return TEXT("Common");
|
||||
String result;
|
||||
while (state)
|
||||
{
|
||||
if (result.HasChars())
|
||||
result += TEXT('|');
|
||||
#define CHECK_STATE(type, name) if ((type & state) == type) { state &= ~type; result += TEXT(name); continue; }
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_GENERIC_READ, "GenericRead");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, "VertexConstantBuffer");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_INDEX_BUFFER, "IndexBuffer");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_RENDER_TARGET, "RenderTarget");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_UNORDERED_ACCESS, "UAV");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_DEPTH_WRITE, "DepthWrite");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_DEPTH_READ, "DepthRead");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, "SRV-PS");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, "SRV-VS");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT, "IndirectArg");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_COPY_DEST, "CopyDst");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_COPY_SOURCE, "CopySrc");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_RESOLVE_DEST, "ResolveDst");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_RESOLVE_SOURCE, "ResolveSrc");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE, "ShadingRate");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE, "RtxAcceleration");
|
||||
CHECK_STATE(D3D12_RESOURCE_STATE_PRESENT, "Present");
|
||||
#undef CHECK_STATE
|
||||
result += TEXT("Unknown");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Ensure to match the indirect commands arguments layout
|
||||
static_assert(sizeof(GPUDispatchIndirectArgs) == sizeof(D3D12_DISPATCH_ARGUMENTS), "Wrong size of GPUDrawIndirectArgs.");
|
||||
static_assert(OFFSET_OF(GPUDispatchIndirectArgs, ThreadGroupCountX) == OFFSET_OF(D3D12_DISPATCH_ARGUMENTS, ThreadGroupCountX), "Wrong offset for GPUDrawIndirectArgs::ThreadGroupCountX");
|
||||
@@ -163,7 +200,7 @@ void GPUContextDX12::AddTransitionBarrier(ResourceOwnerDX12* resource, const D3D
|
||||
resourceName = gpuResource->GetName();
|
||||
else
|
||||
resourceName = StringUtils::ToString((uint32)(uint64)resource->GetResource());
|
||||
const auto info = String::Format(TEXT("[DX12 Resource Barrier]: 0x{0:x} -> 0x{1:x}: {2} (subresource: {3})"), before, after, resourceName, subresourceIndex);
|
||||
const auto info = String::Format(TEXT("[DX12 Resource Barrier]: {0} -> {1}: {2} (subresource: {3})"), ResourceStateToString(before), ResourceStateToString(after), resourceName, subresourceIndex);
|
||||
Log::Logger::Write(LogType::Info, info);
|
||||
#endif
|
||||
|
||||
@@ -349,6 +386,7 @@ void GPUContextDX12::OnSwapChainFlush(ResourceOwnerDX12* backBuffer)
|
||||
if (_swapChains.Count() > 1)
|
||||
{
|
||||
// Flush GPU commands
|
||||
flushSwapChains();
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
@@ -362,6 +400,17 @@ void GPUContextDX12::GetActiveHeapDescriptor(const D3D12_CPU_DESCRIPTOR_HANDLE&
|
||||
_device->GetDevice()->CopyDescriptorsSimple(1, descriptor.CPU, cpuHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
}
|
||||
|
||||
void GPUContextDX12::flushSwapChains()
|
||||
{
|
||||
// Transition swapchains to the present state
|
||||
for (ResourceOwnerDX12* backBuffer : _swapChains)
|
||||
{
|
||||
SetResourceState(backBuffer, D3D12_RESOURCE_STATE_PRESENT);
|
||||
}
|
||||
_swapChains.Clear();
|
||||
flushRBs();
|
||||
}
|
||||
|
||||
void GPUContextDX12::flushSRVs()
|
||||
{
|
||||
uint32 srMask;
|
||||
@@ -753,12 +802,7 @@ void GPUContextDX12::FrameBegin()
|
||||
|
||||
void GPUContextDX12::FrameEnd()
|
||||
{
|
||||
// Transition swapchains to the present state
|
||||
for (ResourceOwnerDX12* backBuffer : _swapChains)
|
||||
{
|
||||
SetResourceState(backBuffer, D3D12_RESOURCE_STATE_PRESENT);
|
||||
}
|
||||
_swapChains.Clear();
|
||||
flushSwapChains();
|
||||
|
||||
// Base
|
||||
GPUContext::FrameEnd();
|
||||
|
||||
@@ -152,7 +152,7 @@ protected:
|
||||
void GetActiveHeapDescriptor(const D3D12_CPU_DESCRIPTOR_HANDLE& cpuHandle, Descriptor& descriptor);
|
||||
|
||||
private:
|
||||
|
||||
void flushSwapChains();
|
||||
void flushSRVs();
|
||||
void flushRTVs();
|
||||
void flushUAVs();
|
||||
|
||||
@@ -381,6 +381,10 @@ void GPUSwapChainDX12::Present(bool vsync)
|
||||
{
|
||||
presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
|
||||
}
|
||||
#if GPU_ENABLE_ASSERTION
|
||||
//ASSERT(_currentFrameIndex == _swapChain->GetCurrentBackBufferIndex());
|
||||
ASSERT(_backBuffers[_currentFrameIndex].State.CheckResourceState(D3D12_RESOURCE_STATE_PRESENT));
|
||||
#endif
|
||||
const HRESULT res = _swapChain->Present(vsync ? 1 : 0, presentFlags);
|
||||
LOG_DIRECTX_RESULT(res);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user