From 68abe2383a127febd5ec96cb2ab4ea763558ca61 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 27 Aug 2020 10:52:29 -0700 Subject: Implemented duration query in D3D12 --- .../GraphicsEngineD3D12/include/QueryD3D12Impl.hpp | 7 ++- .../GraphicsEngineD3D12/interface/QueryD3D12.h | 16 ++++- .../src/D3D12TypeConversions.cpp | 2 + .../src/DeviceContextD3D12Impl.cpp | 9 ++- .../GraphicsEngineD3D12/src/QueryD3D12Impl.cpp | 71 ++++++++++++++++------ 5 files changed, 76 insertions(+), 29 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.hpp index 18c01547..7170a720 100644 --- a/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.hpp @@ -64,15 +64,16 @@ public: } /// Implementation of IQueryD3D12::GetQueryHeapIndex(). - virtual Uint32 DILIGENT_CALL_TYPE GetQueryHeapIndex() const override final + virtual Uint32 DILIGENT_CALL_TYPE GetQueryHeapIndex(Uint32 QueryId) const override final { - return m_QueryHeapIndex; + VERIFY_EXPR(QueryId == 0 || m_Desc.Type == QUERY_TYPE_DURATION && QueryId == 1); + return m_QueryHeapIndex[QueryId]; } bool OnEndQuery(IDeviceContext* pContext); private: - Uint32 m_QueryHeapIndex = static_cast(-1); + Uint32 m_QueryHeapIndex[2] = {~Uint32{0}, ~Uint32{0}}; Uint64 m_QueryEndFenceValue = 0; }; diff --git a/Graphics/GraphicsEngineD3D12/interface/QueryD3D12.h b/Graphics/GraphicsEngineD3D12/interface/QueryD3D12.h index 34b5b660..d49f067b 100644 --- a/Graphics/GraphicsEngineD3D12/interface/QueryD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/QueryD3D12.h @@ -45,6 +45,8 @@ static const INTERFACE_ID IID_QueryD3D12 = IQueryInclusiveMethods; \ IQueryD3D12Methods QueryD3D12 +// clang-format off + /// Exposes Direct3D12-specific functionality of a Query object. DILIGENT_BEGIN_INTERFACE(IQueryD3D12, IQuery) { @@ -52,16 +54,24 @@ DILIGENT_BEGIN_INTERFACE(IQueryD3D12, IQuery) VIRTUAL ID3D12QueryHeap* METHOD(GetD3D12QueryHeap)(THIS) PURE; /// Returns the index of a query object in Direct3D12 query heap. - VIRTUAL Uint32 METHOD(GetQueryHeapIndex)(THIS) CONST PURE; + + /// \param [in] QueryId - Query Id. For most query types this must be 0. An exception is + /// QUERY_TYPE_DURATION, in which case allowed values are 0 for the + /// beginning timestamp query, and 1 for the ending query. + /// \return the index of a query object in Direct3D12 query heap + VIRTUAL Uint32 METHOD(GetQueryHeapIndex)(THIS_ + Uint32 QueryId) CONST PURE; }; DILIGENT_END_INTERFACE +// clang-format on + #include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" #if DILIGENT_C_INTERFACE -# define IQueryD3D12_GetD3D12QueryHeap(This) CALL_IFACE_METHOD(QueryD3D12, GetD3D12QueryHeap, This) -# define IQueryD3D12_GetQueryHeapIndex(This) CALL_IFACE_METHOD(QueryD3D12, GetQueryHeapIndex, This) +# define IQueryD3D12_GetD3D12QueryHeap(This) CALL_IFACE_METHOD(QueryD3D12, GetD3D12QueryHeap, This) +# define IQueryD3D12_GetQueryHeapIndex(This, ...) CALL_IFACE_METHOD(QueryD3D12, GetQueryHeapIndex, This, __VA_ARGS__) #endif diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 88c1fb2d..23652519 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -477,7 +477,9 @@ D3D12_QUERY_TYPE QueryTypeToD3D12QueryType(QUERY_TYPE QueryType) case QUERY_TYPE_BINARY_OCCLUSION: return D3D12_QUERY_TYPE_BINARY_OCCLUSION; case QUERY_TYPE_TIMESTAMP: return D3D12_QUERY_TYPE_TIMESTAMP; case QUERY_TYPE_PIPELINE_STATISTICS: return D3D12_QUERY_TYPE_PIPELINE_STATISTICS; + case QUERY_TYPE_DURATION: return D3D12_QUERY_TYPE_TIMESTAMP; + static_assert(QUERY_TYPE_NUM_TYPES == 6, "Not all QUERY_TYPE enum values are handled"); default: UNEXPECTED("Unexpected query type"); return static_cast(-1); diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 355b90b0..5217da9e 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2007,8 +2007,11 @@ void DeviceContextD3D12Impl::BeginQuery(IQuery* pQuery) auto& QueryMgr = m_pDevice->GetQueryManager(); auto& Ctx = GetCmdContext(); - auto Idx = pQueryD3D12Impl->GetQueryHeapIndex(); - QueryMgr.BeginQuery(Ctx, QueryType, Idx); + auto Idx = pQueryD3D12Impl->GetQueryHeapIndex(0); + if (QueryType != QUERY_TYPE_DURATION) + QueryMgr.BeginQuery(Ctx, QueryType, Idx); + else + QueryMgr.EndQuery(Ctx, QueryType, Idx); } void DeviceContextD3D12Impl::EndQuery(IQuery* pQuery) @@ -2026,7 +2029,7 @@ void DeviceContextD3D12Impl::EndQuery(IQuery* pQuery) auto& QueryMgr = m_pDevice->GetQueryManager(); auto& Ctx = GetCmdContext(); - auto Idx = pQueryD3D12Impl->GetQueryHeapIndex(); + auto Idx = pQueryD3D12Impl->GetQueryHeapIndex(QueryType == QUERY_TYPE_DURATION ? 1 : 0); QueryMgr.EndQuery(Ctx, QueryType, Idx); } diff --git a/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp index e7b5c1ee..37337e53 100644 --- a/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp @@ -41,19 +41,32 @@ QueryD3D12Impl::QueryD3D12Impl(IReferenceCounters* pRefCounters, const QueryDesc& Desc) : TQueryBase{pRefCounters, pDevice, Desc} { - auto& QueryMgr = pDevice->GetQueryManager(); - m_QueryHeapIndex = QueryMgr.AllocateQuery(m_Desc.Type); - if (m_QueryHeapIndex == QueryManagerD3D12::InvalidIndex) + auto& QueryMgr = pDevice->GetQueryManager(); + for (Uint32 i = 0; i < (m_Desc.Type == QUERY_TYPE_DURATION ? Uint32{2} : Uint32{1}); ++i) { - LOG_ERROR_AND_THROW("Failed to allocate D3D12 query for type ", GetQueryTypeString(m_Desc.Type), - ". Increase the query pool size in EngineD3D12CreateInfo."); + m_QueryHeapIndex[i] = QueryMgr.AllocateQuery(m_Desc.Type); + if (m_QueryHeapIndex[i] == QueryManagerD3D12::InvalidIndex) + { + for (Uint32 j = 0; j < i; ++j) + { + QueryMgr.ReleaseQuery(m_Desc.Type, m_QueryHeapIndex[j]); + } + LOG_ERROR_AND_THROW("Failed to allocate D3D12 query for type ", GetQueryTypeString(m_Desc.Type), + ". Increase the query pool size in EngineD3D12CreateInfo."); + } } } QueryD3D12Impl::~QueryD3D12Impl() { auto& QueryMgr = m_pDevice->GetQueryManager(); - QueryMgr.ReleaseQuery(m_Desc.Type, m_QueryHeapIndex); + for (Uint32 i = 0; i < _countof(m_QueryHeapIndex); ++i) + { + if (m_QueryHeapIndex[i] != QueryManagerD3D12::InvalidIndex) + { + QueryMgr.ReleaseQuery(m_Desc.Type, m_QueryHeapIndex[i]); + } + } } bool QueryD3D12Impl::OnEndQuery(IDeviceContext* pContext) @@ -75,12 +88,23 @@ bool QueryD3D12Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) { auto& QueryMgr = m_pDevice->GetQueryManager(); + auto GetTimestampFrequency = [this](Uint32 CmdQueueId) // + { + const auto& CmdQueue = m_pDevice->GetCommandQueue(CmdQueueId); + auto* pd3d12Queue = const_cast(CmdQueue).GetD3D12CommandQueue(); + + // https://microsoft.github.io/DirectX-Specs/d3d/CountersAndQueries.html#timestamp-frequency + UINT64 TimestampFrequency = 0; + pd3d12Queue->GetTimestampFrequency(&TimestampFrequency); + return TimestampFrequency; + }; + switch (m_Desc.Type) { case QUERY_TYPE_OCCLUSION: { UINT64 NumSamples; - QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex, &NumSamples, sizeof(NumSamples)); + QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex[0], &NumSamples, sizeof(NumSamples)); if (pData != nullptr) { auto& QueryData = *reinterpret_cast(pData); @@ -92,7 +116,7 @@ bool QueryD3D12Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) case QUERY_TYPE_BINARY_OCCLUSION: { UINT64 AnySamplePassed; - QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex, &AnySamplePassed, sizeof(AnySamplePassed)); + QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex[0], &AnySamplePassed, sizeof(AnySamplePassed)); if (pData != nullptr) { auto& QueryData = *reinterpret_cast(pData); @@ -106,19 +130,12 @@ bool QueryD3D12Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) case QUERY_TYPE_TIMESTAMP: { UINT64 Counter; - QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex, &Counter, sizeof(Counter)); + QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex[0], &Counter, sizeof(Counter)); if (pData != nullptr) { - auto& QueryData = *reinterpret_cast(pData); - QueryData.Counter = Counter; - - const auto& CmdQueue = m_pDevice->GetCommandQueue(CmdQueueId); - auto* pd3d12Queue = const_cast(CmdQueue).GetD3D12CommandQueue(); - - // https://microsoft.github.io/DirectX-Specs/d3d/CountersAndQueries.html#timestamp-frequency - UINT64 TimestampFrequency = 0; - pd3d12Queue->GetTimestampFrequency(&TimestampFrequency); - QueryData.Frequency = TimestampFrequency; + auto& QueryData = *reinterpret_cast(pData); + QueryData.Counter = Counter; + QueryData.Frequency = GetTimestampFrequency(CmdQueueId); } } break; @@ -126,7 +143,7 @@ bool QueryD3D12Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) case QUERY_TYPE_PIPELINE_STATISTICS: { D3D12_QUERY_DATA_PIPELINE_STATISTICS d3d12QueryData; - QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex, &d3d12QueryData, sizeof(d3d12QueryData)); + QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex[0], &d3d12QueryData, sizeof(d3d12QueryData)); if (pData != nullptr) { auto& QueryData = *reinterpret_cast(pData); @@ -146,6 +163,20 @@ bool QueryD3D12Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) } break; + case QUERY_TYPE_DURATION: + { + UINT64 StartCounter, EndCounter; + QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex[0], &StartCounter, sizeof(StartCounter)); + QueryMgr.ReadQueryData(m_Desc.Type, m_QueryHeapIndex[1], &EndCounter, sizeof(EndCounter)); + if (pData != nullptr) + { + auto& QueryData = *reinterpret_cast(pData); + QueryData.Duration = EndCounter - StartCounter; + QueryData.Frequency = GetTimestampFrequency(CmdQueueId); + } + } + break; + default: UNEXPECTED("Unexpected query type"); } -- cgit v1.2.3