diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 6d5febb1..61e05274 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -80,17 +80,33 @@ namespace dxvk { SynchronizeCsThread(); // Get query status directly from the query object - HRESULT hr = static_cast(pAsync)->GetData(pData, GetDataFlags); + auto query = static_cast(pAsync); + HRESULT hr = query->GetData(pData, GetDataFlags); // 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) + if (hr == S_FALSE) { + query->NotifyStall(); FlushImplicit(FALSE); + } return hr; } + void STDMETHODCALLTYPE D3D11ImmediateContext::End(ID3D11Asynchronous* pAsync) { + D3D11DeviceContext::End(pAsync); + + auto query = static_cast(pAsync); + if (unlikely(query && query->IsEvent())) { + query->NotifyEnd(); + query->IsStalling() + ? Flush() + : FlushImplicit(TRUE); + } + } + + void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() { m_parent->FlushInitContext(); diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 26e5e4b4..d1de71a3 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -32,6 +32,8 @@ namespace dxvk { UINT DataSize, UINT GetDataFlags); + void STDMETHODCALLTYPE End(ID3D11Asynchronous *pAsync); + void STDMETHODCALLTYPE Flush(); void STDMETHODCALLTYPE ExecuteCommandList( diff --git a/src/d3d11/d3d11_query.h b/src/d3d11/d3d11_query.h index 3b5b98f1..5c96aa0c 100644 --- a/src/d3d11/d3d11_query.h +++ b/src/d3d11/d3d11_query.h @@ -46,6 +46,23 @@ namespace dxvk { UINT GetDataFlags); DxvkBufferSlice GetPredicate(DxvkContext* ctx); + + bool IsEvent() const { + return m_desc.Query == D3D11_QUERY_EVENT; + } + + bool IsStalling() const { + return m_stallFlag; + } + + void NotifyEnd() { + m_stallMask <<= 1; + } + + void NotifyStall() { + m_stallMask |= 1; + m_stallFlag |= bit::popcnt(m_stallMask) >= 16; + } D3D10Query* GetD3D10Iface() { return &m_d3d10; @@ -66,6 +83,9 @@ namespace dxvk { D3D10Query m_d3d10; + uint32_t m_stallMask = 0; + bool m_stallFlag = false; + UINT64 GetTimestampQueryFrequency() const; };