From d4cb5115e735f072652a2605b06ee84a8cb49144 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jun 2018 13:11:24 +0200 Subject: [PATCH] [d3d11] Flush implicitly when GetData returns S_FALSE Keeps the GPU busy when spinning on a query and ensures that we're flushing at some point. Replaces the Fallout 4 hang workaround. --- src/d3d11/d3d11_context_imm.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 4ebdcef5..86707996 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -73,16 +73,26 @@ namespace dxvk { if ((GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH) == 0) Flush(); - // This method handles various different but incompatible interfaces, + // Default error return for unsupported interfaces + HRESULT hr = E_INVALIDARG; + + // This method can handle various incompatible interfaces, // so we have to find out what we are actually dealing with Com query; if (SUCCEEDED(pAsync->QueryInterface(__uuidof(ID3D11Query), reinterpret_cast(&query)))) - return static_cast(query.ptr())->GetData(pData, GetDataFlags); + hr = static_cast(query.ptr())->GetData(pData, GetDataFlags); - // The interface is not supported - Logger::err("D3D11: GetData: Unsupported Async type"); - return E_INVALIDARG; + // If we're likely going to spin on the asynchronous object, + // flush the context so that we're keeping the GPU busy + if (hr == S_FALSE) + FlushImplicit(); + + // The requested interface is not supported + if (FAILED(hr)) + Logger::err("D3D11: GetData: Unsupported Async type"); + + return hr; } @@ -103,10 +113,11 @@ namespace dxvk { FlushCsChunk(); - // Reset optimization info - m_csIsBusy = false; - m_lastFlush = std::chrono::high_resolution_clock::now(); } + + // Reset optimization info + m_csIsBusy = false; + m_lastFlush = std::chrono::high_resolution_clock::now(); }