From 568268cc51b0df5a7c1a712fe28ea7ef11ff4ed6 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 3 Jan 2020 11:02:29 -0800 Subject: Completed implementation of timestamp queries in D3D11 --- Graphics/GraphicsEngineD3D11/CMakeLists.txt | 1 + .../include/DeviceContextD3D11Impl.h | 4 + .../include/DisjointQueryPool.h | 101 +++++++++++++++++++++ .../GraphicsEngineD3D11/include/QueryD3D11Impl.h | 10 ++ .../src/DeviceContextD3D11Impl.cpp | 16 ++++ .../GraphicsEngineD3D11/src/QueryD3D11Impl.cpp | 16 +++- 6 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 Graphics/GraphicsEngineD3D11/include/DisjointQueryPool.h (limited to 'Graphics/GraphicsEngineD3D11') diff --git a/Graphics/GraphicsEngineD3D11/CMakeLists.txt b/Graphics/GraphicsEngineD3D11/CMakeLists.txt index 58396980..ab544ad1 100644 --- a/Graphics/GraphicsEngineD3D11/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3D11/CMakeLists.txt @@ -10,6 +10,7 @@ set(INCLUDE include/D3D11TypeConversions.h include/D3D11TypeDefinitions.h include/DeviceContextD3D11Impl.h + include/DisjointQueryPool.h include/EngineD3D11Defines.h include/pch.h include/FenceD3D11Impl.h diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h index d6624694..68dfdab0 100755 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -37,6 +37,7 @@ #include "TextureBaseD3D11.h" #include "PipelineStateD3D11Impl.h" #include "QueryD3D11Impl.h" +#include "DisjointQueryPool.h" #ifdef _DEBUG # define VERIFY_CONTEXT_BINDINGS @@ -370,6 +371,9 @@ private: FixedBlockMemoryAllocator m_CmdListAllocator; + DisjointQueryPool m_DisjointQueryPool; + std::shared_ptr m_ActiveDisjointQuery; + #ifdef VERIFY_CONTEXT_BINDINGS /// Helper template function used to facilitate context verification diff --git a/Graphics/GraphicsEngineD3D11/include/DisjointQueryPool.h b/Graphics/GraphicsEngineD3D11/include/DisjointQueryPool.h new file mode 100644 index 00000000..5de5cc2a --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/DisjointQueryPool.h @@ -0,0 +1,101 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::DisjointQueryPool class + +#include + +namespace Diligent +{ + +class DisjointQueryPool final +{ +public: + struct DisjointQueryWrapper + { + DisjointQueryPool& Pool; + CComPtr pd3d11Query; + + DisjointQueryWrapper(DisjointQueryPool& _Pool, + CComPtr&& _pd3d11Query) : + Pool(_Pool), + pd3d11Query(std::move(_pd3d11Query)) + { + } + + ~DisjointQueryWrapper() + { + Pool.m_AvailableQueries.emplace_back(std::move(pd3d11Query)); + } + + DisjointQueryWrapper(DisjointQueryWrapper&&) = default; + + DisjointQueryWrapper(const DisjointQueryWrapper&) = delete; + DisjointQueryWrapper& operator=(const DisjointQueryWrapper&) = delete; + DisjointQueryWrapper& operator=(DisjointQueryWrapper&&) = delete; + }; + + std::shared_ptr GetDisjointQuery(ID3D11Device* pd3d11Device) + { + CComPtr pd3d11Query; + if (!m_AvailableQueries.empty()) + { + pd3d11Query = std::move(m_AvailableQueries.back()); + m_AvailableQueries.pop_back(); + } + else + { + pd3d11Query = CreateQuery(pd3d11Device); + } + return std::shared_ptr{new DisjointQueryWrapper{*this, std::move(pd3d11Query)}}; + } + + ~DisjointQueryPool() + { + LOG_INFO_MESSAGE("Disjoint query pool: created ", m_NumQueriesCreated, (m_NumQueriesCreated == 1 ? " query" : " queries")); + } + +private: + CComPtr CreateQuery(ID3D11Device* pd3d11Device) + { + D3D11_QUERY_DESC QueryDesc = {D3D11_QUERY_TIMESTAMP_DISJOINT, 0}; + + CComPtr pd3d11Query; + pd3d11Device->CreateQuery(&QueryDesc, &pd3d11Query); + DEV_CHECK_ERR(pd3d11Query, "Failed to create D3D11 disjoint query"); + ++m_NumQueriesCreated; + return pd3d11Query; + } + std::vector> m_AvailableQueries; + + Uint32 m_NumQueriesCreated = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h index d37b0cf0..0d8cba37 100644 --- a/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h @@ -30,9 +30,12 @@ /// \file /// Declaration of Diligent::QueryD3D11Impl class +#include + #include "QueryD3D11.h" #include "QueryBase.h" #include "RenderDeviceD3D11Impl.h" +#include "DisjointQueryPool.h" namespace Diligent { @@ -61,8 +64,15 @@ public: return m_pd3d11Query; } + void SetDisjointQuery(std::shared_ptr DisjointQuery) + { + m_DisjointQuery = DisjointQuery; + } + private: CComPtr m_pd3d11Query; + + std::shared_ptr m_DisjointQuery; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 0d0f1a9d..8009c9b0 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -1149,6 +1149,11 @@ void DeviceContextD3D11Impl::GenerateMips(ITextureView* pTextureView) void DeviceContextD3D11Impl::FinishFrame() { + if (m_ActiveDisjointQuery) + { + m_pd3d11DeviceContext->End(m_ActiveDisjointQuery->pd3d11Query); + m_ActiveDisjointQuery.reset(); + } } void DeviceContextD3D11Impl::SetVertexBuffers(Uint32 StartSlot, @@ -1826,6 +1831,17 @@ void DeviceContextD3D11Impl::EndQuery(IQuery* pQuery) return; auto* pQueryD3D11Impl = ValidatedCast(pQuery); + if (pQueryD3D11Impl->GetDesc().Type == QUERY_TYPE_TIMESTAMP) + { + if (!m_ActiveDisjointQuery) + { + m_ActiveDisjointQuery = m_DisjointQueryPool.GetDisjointQuery(m_pDevice->GetD3D11Device()); + // Disjoint timestamp queries should only be invoked once per frame or less. + m_pd3d11DeviceContext->Begin(m_ActiveDisjointQuery->pd3d11Query); + } + pQueryD3D11Impl->SetDisjointQuery(m_ActiveDisjointQuery); + } + m_pd3d11DeviceContext->End(pQueryD3D11Impl->GetD3D11Query()); } diff --git a/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp index 0ec0f7bc..d7cc9458 100644 --- a/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp @@ -113,12 +113,22 @@ bool QueryD3D11Impl::GetData(void* pData, Uint32 DataSize) case QUERY_TYPE_TIMESTAMP: { + VERIFY_EXPR(m_DisjointQuery); + + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT DisjointQueryData; + DataReady = pd3d11Ctx->GetData(m_DisjointQuery->pd3d11Query, &DisjointQueryData, sizeof(DisjointQueryData), 0) == S_OK; + UINT64 NumTicks; - DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &NumTicks, sizeof(NumTicks), 0) == S_OK; if (DataReady) { - auto& QueryData = *reinterpret_cast(pData); - QueryData.NumTicks = NumTicks; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &NumTicks, sizeof(NumTicks), 0) == S_OK; + } + if (DataReady) + { + auto& QueryData = *reinterpret_cast(pData); + QueryData.NumTicks = NumTicks; + // The timestamp returned by ID3D11DeviceContext::GetData for a timestamp query is only reliable if Disjoint is FALSE. + QueryData.Frequency = DisjointQueryData.Disjoint ? 0 : DisjointQueryData.Frequency; } } break; -- cgit v1.2.3