diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index e2178a2f1..988ccddb8 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -80,10 +80,14 @@ namespace dxvk { m_queriesBegun.begin(), m_queriesBegun.end(), query); - if (unlikely(entry == m_queriesBegun.end())) - return; - - m_queriesBegun.erase(entry); + if (likely(entry != m_queriesBegun.end())) { + m_queriesBegun.erase(entry); + } else { + EmitCs([cQuery = query] + (DxvkContext* ctx) { + cQuery->Begin(ctx); + }); + } } m_commandList->AddQuery(query.ptr()); diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 0b4d9efa8..a0a1f9229 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -124,8 +124,12 @@ namespace dxvk { auto query = static_cast(pAsync); - if (unlikely(!query->DoEnd())) - return; + if (unlikely(!query->DoEnd())) { + EmitCs([cQuery = Com(query)] + (DxvkContext* ctx) { + cQuery->Begin(ctx); + }); + } EmitCs([cQuery = Com(query)] (DxvkContext* ctx) { diff --git a/src/d3d11/d3d11_query.cpp b/src/d3d11/d3d11_query.cpp index b35d9429e..62a930d89 100644 --- a/src/d3d11/d3d11_query.cpp +++ b/src/d3d11/d3d11_query.cpp @@ -228,12 +228,14 @@ namespace dxvk { } bool STDMETHODCALLTYPE D3D11Query::DoEnd() { - if (IsScoped() && m_state != D3D11_VK_QUERY_BEGUN) - return false; + // Apparently the D3D11 runtime implicitly begins the query + // if it is in the wrong state at the time End is called, so + // let the caller react to it instead of just failing here. + bool result = m_state == D3D11_VK_QUERY_BEGUN || !IsScoped(); m_state = D3D11_VK_QUERY_ENDED; m_resetCtr.fetch_add(1, std::memory_order_acquire); - return true; + return result; }