From 6554ca8f9e14c766f6ebf8cd240403d6fc5fb252 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 14 Dec 2020 21:58:34 +0100 Subject: [PATCH] [d3d9] Cache query data --- src/d3d9/d3d9_query.cpp | 65 +++++++++++++++++++++++++++-------------- src/d3d9/d3d9_query.h | 3 ++ 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/d3d9/d3d9_query.cpp b/src/d3d9/d3d9_query.cpp index 8ebd2e3b3..bb905401f 100644 --- a/src/d3d9/d3d9_query.cpp +++ b/src/d3d9/d3d9_query.cpp @@ -121,12 +121,26 @@ namespace dxvk { } m_state = D3D9_VK_QUERY_ENDED; } - + return D3D_OK; } HRESULT STDMETHODCALLTYPE D3D9Query::GetData(void* pData, DWORD dwSize, DWORD dwGetDataFlags) { + if (m_state == D3D9_VK_QUERY_CACHED) { + // Query data was already retrieved once. + // Use cached query data to prevent having to check the VK event + // and having to iterate over the VK queries again + if (likely(pData && dwSize)) { + if (m_queryType != D3DQUERYTYPE_EVENT) { + memcpy(pData, &m_dataCache, dwSize); + } else { + *static_cast(pData) = true; + } + } + return D3D_OK; + } + HRESULT hr = this->GetQueryData(pData, dwSize); bool flush = dwGetDataFlags & D3DGETDATA_FLUSH; @@ -170,7 +184,12 @@ namespace dxvk { if (pData != nullptr) *static_cast(pData) = signaled; - return signaled ? D3D_OK : S_FALSE; + if (signaled) { + m_state = D3D9_VK_QUERY_CACHED; + return D3D_OK; + } else { + return S_FALSE; + } } else { std::array queryData = { }; @@ -189,42 +208,44 @@ namespace dxvk { if (pData == nullptr) return D3D_OK; - auto* data = static_cast(pData); switch (m_queryType) { case D3DQUERYTYPE_VCACHE: // Don't know what the hell any of this means. // Nor do I care. This just makes games work. - data->VCache.Pattern = MAKEFOURCC('H', 'C', 'A', 'C'); - data->VCache.OptMethod = 1; - data->VCache.CacheSize = 24; - data->VCache.MagicNumber = 20; - return D3D_OK; + m_dataCache.VCache.Pattern = MAKEFOURCC('H', 'C', 'A', 'C'); + m_dataCache.VCache.OptMethod = 1; + m_dataCache.VCache.CacheSize = 24; + m_dataCache.VCache.MagicNumber = 20; + break; case D3DQUERYTYPE_OCCLUSION: - data->Occlusion = DWORD(queryData[0].occlusion.samplesPassed); - return D3D_OK; + m_dataCache.Occlusion = DWORD(queryData[0].occlusion.samplesPassed); + break; case D3DQUERYTYPE_TIMESTAMP: - data->Timestamp = queryData[0].timestamp.time; - return D3D_OK; + m_dataCache.Timestamp = queryData[0].timestamp.time; + break; case D3DQUERYTYPE_TIMESTAMPDISJOINT: - data->TimestampDisjoint = queryData[0].timestamp.time < queryData[1].timestamp.time; - return D3D_OK; + m_dataCache.TimestampDisjoint = queryData[0].timestamp.time < queryData[1].timestamp.time; + break; case D3DQUERYTYPE_TIMESTAMPFREQ: - data->TimestampFreq = GetTimestampQueryFrequency(); - return D3D_OK; + m_dataCache.TimestampFreq = GetTimestampQueryFrequency(); + break; case D3DQUERYTYPE_VERTEXSTATS: - data->VertexStats.NumRenderedTriangles = queryData[0].statistic.iaPrimitives; - data->VertexStats.NumExtraClippingTriangles = queryData[0].statistic.clipPrimitives; - return D3D_OK; - - default: - return D3D_OK; + m_dataCache.VertexStats.NumRenderedTriangles = queryData[0].statistic.iaPrimitives; + m_dataCache.VertexStats.NumExtraClippingTriangles = queryData[0].statistic.clipPrimitives; + break; } + + if (likely(pData && dwSize)) + memcpy(pData, &m_dataCache, dwSize); + + m_state = D3D9_VK_QUERY_CACHED; + return D3D_OK; } } diff --git a/src/d3d9/d3d9_query.h b/src/d3d9/d3d9_query.h index ac6611e40..8d742c96c 100644 --- a/src/d3d9/d3d9_query.h +++ b/src/d3d9/d3d9_query.h @@ -10,6 +10,7 @@ namespace dxvk { D3D9_VK_QUERY_INITIAL, D3D9_VK_QUERY_BEGUN, D3D9_VK_QUERY_ENDED, + D3D9_VK_QUERY_CACHED }; union D3D9_QUERY_DATA { @@ -81,6 +82,8 @@ namespace dxvk { std::atomic m_resetCtr = { 0u }; + D3D9_QUERY_DATA m_dataCache; + UINT64 GetTimestampQueryFrequency() const; };