diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-08-31 12:04:27 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-08-31 12:09:36 +0000 |
| commit | ab1149384b1185eb1b22eab8344055f82f9e10cb (patch) | |
| tree | 8221754353a7250d0a0b3ef84d229200c623f67b /Graphics/GraphicsEngineD3D11 | |
| parent | removed unused DXILUtils, fixed some Codacy issues (diff) | |
| parent | Added C API for IReferenceCounters (diff) | |
| download | DiligentCore-ab1149384b1185eb1b22eab8344055f82f9e10cb.tar.gz DiligentCore-ab1149384b1185eb1b22eab8344055f82f9e10cb.zip | |
Merge branch 'master' into mesh_shader
# Conflicts:
# Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
Diffstat (limited to 'Graphics/GraphicsEngineD3D11')
5 files changed, 99 insertions, 26 deletions
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp index 07020389..dbb74361 100644 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp @@ -321,6 +321,8 @@ private: void ClearStateCache(); + std::shared_ptr<DisjointQueryPool::DisjointQueryWrapper> BeginDisjointQuery(); + CComPtr<ID3D11DeviceContext> m_pd3d11DeviceContext; ///< D3D11 device context // clang-format off diff --git a/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp index 6cea3240..ece79c6a 100644 --- a/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp +++ b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp @@ -66,9 +66,10 @@ public: } /// Implementation of IQueryD3D11::GetD3D11Query(). - virtual ID3D11Query* DILIGENT_CALL_TYPE GetD3D11Query() override final + virtual ID3D11Query* DILIGENT_CALL_TYPE GetD3D11Query(Uint32 QueryId) override final { - return m_pd3d11Query; + VERIFY_EXPR(QueryId == 0 || m_Desc.Type == QUERY_TYPE_DURATION && QueryId == 1); + return m_pd3d11Query[QueryId]; } void SetDisjointQuery(std::shared_ptr<DisjointQueryPool::DisjointQueryWrapper> DisjointQuery) @@ -77,7 +78,7 @@ public: } private: - CComPtr<ID3D11Query> m_pd3d11Query; + CComPtr<ID3D11Query> m_pd3d11Query[2]; std::shared_ptr<DisjointQueryPool::DisjointQueryWrapper> m_DisjointQuery; }; diff --git a/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h b/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h index c9df1776..57f1fdf4 100644 --- a/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h @@ -45,19 +45,29 @@ static const struct INTERFACE_ID IID_QueryD3D11 = IQueryInclusiveMethods; \ IQueryD3D11Methods QueryD3D11 +// clang-format off + /// Exposes Direct3D11-specific functionality of a Query object. DILIGENT_BEGIN_INTERFACE(IQueryD3D11, IQuery) { /// Returns a pointer to the internal ID3D11Query object. - VIRTUAL ID3D11Query* METHOD(GetD3D11Query)(THIS) 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 pointer to the ID3D11Query object. + VIRTUAL ID3D11Query* METHOD(GetD3D11Query)(THIS_ + Uint32 QueryId) PURE; }; DILIGENT_END_INTERFACE +// clang-format on + #include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" #if DILIGENT_C_INTERFACE -# define IQueryD3D11_GetD3D11Query(This) CALL_IFACE_METHOD(QueryD3D11, GetD3D11Query, This) +# define IQueryD3D11_GetD3D11Query(This, ...) CALL_IFACE_METHOD(QueryD3D11, GetD3D11Query, This, __VA_ARGS__) #endif diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index d4f0d662..a7d3c169 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -2000,13 +2000,33 @@ void DeviceContextD3D11Impl::WaitForIdle() std::this_thread::yield(); } +std::shared_ptr<DisjointQueryPool::DisjointQueryWrapper> DeviceContextD3D11Impl::BeginDisjointQuery() +{ + 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); + m_ActiveDisjointQuery->IsEnded = false; + } + return m_ActiveDisjointQuery; +} + void DeviceContextD3D11Impl::BeginQuery(IQuery* pQuery) { if (!TDeviceContextBase::BeginQuery(pQuery, 0)) return; - auto* pQueryD3D11Impl = ValidatedCast<QueryD3D11Impl>(pQuery); - m_pd3d11DeviceContext->Begin(pQueryD3D11Impl->GetD3D11Query()); + auto* const pQueryD3D11Impl = ValidatedCast<QueryD3D11Impl>(pQuery); + if (pQueryD3D11Impl->GetDesc().Type == QUERY_TYPE_DURATION) + { + pQueryD3D11Impl->SetDisjointQuery(BeginDisjointQuery()); + m_pd3d11DeviceContext->End(pQueryD3D11Impl->GetD3D11Query(0)); + } + else + { + m_pd3d11DeviceContext->Begin(pQueryD3D11Impl->GetD3D11Query(0)); + } } void DeviceContextD3D11Impl::EndQuery(IQuery* pQuery) @@ -2014,20 +2034,16 @@ void DeviceContextD3D11Impl::EndQuery(IQuery* pQuery) if (!TDeviceContextBase::EndQuery(pQuery, 0)) return; - auto* pQueryD3D11Impl = ValidatedCast<QueryD3D11Impl>(pQuery); - if (pQueryD3D11Impl->GetDesc().Type == QUERY_TYPE_TIMESTAMP) + auto* const pQueryD3D11Impl = ValidatedCast<QueryD3D11Impl>(pQuery); + + const auto QueryType = pQueryD3D11Impl->GetDesc().Type; + VERIFY(QueryType != QUERY_TYPE_DURATION || m_ActiveDisjointQuery, + "There is no active disjoint query. Did you forget to call BeginQuery for the duration query?"); + if (QueryType == 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); - m_ActiveDisjointQuery->IsEnded = false; - } - pQueryD3D11Impl->SetDisjointQuery(m_ActiveDisjointQuery); + pQueryD3D11Impl->SetDisjointQuery(BeginDisjointQuery()); } - - m_pd3d11DeviceContext->End(pQueryD3D11Impl->GetD3D11Query()); + m_pd3d11DeviceContext->End(pQueryD3D11Impl->GetD3D11Query(QueryType == QUERY_TYPE_DURATION ? 1 : 0)); } void DeviceContextD3D11Impl::ClearStateCache() diff --git a/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp index bf70dfc1..e742958c 100644 --- a/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp @@ -53,6 +53,7 @@ QueryD3D11Impl::QueryD3D11Impl(IReferenceCounters* pRefCounters, break; case QUERY_TYPE_TIMESTAMP: + case QUERY_TYPE_DURATION: d3d11QueryDesc.Query = D3D11_QUERY_TIMESTAMP; break; @@ -65,9 +66,12 @@ QueryD3D11Impl::QueryD3D11Impl(IReferenceCounters* pRefCounters, } auto* pd3d11Device = pDevice->GetD3D11Device(); - auto hr = pd3d11Device->CreateQuery(&d3d11QueryDesc, &m_pd3d11Query); - CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D11 query object"); - VERIFY_EXPR(m_pd3d11Query != nullptr); + for (Uint32 i = 0; i < (Desc.Type == QUERY_TYPE_DURATION ? Uint32{2} : Uint32{1}); ++i) + { + auto hr = pd3d11Device->CreateQuery(&d3d11QueryDesc, &m_pd3d11Query[i]); + CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D11 query object"); + VERIFY_EXPR(m_pd3d11Query[i] != nullptr); + } } QueryD3D11Impl::~QueryD3D11Impl() @@ -90,7 +94,7 @@ bool QueryD3D11Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) case QUERY_TYPE_OCCLUSION: { UINT64 NumSamples; - DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &NumSamples, sizeof(NumSamples), 0) == S_OK; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query[0], &NumSamples, sizeof(NumSamples), 0) == S_OK; if (DataReady && pData != nullptr) { auto& QueryData = *reinterpret_cast<QueryDataOcclusion*>(pData); @@ -102,7 +106,7 @@ bool QueryD3D11Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) case QUERY_TYPE_BINARY_OCCLUSION: { BOOL AnySamplePassed; - DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &AnySamplePassed, sizeof(AnySamplePassed), 0) == S_OK; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query[0], &AnySamplePassed, sizeof(AnySamplePassed), 0) == S_OK; if (DataReady && pData != nullptr) { auto& QueryData = *reinterpret_cast<QueryDataBinaryOcclusion*>(pData); @@ -123,8 +127,9 @@ bool QueryD3D11Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) if (DataReady) { UINT64 Counter = 0; - DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &Counter, sizeof(Counter), 0) == S_OK; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query[0], &Counter, sizeof(Counter), 0) == S_OK; + // Note: DataReady is a return value, so we query the counter first, and then check pData for null. if (DataReady && pData != nullptr) { D3D11_QUERY_DATA_TIMESTAMP_DISJOINT DisjointQueryData; @@ -145,7 +150,7 @@ bool QueryD3D11Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) case QUERY_TYPE_PIPELINE_STATISTICS: { D3D11_QUERY_DATA_PIPELINE_STATISTICS d3d11QueryData; - DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &d3d11QueryData, sizeof(d3d11QueryData), 0) == S_OK; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query[0], &d3d11QueryData, sizeof(d3d11QueryData), 0) == S_OK; if (DataReady && pData != nullptr) { auto& QueryData = *reinterpret_cast<QueryDataPipelineStatistics*>(pData); @@ -165,6 +170,45 @@ bool QueryD3D11Impl::GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) } break; + case QUERY_TYPE_DURATION: + { + // Timestamp query is only useful if two timestamp queries are done in the middle of a D3D11_QUERY_TIMESTAMP_DISJOINT query. + // Timestamp disjoint query is begun by the device context when the first timestamp query is begun and ended + // by FinishFrame. Thus timestamp queries will only become available after FinishFrame. + + VERIFY_EXPR(m_DisjointQuery); + + DataReady = m_DisjointQuery->IsEnded; + if (DataReady) + { + UINT64 StartCounter = 0; + UINT64 EndCounter = 0; + + DataReady = pd3d11Ctx->GetData(m_pd3d11Query[0], &StartCounter, sizeof(StartCounter), 0) == S_OK; + if (DataReady) + { + DataReady = pd3d11Ctx->GetData(m_pd3d11Query[1], &EndCounter, sizeof(EndCounter), 0) == S_OK; + + // Note: DataReady is a return value, so we query the counters first, and then check pData for null. + if (DataReady && pData != nullptr) + { + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT DisjointQueryData; + DataReady = pd3d11Ctx->GetData(m_DisjointQuery->pd3d11Query, &DisjointQueryData, sizeof(DisjointQueryData), 0) == S_OK; + + if (DataReady) + { + auto& QueryData = *reinterpret_cast<QueryDataDuration*>(pData); + VERIFY_EXPR(EndCounter >= StartCounter); + QueryData.Duration = EndCounter - StartCounter; + // 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; + default: UNEXPECTED("Unexpected query type"); } |
