From 7501af2487700060526c5b0c7fc78cc1ee2965cf Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 2 Jan 2020 22:29:01 -0800 Subject: Added query interface; implemented queries in D3D11 and D3D12 --- Graphics/GraphicsEngineD3D11/CMakeLists.txt | 3 + .../include/DeviceContextD3D11Impl.h | 8 ++ .../GraphicsEngineD3D11/include/FenceD3D11Impl.h | 2 + .../GraphicsEngineD3D11/include/QueryD3D11Impl.h | 68 +++++++++ .../include/RenderDeviceD3D11Impl.h | 3 + .../GraphicsEngineD3D11/interface/QueryD3D11.h | 49 +++++++ .../src/DeviceContextD3D11Impl.cpp | 19 +++ .../GraphicsEngineD3D11/src/QueryD3D11Impl.cpp | 156 +++++++++++++++++++++ .../src/RenderDeviceD3D11Impl.cpp | 15 +- 9 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h create mode 100644 Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h create mode 100644 Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp (limited to 'Graphics/GraphicsEngineD3D11') diff --git a/Graphics/GraphicsEngineD3D11/CMakeLists.txt b/Graphics/GraphicsEngineD3D11/CMakeLists.txt index f343e4ef..58396980 100644 --- a/Graphics/GraphicsEngineD3D11/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3D11/CMakeLists.txt @@ -14,6 +14,7 @@ set(INCLUDE include/pch.h include/FenceD3D11Impl.h include/PipelineStateD3D11Impl.h + include/QueryD3D11Impl.h include/RenderDeviceD3D11Impl.h include/SamplerD3D11Impl.h include/ShaderD3D11Impl.h @@ -37,6 +38,7 @@ set(INTERFACE interface/EngineFactoryD3D11.h interface/FenceD3D11.h interface/PipelineStateD3D11.h + interface/QueryD3D11.h interface/RenderDeviceD3D11.h interface/SamplerD3D11.h interface/ShaderD3D11.h @@ -57,6 +59,7 @@ set(SRC src/FenceD3D11Impl.cpp src/GUIDDef.cpp src/PipelineStateD3D11Impl.cpp + src/QueryD3D11Impl.cpp src/RenderDeviceD3D11Impl.cpp src/SamplerD3D11Impl.cpp src/ShaderD3D11Impl.cpp diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h index 8eb93264..d6624694 100755 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -36,6 +36,7 @@ #include "BufferD3D11Impl.h" #include "TextureBaseD3D11.h" #include "PipelineStateD3D11Impl.h" +#include "QueryD3D11Impl.h" #ifdef _DEBUG # define VERIFY_CONTEXT_BINDINGS @@ -52,6 +53,7 @@ struct DeviceContextD3D11ImplTraits using TextureType = TextureBaseD3D11; using PipelineStateType = PipelineStateD3D11Impl; using DeviceType = RenderDeviceD3D11Impl; + using QueryType = QueryD3D11Impl; }; /// Device context implementation in Direct3D11 backend. @@ -208,6 +210,12 @@ public: /// Implementation of IDeviceContext::WaitForIdle() in Direct3D11 backend. virtual void WaitForIdle() override final; + /// Implementation of IDeviceContext::BeginQuery() in Direct3D11 backend. + virtual void BeginQuery(IQuery* pQuery) override final; + + /// Implementation of IDeviceContext::EndQuery() in Direct3D11 backend. + virtual void EndQuery(IQuery* pQuery) override final; + /// Implementation of IDeviceContext::Flush() in Direct3D11 backend. virtual void Flush() override final; diff --git a/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h index bbd2a7d0..e4f923de 100644 --- a/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h @@ -52,6 +52,8 @@ public: const FenceDesc& Desc); ~FenceD3D11Impl(); + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_FenceD3D11, TFenceBase); + /// Implementation of IFence::GetCompletedValue() in Direct3D11 backend. virtual Uint64 GetCompletedValue() override final; diff --git a/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h new file mode 100644 index 00000000..d37b0cf0 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/include/QueryD3D11Impl.h @@ -0,0 +1,68 @@ +/* + * 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 + +/// \file +/// Declaration of Diligent::QueryD3D11Impl class + +#include "QueryD3D11.h" +#include "QueryBase.h" +#include "RenderDeviceD3D11Impl.h" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Query implementation in Direct3D11 backend. +class QueryD3D11Impl final : public QueryBase +{ +public: + using TQueryBase = QueryBase; + + QueryD3D11Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D11Impl* pDevice, + const QueryDesc& Desc); + ~QueryD3D11Impl(); + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_QueryD3D11, TQueryBase); + + /// Implementation of IQuery::GetData(). + virtual bool GetData(void* pData, Uint32 DataSize) override final; + + /// Implementation of IQueryD3D11::GetD3D11Query(). + virtual ID3D11Query* GetD3D11Query() override final + { + return m_pd3d11Query; + } + +private: + CComPtr m_pd3d11Query; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h index 52f812d7..17285244 100644 --- a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.h @@ -69,6 +69,9 @@ public: /// Implementation of IRenderDevice::CreateFence() in Direct3D11 backend. virtual void CreateFence(const FenceDesc& Desc, IFence** ppFence) override final; + /// Implementation of IRenderDevice::CreateQuery() in Direct3D11 backend. + virtual void CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) override final; + /// Implementation of IRenderDeviceD3D11::GetD3D11Device() in Direct3D11 backend. ID3D11Device* GetD3D11Device() override final { return m_pd3d11Device; } diff --git a/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h b/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h new file mode 100644 index 00000000..9096ca37 --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/interface/QueryD3D11.h @@ -0,0 +1,49 @@ +/* + * 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 + +/// \file +/// Definition of the Diligent::IQueryD3D11 interface + +#include "../../GraphicsEngine/interface/Query.h" + +namespace Diligent +{ + +// {77D95EAA-D16E-43F4-B0EB-BEBCD2EC8C57} +static constexpr INTERFACE_ID IID_QueryD3D11 = + {0x77d95eaa, 0xd16e, 0x43f4, {0xb0, 0xeb, 0xbe, 0xbc, 0xd2, 0xec, 0x8c, 0x57}}; + +/// Exposes Direct3D11-specific functionality of a Query object. +class IQueryD3D11 : public IQuery +{ + /// Returns a pointer to the internal ID3D11Query object. + virtual ID3D11Query* GetD3D11Query() = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 7cb5fdba..0d0f1a9d 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -41,6 +41,7 @@ #include "CommandListD3D11Impl.h" #include "RenderDeviceD3D11Impl.h" #include "FenceD3D11Impl.h" +#include "QueryD3D11Impl.h" namespace Diligent { @@ -1810,6 +1811,24 @@ void DeviceContextD3D11Impl::WaitForIdle() std::this_thread::yield(); } +void DeviceContextD3D11Impl::BeginQuery(IQuery* pQuery) +{ + if (!TDeviceContextBase::BeginQuery(pQuery, 0)) + return; + + auto* pQueryD3D11Impl = ValidatedCast(pQuery); + m_pd3d11DeviceContext->Begin(pQueryD3D11Impl->GetD3D11Query()); +} + +void DeviceContextD3D11Impl::EndQuery(IQuery* pQuery) +{ + if (!TDeviceContextBase::EndQuery(pQuery, 0)) + return; + + auto* pQueryD3D11Impl = ValidatedCast(pQuery); + m_pd3d11DeviceContext->End(pQueryD3D11Impl->GetD3D11Query()); +} + void DeviceContextD3D11Impl::ClearStateCache() { TDeviceContextBase::ClearStateCache(); diff --git a/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp new file mode 100644 index 00000000..0ec0f7bc --- /dev/null +++ b/Graphics/GraphicsEngineD3D11/src/QueryD3D11Impl.cpp @@ -0,0 +1,156 @@ +/* + * 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 "QueryD3D11Impl.h" +#include "DeviceContextD3D11Impl.h" + +namespace Diligent +{ + +QueryD3D11Impl::QueryD3D11Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D11Impl* pDevice, + const QueryDesc& Desc) : + TQueryBase{pRefCounters, pDevice, Desc} +{ + D3D11_QUERY_DESC d3d11QueryDesc = {}; + switch (Desc.Type) + { + case QUERY_TYPE_UNDEFINED: + LOG_ERROR_AND_THROW("Query type is undefined"); + + case QUERY_TYPE_OCCLUSION: + d3d11QueryDesc.Query = D3D11_QUERY_OCCLUSION; + break; + + case QUERY_TYPE_BINARY_OCCLUSION: + d3d11QueryDesc.Query = D3D11_QUERY_OCCLUSION_PREDICATE; + break; + + case QUERY_TYPE_TIMESTAMP: + d3d11QueryDesc.Query = D3D11_QUERY_TIMESTAMP; + break; + + case QUERY_TYPE_PIPELINE_STATISTICS: + d3d11QueryDesc.Query = D3D11_QUERY_PIPELINE_STATISTICS; + break; + + default: + UNEXPECTED("Unexpected query type"); + } + 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); +} + +QueryD3D11Impl::~QueryD3D11Impl() +{ +} + +bool QueryD3D11Impl::GetData(void* pData, Uint32 DataSize) +{ + if (!TQueryBase::CheckQueryDataPtr(pData, DataSize)) + return false; + + auto* pCtxD3D11Impl = m_pContext.RawPtr(); + VERIFY_EXPR(!pCtxD3D11Impl->IsDeferred()); + + auto* pd3d11Ctx = pCtxD3D11Impl->GetD3D11DeviceContext(); + + bool DataReady = false; + switch (m_Desc.Type) + { + case QUERY_TYPE_OCCLUSION: + { + UINT64 NumSamples; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &NumSamples, sizeof(NumSamples), 0) == S_OK; + if (DataReady) + { + auto& QueryData = *reinterpret_cast(pData); + QueryData.NumSamples = NumSamples; + } + } + break; + + case QUERY_TYPE_BINARY_OCCLUSION: + { + BOOL AnySamplePassed; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &AnySamplePassed, sizeof(AnySamplePassed), 0) == S_OK; + if (DataReady) + { + auto& QueryData = *reinterpret_cast(pData); + QueryData.AnySamplePassed = AnySamplePassed != FALSE; + } + } + break; + + case QUERY_TYPE_TIMESTAMP: + { + UINT64 NumTicks; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &NumTicks, sizeof(NumTicks), 0) == S_OK; + if (DataReady) + { + auto& QueryData = *reinterpret_cast(pData); + QueryData.NumTicks = NumTicks; + } + } + break; + + case QUERY_TYPE_PIPELINE_STATISTICS: + { + D3D11_QUERY_DATA_PIPELINE_STATISTICS d3d11QueryData; + DataReady = pd3d11Ctx->GetData(m_pd3d11Query, &d3d11QueryData, sizeof(d3d11QueryData), 0) == S_OK; + if (DataReady) + { + auto& QueryData = *reinterpret_cast(pData); + + QueryData.InputVertices = d3d11QueryData.IAVertices; + QueryData.InputPrimitives = d3d11QueryData.IAPrimitives; + QueryData.GSPrimitives = d3d11QueryData.GSPrimitives; + QueryData.ClippingInvocations = d3d11QueryData.CInvocations; + QueryData.ClippingPrimitives = d3d11QueryData.CPrimitives; + QueryData.VSInvocations = d3d11QueryData.VSInvocations; + QueryData.GSInvocations = d3d11QueryData.GSInvocations; + QueryData.PSInvocations = d3d11QueryData.PSInvocations; + QueryData.HSInvocations = d3d11QueryData.HSInvocations; + QueryData.DSInvocations = d3d11QueryData.DSInvocations; + QueryData.CSInvocations = d3d11QueryData.CSInvocations; + } + } + break; + + default: + UNEXPECTED("Unexpected query type"); + } + + return DataReady; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp index 4ba217dd..8475a402 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp @@ -39,6 +39,7 @@ #include "PipelineStateD3D11Impl.h" #include "ShaderResourceBindingD3D11Impl.h" #include "FenceD3D11Impl.h" +#include "QueryD3D11Impl.h" #include "EngineMemory.h" namespace Diligent @@ -95,7 +96,8 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo sizeof(SamplerD3D11Impl), sizeof(PipelineStateD3D11Impl), sizeof(ShaderResourceBindingD3D11Impl), - sizeof(FenceD3D11Impl) + sizeof(FenceD3D11Impl), + sizeof(QueryD3D11Impl) } }, m_EngineAttribs{EngineAttribs}, @@ -340,6 +342,17 @@ void RenderDeviceD3D11Impl::CreateFence(const FenceDesc& Desc, IFence** ppFence) }); } +void RenderDeviceD3D11Impl::CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) +{ + CreateDeviceObject("Query", Desc, ppQuery, + [&]() // + { + QueryD3D11Impl* pQueryD3D11(NEW_RC_OBJ(m_QueryAllocator, "QueryD3D11Impl instance", QueryD3D11Impl)(this, Desc)); + pQueryD3D11->QueryInterface(IID_Query, reinterpret_cast(ppQuery)); + OnCreateDeviceObject(pQueryD3D11); + }); +} + void RenderDeviceD3D11Impl::IdleGPU() { if (auto pImmediateCtx = m_wpImmediateContext.Lock()) -- cgit v1.2.3