summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsTools
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-01-11 07:10:48 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-01-11 07:10:48 +0000
commit4e6888fa1a776ee694270e325f3832d897201057 (patch)
tree89d2a86b735b826d9ebe1030617f9693ecae9564 /Graphics/GraphicsTools
parentFixed few issues with queries (diff)
downloadDiligentCore-4e6888fa1a776ee694270e325f3832d897201057.tar.gz
DiligentCore-4e6888fa1a776ee694270e325f3832d897201057.zip
Added ScopedQueryHelper class
Diffstat (limited to 'Graphics/GraphicsTools')
-rw-r--r--Graphics/GraphicsTools/CMakeLists.txt2
-rw-r--r--Graphics/GraphicsTools/interface/ScopedQueryHelper.h88
-rw-r--r--Graphics/GraphicsTools/src/ScopedQueryHelper.cpp92
3 files changed, 182 insertions, 0 deletions
diff --git a/Graphics/GraphicsTools/CMakeLists.txt b/Graphics/GraphicsTools/CMakeLists.txt
index eb120586..66b7a1ef 100644
--- a/Graphics/GraphicsTools/CMakeLists.txt
+++ b/Graphics/GraphicsTools/CMakeLists.txt
@@ -6,6 +6,7 @@ set(INTERFACE
interface/CommonlyUsedStates.h
interface/GraphicsUtilities.h
interface/pch.h
+ interface/ScopedQueryHelper.h
interface/ScreenCapture.h
interface/ShaderMacroHelper.h
interface/TextureUploader.h
@@ -14,6 +15,7 @@ set(INTERFACE
set(SOURCE
src/GraphicsUtilities.cpp
+ src/ScopedQueryHelper.cpp
src/ScreenCapture.cpp
src/pch.cpp
src/TextureUploader.cpp
diff --git a/Graphics/GraphicsTools/interface/ScopedQueryHelper.h b/Graphics/GraphicsTools/interface/ScopedQueryHelper.h
new file mode 100644
index 00000000..6dbf9553
--- /dev/null
+++ b/Graphics/GraphicsTools/interface/ScopedQueryHelper.h
@@ -0,0 +1,88 @@
+/*
+ * 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
+
+#include <vector>
+#include <deque>
+
+#include "../../GraphicsEngine/interface/RenderDevice.h"
+#include "../../GraphicsEngine/interface/DeviceContext.h"
+#include "../../GraphicsEngine/interface/Query.h"
+#include "../../../Common/interface/RefCntAutoPtr.h"
+
+namespace Diligent
+{
+
+/// Helper class to manage scoped queries.
+/// One scoped query instance must be used once per frame.
+class ScopedQueryHelper
+{
+public:
+ ScopedQueryHelper(IRenderDevice* pDevice,
+ const QueryDesc& queryDesc,
+ Uint32 NumQueriesToReserve,
+ Uint32 ExpectedQueryLimit = 5);
+
+ // clang-format off
+ ScopedQueryHelper (const ScopedQueryHelper&) = delete;
+ ScopedQueryHelper& operator=(const ScopedQueryHelper&) = delete;
+ ScopedQueryHelper (ScopedQueryHelper&&) = default;
+ ScopedQueryHelper& operator=(ScopedQueryHelper&&) = default;
+ // clang-format on
+
+
+ /// Begins a query.
+
+ /// \param [in] pCtx - Context to record begin query command
+ ///
+ /// \remarks There must be exaclty one matching Begin() for every End() call, otherwise
+ /// the behavior is undefined.
+ void Begin(IDeviceContext* pCtx);
+
+
+ /// Ends a query and returns the query data, if it is available.
+
+ /// \param [in] pCtx - Context to record end query command.
+ /// \param [out] pData - Pointer to the buffer that will receive query data.
+ /// \param [in] DataSize - Buffer data size.
+ /// \return true if the data from the oldest query is available, and false otherwise.
+ ///
+ /// \remarks There must be exaclty one matching End() for every Begin() call, otherwise
+ /// the behavior is undefined.
+ bool End(IDeviceContext* pCtx, void* pData, Uint32 DataSize);
+
+private:
+ RefCntAutoPtr<IRenderDevice> m_pDevice;
+ const QueryDesc m_QueryDesc;
+ const Uint32 m_ExpectedQueryLimit;
+
+ std::deque<RefCntAutoPtr<IQuery>> m_PendingQueries;
+ std::vector<RefCntAutoPtr<IQuery>> m_AvailableQueries;
+};
+
+} // namespace Diligent
diff --git a/Graphics/GraphicsTools/src/ScopedQueryHelper.cpp b/Graphics/GraphicsTools/src/ScopedQueryHelper.cpp
new file mode 100644
index 00000000..236a6551
--- /dev/null
+++ b/Graphics/GraphicsTools/src/ScopedQueryHelper.cpp
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+#include "pch.h"
+#include "ScopedQueryHelper.h"
+
+namespace Diligent
+{
+
+ScopedQueryHelper::ScopedQueryHelper(IRenderDevice* pDevice,
+ const QueryDesc& queryDesc,
+ Uint32 NumQueriesToReserve,
+ Uint32 ExpectedQueryLimit) :
+ m_pDevice{pDevice},
+ m_QueryDesc{queryDesc},
+ m_ExpectedQueryLimit{ExpectedQueryLimit}
+{
+ VERIFY(queryDesc.Type != QUERY_TYPE_TIMESTAMP, "Scoped query type is expected");
+ m_AvailableQueries.resize(NumQueriesToReserve);
+ for (Uint32 i = 0; i < NumQueriesToReserve; ++i)
+ {
+ m_pDevice->CreateQuery(queryDesc, &m_AvailableQueries[i]);
+ VERIFY(m_AvailableQueries[i], "Failed to create query");
+ }
+}
+
+void ScopedQueryHelper::Begin(IDeviceContext* pCtx)
+{
+ if (m_AvailableQueries.empty())
+ {
+ m_AvailableQueries.resize(1);
+ m_pDevice->CreateQuery(m_QueryDesc, &m_AvailableQueries.front());
+ }
+
+ auto pQuery = std::move(m_AvailableQueries.back());
+ m_AvailableQueries.pop_back();
+
+ pCtx->BeginQuery(pQuery);
+ m_PendingQueries.push_front(std::move(pQuery));
+}
+
+bool ScopedQueryHelper::End(IDeviceContext* pCtx, void* pData, Uint32 DataSize)
+{
+ if (m_PendingQueries.empty())
+ {
+ LOG_ERROR_MESSAGE("There are no pending queries, which likely indicates incosistent Begin()/End() calls");
+ return false;
+ }
+
+ if (m_PendingQueries.size() > m_ExpectedQueryLimit)
+ {
+ LOG_WARNING_MESSAGE("There are ", m_PendingQueries.size(), " pending queries which exceeds the specified expected limit (", m_ExpectedQueryLimit, ")");
+ }
+
+ pCtx->EndQuery(m_PendingQueries.front());
+
+ auto& pLastQuery = m_PendingQueries.back();
+ auto DataAvailable = pLastQuery->GetData(pData, DataSize);
+ if (DataAvailable)
+ {
+ m_AvailableQueries.emplace_back(std::move(pLastQuery));
+ m_PendingQueries.pop_back();
+ }
+
+ return DataAvailable;
+}
+
+} // namespace Diligent