diff --git a/src/d3d11/d3d11_cmdlist.cpp b/src/d3d11/d3d11_cmdlist.cpp index cd8939a5..87863fbb 100644 --- a/src/d3d11/d3d11_cmdlist.cpp +++ b/src/d3d11/d3d11_cmdlist.cpp @@ -49,12 +49,20 @@ namespace dxvk { } + void D3D11CommandList::AddQuery(D3D11Query* pQuery) { + m_queries.emplace_back(pQuery); + } + + void D3D11CommandList::EmitToCommandList(ID3D11CommandList* pCommandList) { auto cmdList = static_cast(pCommandList); for (const auto& chunk : m_chunks) cmdList->m_chunks.push_back(chunk); - + + for (const auto& query : m_queries) + cmdList->m_queries.push_back(query); + MarkSubmitted(); } diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index d8437fee..323d301d 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -25,6 +25,9 @@ namespace dxvk { void AddChunk( DxvkCsChunkRef&& Chunk); + + void AddQuery( + D3D11Query* pQuery); void EmitToCommandList( ID3D11CommandList* pCommandList); @@ -37,7 +40,8 @@ namespace dxvk { D3D11Device* const m_device; UINT const m_contextFlags; - std::vector m_chunks; + std::vector m_chunks; + std::vector> m_queries; std::atomic m_submitted = { false }; std::atomic m_warned = { false }; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 7a4fb822..b2d9ccff 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -34,6 +34,63 @@ namespace dxvk { } + void STDMETHODCALLTYPE D3D11DeferredContext::Begin( + ID3D11Asynchronous* pAsync) { + D3D10DeviceLock lock = LockContext(); + + if (unlikely(!pAsync)) + return; + + Com query(static_cast(pAsync)); + + if (unlikely(!query->IsScoped())) + return; + + auto entry = std::find( + m_queriesBegun.begin(), + m_queriesBegun.end(), query); + + if (unlikely(entry != m_queriesBegun.end())) + return; + + EmitCs([cQuery = query] + (DxvkContext* ctx) { + cQuery->Begin(ctx); + }); + + m_queriesBegun.push_back(std::move(query)); + } + + + void STDMETHODCALLTYPE D3D11DeferredContext::End( + ID3D11Asynchronous* pAsync) { + D3D10DeviceLock lock = LockContext(); + + if (unlikely(!pAsync)) + return; + + Com query(static_cast(pAsync)); + + if (query->IsScoped()) { + auto entry = std::find( + m_queriesBegun.begin(), + m_queriesBegun.end(), query); + + if (unlikely(entry == m_queriesBegun.end())) + return; + + m_queriesBegun.erase(entry); + } + + m_commandList->AddQuery(query.ptr()); + + EmitCs([cQuery = std::move(query)] + (DxvkContext* ctx) { + cQuery->End(ctx); + }); + } + + void STDMETHODCALLTYPE D3D11DeferredContext::Flush() { Logger::err("D3D11: Flush called on a deferred context"); } @@ -83,6 +140,7 @@ namespace dxvk { ID3D11CommandList **ppCommandList) { D3D10DeviceLock lock = LockContext(); + FinalizeQueries(); FlushCsChunk(); if (ppCommandList != nullptr) @@ -309,6 +367,20 @@ namespace dxvk { } + void D3D11DeferredContext::FinalizeQueries() { + for (auto& query : m_queriesBegun) { + m_commandList->AddQuery(query.ptr()); + + EmitCs([cQuery = std::move(query)] + (DxvkContext* ctx) { + cQuery->End(ctx); + }); + } + + m_queriesBegun.clear(); + } + + Com D3D11DeferredContext::CreateCommandList() { return new D3D11CommandList(m_parent, m_contextFlags); } diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index 9ffa6902..bdfcf441 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -33,11 +33,17 @@ namespace dxvk { UINT STDMETHODCALLTYPE GetContextFlags(); HRESULT STDMETHODCALLTYPE GetData( - ID3D11Asynchronous* pAsync, - void* pData, - UINT DataSize, - UINT GetDataFlags); + ID3D11Asynchronous* pAsync, + void* pData, + UINT DataSize, + UINT GetDataFlags); + void STDMETHODCALLTYPE Begin( + ID3D11Asynchronous* pAsync); + + void STDMETHODCALLTYPE End( + ID3D11Asynchronous* pAsync); + void STDMETHODCALLTYPE Flush(); void STDMETHODCALLTYPE Flush1( @@ -87,6 +93,9 @@ namespace dxvk { // number of mapped resources per command list. std::vector m_mappedResources; + // Begun and ended queries, will also be stored in command list + std::vector> m_queriesBegun; + HRESULT MapBuffer( ID3D11Resource* pResource, D3D11_MAP MapType, @@ -100,6 +109,8 @@ namespace dxvk { UINT MapFlags, D3D11DeferredContextMapEntry* pMapEntry); + void FinalizeQueries(); + Com CreateCommandList(); void EmitCsChunk(DxvkCsChunkRef&& chunk);