From ef733fdbac35b6180964766b107f219eb41b1d75 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 6 Oct 2018 19:19:50 -0700 Subject: Updated submodules (main change: refactored release queues in D3D12 and Vulkan backends) --- DiligentCore | 2 +- DiligentTools | 2 +- Projects/Asteroids/src/asteroids_DE.cpp | 7 +- Tests/TestApp/src/ResourceReleaseQueueTest.cpp | 129 +++++++++++++++++++++ Tests/TestApp/src/TestApp.cpp | 46 +++++++- Tests/TestApp/src/TestTextureCreation.cpp | 2 + .../TestApp/src/VarSizeAllocationsManagerTest.cpp | 2 +- .../PluginSource/src/RenderAPI_D3D12.cpp | 14 ++- .../src/DiligentGraphicsAdapterD3D12.cpp | 24 ++-- .../src/UnityGraphicsD3D12Emulator.cpp | 10 +- .../UnityEmulator/src/UnityGraphicsD3D12Impl.h | 2 +- 11 files changed, 213 insertions(+), 27 deletions(-) create mode 100644 Tests/TestApp/src/ResourceReleaseQueueTest.cpp diff --git a/DiligentCore b/DiligentCore index 27a8812..9d1014f 160000 --- a/DiligentCore +++ b/DiligentCore @@ -1 +1 @@ -Subproject commit 27a8812b4e554c54cd102b785b003234893456ee +Subproject commit 9d1014f0afdcf2c5897019448f42e1352ae8c1f2 diff --git a/DiligentTools b/DiligentTools index 3147bca..48929c7 160000 --- a/DiligentTools +++ b/DiligentTools @@ -1 +1 @@ -Subproject commit 3147bcad48e72863c1a15e23ffb3e9754527fccb +Subproject commit 48929c7ccf570e15bb28ad11702c5806f3332a51 diff --git a/Projects/Asteroids/src/asteroids_DE.cpp b/Projects/Asteroids/src/asteroids_DE.cpp index 033106c..c9ad7f0 100644 --- a/Projects/Asteroids/src/asteroids_DE.cpp +++ b/Projects/Asteroids/src/asteroids_DE.cpp @@ -90,10 +90,10 @@ void Asteroids::InitDevice(HWND hWnd, DeviceType DevType) { EngineD3D12Attribs Attribs; Attribs.GPUDescriptorHeapDynamicSize[0] = 65536*4; - Attribs.GPUDescriptorHeapSize[0] = 65536*4; + Attribs.GPUDescriptorHeapSize[0] = 65536; // For mutable mode Attribs.NumCommandsToFlushCmdList = 1024; #ifndef _DEBUG - Attribs.DynamicDescriptorAllocationChunkSize[0] = 4*2048; + Attribs.DynamicDescriptorAllocationChunkSize[0] = 8192; #endif #if ENGINE_DLL if(!GetEngineFactoryD3D12) @@ -476,6 +476,9 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G Asteroids::~Asteroids() { + mDeviceCtxt->Flush(); + mDeviceCtxt->FinishFrame(); + mUpdateSubsetsSignal.Trigger(true, -1); for(auto &thread : mWorkerThreads) diff --git a/Tests/TestApp/src/ResourceReleaseQueueTest.cpp b/Tests/TestApp/src/ResourceReleaseQueueTest.cpp new file mode 100644 index 0000000..1c76164 --- /dev/null +++ b/Tests/TestApp/src/ResourceReleaseQueueTest.cpp @@ -0,0 +1,129 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// EngineSandbox.cpp : Defines the entry point for the application. +// + +#include "pch.h" +#include "Errors.h" +#include "ResourceReleaseQueue.h" +#include "DefaultRawMemoryAllocator.h" +#include "UnitTestBase.h" +#include + +using namespace Diligent; + +class ResourceReleaseQueueTest : public UnitTestBase +{ +public: + ResourceReleaseQueueTest() : + UnitTestBase("Resource release queue test") + { + struct ResourceA + { + int Data = 1; + }; + struct ResourceB + { + float Data = 2; + }; + struct ResourceC + { + float Data[2] = {3, 4}; + }; + + { + ResourceReleaseQueue Queue(DefaultRawMemoryAllocator::GetAllocator()); + std::unique_ptr res0(new ResourceA); + std::unique_ptr res1(new ResourceB); + + Queue.SafeReleaseResource(std::move(res0), 0); + Queue.SafeReleaseResource(std::move(res1), 0); + + std::unique_ptr res2(new ResourceC); + auto Wrapper2 = Queue.CreateWrapper(std::move(res2), 1); + //auto WrapperX = Queue.CreateWrapper(res2, 1);// - error + //auto WrapperY = Queue.CreateWrapper(static_cast&>(res2), 1);// - error + Queue.SafeReleaseResource(std::move(Wrapper2), 0); + + Queue.DiscardStaleResources(0, 1); + + std::unique_ptr res4(new ResourceA); + Queue.DiscardResource(std::move(res4), 1); + + std::unique_ptr res5(new ResourceB); + auto Wrapper5 = Queue.CreateWrapper(std::move(res5), 1); + Queue.DiscardResource(std::move(Wrapper5), 1); + + Queue.Purge(1); + } + + { + ResourceReleaseQueue Queue0(DefaultRawMemoryAllocator::GetAllocator()); + ResourceReleaseQueue Queue1(DefaultRawMemoryAllocator::GetAllocator()); + ResourceReleaseQueue Queue2(DefaultRawMemoryAllocator::GetAllocator()); + + std::unique_ptr res0(new ResourceA); + std::unique_ptr res1(new ResourceB); + std::unique_ptr res2(new ResourceC); + + auto Wrapper0 = ResourceReleaseQueue::CreateWrapper(std::move(res0), 3); + auto Wrapper1 = ResourceReleaseQueue::CreateWrapper(std::move(res1), 3); + auto Wrapper2 = ResourceReleaseQueue::CreateWrapper(std::move(res2), 1); + + Queue0.SafeReleaseResource(Wrapper0, 0); + Queue0.SafeReleaseResource(Wrapper1, 0); + Queue0.SafeReleaseResource(Wrapper2, 0); + Wrapper2.GiveUpOwnership(); + + Queue1.SafeReleaseResource(Wrapper0, 0); + Queue1.SafeReleaseResource(Wrapper1, 0); + + Queue2.SafeReleaseResource(std::move(Wrapper0), 0); + Queue2.SafeReleaseResource(Wrapper1, 0); + Wrapper1.GiveUpOwnership(); + + Queue0.DiscardStaleResources(0, 1); + Queue1.DiscardStaleResources(0, 1); + Queue2.DiscardStaleResources(0, 1); + + std::unique_ptr res3(new ResourceC); + auto Wrapper3 = ResourceReleaseQueue::CreateWrapper(std::move(res3), 2); + Queue0.DiscardResource(Wrapper3, 1); + Queue1.DiscardResource(std::move(Wrapper3), 1); + + std::unique_ptr res4(new ResourceA); + auto Wrapper4 = ResourceReleaseQueue::CreateWrapper(std::move(res4), 1); + Queue2.DiscardResource(Wrapper4, 1); + Wrapper4.GiveUpOwnership(); + + Queue0.Purge(1); + Queue1.Purge(1); + Queue2.Purge(1); + } + + SetStatus(TestResult::Succeeded); + } +}; + +static ResourceReleaseQueueTest TheTest; \ No newline at end of file diff --git a/Tests/TestApp/src/TestApp.cpp b/Tests/TestApp/src/TestApp.cpp index 784fca1..e5bcefb 100644 --- a/Tests/TestApp/src/TestApp.cpp +++ b/Tests/TestApp/src/TestApp.cpp @@ -72,11 +72,44 @@ using namespace Diligent; TestApp::TestApp() : m_AppTitle("Test app") { + VERIFY_EXPR(PlatformMisc::GetMSB(Uint32{0}) == 32); for (Uint32 i = 0; i < 32; ++i) { - auto MSB = PlatformMisc::GetMSB((1 << i) | 1); + auto MSB = PlatformMisc::GetMSB((Uint32{1} << i) | 1); VERIFY_EXPR(MSB == i); } + + VERIFY_EXPR(PlatformMisc::GetMSB(Uint64{0}) == 64); + for (Uint32 i = 0; i < 64; ++i) + { + auto MSB = PlatformMisc::GetMSB((Uint64{1} << i) | 1); + VERIFY_EXPR(MSB == i); + } + + VERIFY_EXPR(PlatformMisc::GetLSB(Uint32{0}) == 32); + for (Uint32 i = 0; i < 32; ++i) + { + auto LSB = PlatformMisc::GetLSB((Uint32{1} << i) | (Uint32{1}<<31)); + VERIFY_EXPR(LSB == i); + } + + VERIFY_EXPR(PlatformMisc::GetLSB(Uint64{0}) == 64); + for (Uint32 i = 0; i < 64; ++i) + { + auto LSB = PlatformMisc::GetLSB((Uint64{1} << i) | (Uint64{1}<<63)); + VERIFY_EXPR(LSB == i); + } + + VERIFY_EXPR(PlatformMisc::CountOneBits(Uint32{0}) == 0); + VERIFY_EXPR(PlatformMisc::CountOneBits(Uint64{0}) == 0); + VERIFY_EXPR(PlatformMisc::CountOneBits(Uint32{1}) == 1); + VERIFY_EXPR(PlatformMisc::CountOneBits(Uint64{1}) == 1); + VERIFY_EXPR(PlatformMisc::CountOneBits(Uint32{7}) == 3); + VERIFY_EXPR(PlatformMisc::CountOneBits(Uint64{7}) == 3); + VERIFY_EXPR(PlatformMisc::CountOneBits( (Uint32{1}<<31) | (Uint32{1} << 15)) == 2); + VERIFY_EXPR(PlatformMisc::CountOneBits( (Uint64{1}<<63) | (Uint32{1} << 31)) == 2); + VERIFY_EXPR(PlatformMisc::CountOneBits( (Uint32{1}<<31) - 1) == 31); + VERIFY_EXPR(PlatformMisc::CountOneBits( (Uint64{1}<<63) - 1) == 63); } TestApp::~TestApp() @@ -160,6 +193,12 @@ void TestApp::InitializeDiligentEngine( } EngineD3D12Attribs EngD3D12Attribs; + EngD3D12Attribs.CPUDescriptorHeapAllocationSize[0] = 64; // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + EngD3D12Attribs.CPUDescriptorHeapAllocationSize[1] = 32; // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + EngD3D12Attribs.CPUDescriptorHeapAllocationSize[2] = 16; // D3D12_DESCRIPTOR_HEAP_TYPE_RTV + EngD3D12Attribs.CPUDescriptorHeapAllocationSize[3] = 16; // D3D12_DESCRIPTOR_HEAP_TYPE_DSV + EngD3D12Attribs.DynamicDescriptorAllocationChunkSize[0] = 8; // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + EngD3D12Attribs.DynamicDescriptorAllocationChunkSize[1] = 8; // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ppContexts.resize(1 + NumDeferredCtx); pFactoryD3D12->CreateDeviceAndContextsD3D12(EngD3D12Attribs, &m_pDevice, ppContexts.data(), NumDeferredCtx); @@ -272,6 +311,8 @@ void TestApp::InitializeDiligentEngine( void TestApp::InitializeRenderers() { + m_pMTResCreationTest.reset(new MTResourceCreationTest(m_pDevice, m_pImmediateContext, 7)); + TestRasterizerState TestRS{m_pDevice, m_pImmediateContext}; TestBlendState TestBS{m_pDevice, m_pImmediateContext}; TestDepthStencilState TestDSS{m_pDevice, m_pImmediateContext}; @@ -283,8 +324,7 @@ void TestApp::InitializeRenderers() m_TestGS.Init(m_pDevice, m_pImmediateContext, m_pSwapChain); m_TestTessellation.Init(m_pDevice, m_pImmediateContext, m_pSwapChain); m_pTestShaderResArrays.reset(new TestShaderResArrays(m_pDevice, m_pImmediateContext, m_pSwapChain, 0.4f, -0.9f, 0.5f, 0.5f)); - m_pMTResCreationTest.reset(new MTResourceCreationTest(m_pDevice, m_pImmediateContext, 7)); - + TestShaderVarAccess TestShaderVarAccess{m_pDevice, m_pImmediateContext, m_pSwapChain}; TestShaderResourceLayout TestShaderResLayout{m_pDevice, m_pImmediateContext}; diff --git a/Tests/TestApp/src/TestTextureCreation.cpp b/Tests/TestApp/src/TestTextureCreation.cpp index 70936a5..1bade31 100644 --- a/Tests/TestApp/src/TestTextureCreation.cpp +++ b/Tests/TestApp/src/TestTextureCreation.cpp @@ -379,6 +379,8 @@ private: m_pDeviceContext->Flush(); // Also call FinishFrame() because otherwise resources will not be released m_pDeviceContext->FinishFrame(); + + m_pDevice->ReleaseStaleResources(); } diff --git a/Tests/TestApp/src/VarSizeAllocationsManagerTest.cpp b/Tests/TestApp/src/VarSizeAllocationsManagerTest.cpp index 791efe3..1e96239 100644 --- a/Tests/TestApp/src/VarSizeAllocationsManagerTest.cpp +++ b/Tests/TestApp/src/VarSizeAllocationsManagerTest.cpp @@ -63,7 +63,7 @@ VariableSizeAllocationsManagerTest::VariableSizeAllocationsManagerTest() : VERIFY_EXPR(a4.UnalignedOffset == 56 && a4.Size == 16); auto a5 = ListMgr.Allocate(64, 1); - VERIFY_EXPR(a5.UnalignedOffset == VariableSizeAllocationsManager::InvalidOffset && a5.Size == 0); + VERIFY_EXPR(!a5.IsValid() && a5.Size == 0); a5 = ListMgr.Allocate(16, 1); VERIFY_EXPR(a5.UnalignedOffset == 72 && a5.Size == 16); diff --git a/unityplugin/GhostCubePlugin/PluginSource/src/RenderAPI_D3D12.cpp b/unityplugin/GhostCubePlugin/PluginSource/src/RenderAPI_D3D12.cpp index 4f57a93..8befeb0 100644 --- a/unityplugin/GhostCubePlugin/PluginSource/src/RenderAPI_D3D12.cpp +++ b/unityplugin/GhostCubePlugin/PluginSource/src/RenderAPI_D3D12.cpp @@ -1,4 +1,5 @@ #include +#include #include "PlatformBase.h" @@ -42,13 +43,13 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_CommandQueueD3D12, TBase ) // Returns the fence value that will be signaled next time - virtual UINT64 GetNextFenceValue()override final + virtual Uint64 GetNextFenceValue()override final { return m_pUnityGraphicsD3D12->GetNextFrameFenceValue(); } // Executes a given command list - virtual UINT64 ExecuteCommandList(ID3D12GraphicsCommandList* commandList)override final + virtual Uint64 Submit(ID3D12GraphicsCommandList* commandList)override final { auto NextFenceValue = m_pUnityGraphicsD3D12->GetNextFrameFenceValue(); m_CurrentFenceValue = m_pUnityGraphicsD3D12->ExecuteCommandList(commandList, static_cast(m_ResourcesToTransition.size()), m_ResourcesToTransition.empty() ? nullptr : m_ResourcesToTransition.data()); @@ -70,7 +71,7 @@ public: } // Blocks execution until all pending GPU commands are complete - virtual void IdleGPU() + virtual Uint64 WaitForIdle() { if (m_CurrentFenceValue < GetCompletedFenceValue()) { @@ -79,6 +80,7 @@ public: WaitForSingleObject(m_WaitForGPUEventHandle, INFINITE); VERIFY(GetCompletedFenceValue() >= m_CurrentFenceValue, "Unexpected signaled fence value"); } + return GetCompletedFenceValue(); } void TransitionResource(const UnityGraphicsD3D12ResourceState &ResourceState) @@ -143,7 +145,8 @@ void RenderAPI_D3D12::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInt m_CmdQueue = NEW_RC_OBJ(DefaultAllocator, "UnityCommandQueueImpl instance", UnityCommandQueueImpl)(m_UnityGraphicsD3D12); auto *pFactoryD3D12 = GetEngineFactoryD3D12(); EngineD3D12Attribs Attribs; - pFactoryD3D12->AttachToD3D12Device(d3d12Device, m_CmdQueue, Attribs, &m_Device, &m_Context, 0); + std::array CmdQueues = {m_CmdQueue}; + pFactoryD3D12->AttachToD3D12Device(d3d12Device, CmdQueues.size(), CmdQueues.data(), Attribs, &m_Device, &m_Context, 0); m_Device->QueryInterface(IID_RenderDeviceD3D12, reinterpret_cast(static_cast(&m_RenderDeviceD3D12))); } break; @@ -169,8 +172,9 @@ void RenderAPI_D3D12::BeginRendering() void RenderAPI_D3D12::EndRendering() { m_Context->Flush(); + m_Context->FinishFrame(); m_Context->InvalidateState(); - m_RenderDeviceD3D12->FinishFrame(); + m_RenderDeviceD3D12->ReleaseStaleResources(); } void RenderAPI_D3D12::AttachToNativeRenderTexture(void *nativeRenderTargetHandle, void *nativeDepthTextureHandle) diff --git a/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp index 5cae5fa..1ef8671 100644 --- a/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp +++ b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp @@ -1,4 +1,6 @@ +#include + #define NOMINMAX #include #include @@ -38,13 +40,13 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_CommandQueueD3D12, TBase ) // Returns the fence value that will be signaled next time - virtual UINT64 GetNextFenceValue()override final + virtual Uint64 GetNextFenceValue()override final { return m_GraphicsD3D12Impl.GetNextFenceValue(); } // Executes a given command list - virtual UINT64 ExecuteCommandList(ID3D12GraphicsCommandList* commandList)override final + virtual Uint64 Submit(ID3D12GraphicsCommandList* commandList)override final { return m_GraphicsD3D12Impl.ExecuteCommandList(commandList); } @@ -56,18 +58,18 @@ public: } /// Returns value of the last completed fence - virtual Uint64 GetCompletedFenceValue() + virtual Uint64 GetCompletedFenceValue()override final { return m_GraphicsD3D12Impl.GetCompletedFenceValue(); } /// Blocks execution until all pending GPU commands are complete - virtual void IdleGPU() + virtual Uint64 WaitForIdle()override final { - m_GraphicsD3D12Impl.IdleGPU(); + return m_GraphicsD3D12Impl.IdleGPU(); } - virtual void SignalFence(ID3D12Fence* pFence, Uint64 Value) + virtual void SignalFence(ID3D12Fence* pFence, Uint64 Value)override final { m_GraphicsD3D12Impl.GetCommandQueue()->Signal(pFence, Value); } @@ -203,7 +205,8 @@ DiligentGraphicsAdapterD3D12::DiligentGraphicsAdapterD3D12(UnityGraphicsD3D12Emu auto *pFactoryD3D12 = GetEngineFactoryD3D12(); EngineD3D12Attribs Attribs; - pFactoryD3D12->AttachToD3D12Device(d3d12Device, CmdQueue, Attribs, &m_pDevice, &m_pDeviceCtx, 0); + std::array CmdQueues = {CmdQueue}; + pFactoryD3D12->AttachToD3D12Device(d3d12Device, CmdQueues.size(), CmdQueues.data(), Attribs, &m_pDevice, &m_pDeviceCtx, 0); } void DiligentGraphicsAdapterD3D12::InitProxySwapChain() @@ -223,11 +226,11 @@ void DiligentGraphicsAdapterD3D12::PreSwapChainResize() auto *pDeviceD3D12 = m_pDevice.RawPtr(); pProxySwapChainD3D12->ReleaseBuffers(); auto *GraphicsImpl = m_UnityGraphicsD3D12.GetGraphicsImpl(); - pDeviceD3D12->FinishFrame(); + pDeviceD3D12->ReleaseStaleResources(); // We must idle GPU GraphicsImpl->IdleGPU(); // And call FinishFrame() to release references to swap chain resources - pDeviceD3D12->FinishFrame(); + pDeviceD3D12->ReleaseStaleResources(); } void DiligentGraphicsAdapterD3D12::PostSwapChainResize() @@ -259,8 +262,9 @@ void DiligentGraphicsAdapterD3D12::EndFrame() pCtxD3D12->TransitionTextureState(pCurrentBackBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET); pCtxD3D12->TransitionTextureState(pDepthBuffer, D3D12_RESOURCE_STATE_DEPTH_WRITE); m_pDeviceCtx->Flush(); + m_pDeviceCtx->FinishFrame(); m_pDeviceCtx->InvalidateState(); - m_pDevice.RawPtr()->FinishFrame(); + m_pDevice.RawPtr()->ReleaseStaleResources(); } bool DiligentGraphicsAdapterD3D12::UsesReverseZ() diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp index 8d102d9..1bf35d6 100644 --- a/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp +++ b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp @@ -383,7 +383,7 @@ bool UnityGraphicsD3D12Impl::IsFenceCompleted(UINT64 FenceValue) return FenceValue <= m_CompletedFenceValue; } -void UnityGraphicsD3D12Impl::IdleGPU() +UINT64 UnityGraphicsD3D12Impl::IdleGPU() { auto SignaledValue = m_NextFenceValue; m_D3D12CmdQueue->Signal(m_D3D12FrameFence, SignaledValue); @@ -395,12 +395,16 @@ void UnityGraphicsD3D12Impl::IdleGPU() m_D3D12FrameFence->SetEventOnCompletion(SignaledValue, m_WaitForGPUEventHandle); WaitForSingleObject(m_WaitForGPUEventHandle, INFINITE); } + return SignaledValue; } UINT64 UnityGraphicsD3D12Impl::ExecuteCommandList(ID3D12CommandList *pCmdList) { - ID3D12CommandList *CmdLists[] = { pCmdList }; - m_D3D12CmdQueue->ExecuteCommandLists(1, CmdLists); + if (pCmdList != nullptr) + { + ID3D12CommandList *CmdLists[] = { pCmdList }; + m_D3D12CmdQueue->ExecuteCommandLists(1, CmdLists); + } auto FenceValue = m_NextFenceValue; m_D3D12CmdQueue->Signal(m_D3D12FrameFence, m_NextFenceValue++); return FenceValue; diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h index c969f0d..a5ad50b 100644 --- a/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h +++ b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h @@ -33,7 +33,7 @@ public: bool IsFenceCompleted(UINT64 FenceValue); - void IdleGPU(); + UINT64 IdleGPU(); IDXGISwapChain3* GetDXGISwapChain() { return m_SwapChain; } ID3D12Resource* GetDepthBuffer() { return m_DepthStencilBuffer; } -- cgit v1.2.3