diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-01-11 07:10:48 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-01-11 07:10:48 +0000 |
| commit | 4e6888fa1a776ee694270e325f3832d897201057 (patch) | |
| tree | 89d2a86b735b826d9ebe1030617f9693ecae9564 /Graphics/GraphicsTools | |
| parent | Fixed few issues with queries (diff) | |
| download | DiligentCore-4e6888fa1a776ee694270e325f3832d897201057.tar.gz DiligentCore-4e6888fa1a776ee694270e325f3832d897201057.zip | |
Added ScopedQueryHelper class
Diffstat (limited to 'Graphics/GraphicsTools')
| -rw-r--r-- | Graphics/GraphicsTools/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | Graphics/GraphicsTools/interface/ScopedQueryHelper.h | 88 | ||||
| -rw-r--r-- | Graphics/GraphicsTools/src/ScopedQueryHelper.cpp | 92 |
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 |
