summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D11
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-25 04:52:38 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-25 04:52:38 +0000
commit414fa5ee38e2055b41883fc9a8ecb42ec1483f6d (patch)
treededddbea70658e301d06efc401eaabfc35e24920 /Graphics/GraphicsEngineD3D11
parentAdded QUERY_TYPE_DURATION value and QueryDataDuration struct (diff)
downloadDiligentCore-414fa5ee38e2055b41883fc9a8ecb42ec1483f6d.tar.gz
DiligentCore-414fa5ee38e2055b41883fc9a8ecb42ec1483f6d.zip
Implemented duration queries in D3D11 backend; added duration query test
Diffstat (limited to 'Graphics/GraphicsEngineD3D11')
-rw-r--r--Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.hpp7
-rw-r--r--Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h13
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp44
-rw-r--r--Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp58
5 files changed, 98 insertions, 26 deletions
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
index 53757b69..d2617152 100644
--- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.hpp
@@ -318,6 +318,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..78180e02 100644
--- a/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h
+++ b/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h
@@ -45,19 +45,28 @@ 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 c94b0e03..17f2dd3a 100755
--- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
@@ -1990,13 +1990,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)
@@ -2004,20 +2024,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");
}