From d5a4775cfc77da29870286a217ea49e4ab3270a3 Mon Sep 17 00:00:00 2001 From: Hao Li Date: Sat, 25 Jul 2020 14:48:12 +0000 Subject: [PATCH] Query API: QuerySet on D3D12 - Implement QuerySet object creation on D3D12 backend. - Add end2end tests for the creation on D3D12 backend. Bug: dawn:434 Change-Id: I9657792ca5cba8f156471783a7c13f6d36b7a19e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/25225 Reviewed-by: Corentin Wallez Commit-Queue: Hao Li --- src/dawn_native/BUILD.gn | 2 + src/dawn_native/CMakeLists.txt | 2 + src/dawn_native/d3d12/DeviceD3D12.cpp | 3 +- src/dawn_native/d3d12/QuerySetD3D12.cpp | 66 +++++++++++++++ src/dawn_native/d3d12/QuerySetD3D12.h | 45 +++++++++++ src/tests/BUILD.gn | 1 + src/tests/end2end/QueryTests.cpp | 103 ++++++++++++++++++++++++ 7 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 src/dawn_native/d3d12/QuerySetD3D12.cpp create mode 100644 src/dawn_native/d3d12/QuerySetD3D12.h create mode 100644 src/tests/end2end/QueryTests.cpp diff --git a/src/dawn_native/BUILD.gn b/src/dawn_native/BUILD.gn index 5d8a383f49..daee013869 100644 --- a/src/dawn_native/BUILD.gn +++ b/src/dawn_native/BUILD.gn @@ -318,6 +318,8 @@ source_set("dawn_native_sources") { "d3d12/PipelineLayoutD3D12.h", "d3d12/PlatformFunctions.cpp", "d3d12/PlatformFunctions.h", + "d3d12/QuerySetD3D12.cpp", + "d3d12/QuerySetD3D12.h", "d3d12/QueueD3D12.cpp", "d3d12/QueueD3D12.h", "d3d12/RenderPassBuilderD3D12.cpp", diff --git a/src/dawn_native/CMakeLists.txt b/src/dawn_native/CMakeLists.txt index 7abd5d970a..c602235541 100644 --- a/src/dawn_native/CMakeLists.txt +++ b/src/dawn_native/CMakeLists.txt @@ -202,6 +202,8 @@ if (DAWN_ENABLE_D3D12) "d3d12/PipelineLayoutD3D12.h" "d3d12/PlatformFunctions.cpp" "d3d12/PlatformFunctions.h" + "d3d12/QuerySetD3D12.cpp" + "d3d12/QuerySetD3D12.h" "d3d12/QueueD3D12.cpp" "d3d12/QueueD3D12.h" "d3d12/RenderPassBuilderD3D12.cpp" diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp index bbca615dc4..7b73ccfdb1 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/src/dawn_native/d3d12/DeviceD3D12.cpp @@ -29,6 +29,7 @@ #include "dawn_native/d3d12/D3D12Error.h" #include "dawn_native/d3d12/PipelineLayoutD3D12.h" #include "dawn_native/d3d12/PlatformFunctions.h" +#include "dawn_native/d3d12/QuerySetD3D12.h" #include "dawn_native/d3d12/QueueD3D12.h" #include "dawn_native/d3d12/RenderPipelineD3D12.h" #include "dawn_native/d3d12/ResidencyManagerD3D12.h" @@ -289,7 +290,7 @@ namespace dawn_native { namespace d3d12 { return PipelineLayout::Create(this, descriptor); } ResultOrError Device::CreateQuerySetImpl(const QuerySetDescriptor* descriptor) { - return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation"); + return QuerySet::Create(this, descriptor); } ResultOrError Device::CreateRenderPipelineImpl( const RenderPipelineDescriptor* descriptor) { diff --git a/src/dawn_native/d3d12/QuerySetD3D12.cpp b/src/dawn_native/d3d12/QuerySetD3D12.cpp new file mode 100644 index 0000000000..e4a6a4191c --- /dev/null +++ b/src/dawn_native/d3d12/QuerySetD3D12.cpp @@ -0,0 +1,66 @@ +// Copyright 2020 The Dawn Authors +// +// 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. + +#include "dawn_native/d3d12/QuerySetD3D12.h" + +#include "dawn_native/d3d12/D3D12Error.h" +#include "dawn_native/d3d12/DeviceD3D12.h" + +namespace dawn_native { namespace d3d12 { + + // static + ResultOrError QuerySet::Create(Device* device, + const QuerySetDescriptor* descriptor) { + Ref querySet = AcquireRef(new QuerySet(device, descriptor)); + DAWN_TRY(querySet->Initialize()); + return querySet.Detach(); + } + + MaybeError QuerySet::Initialize() { + D3D12_QUERY_HEAP_DESC queryHeapDesc = {}; + switch (GetQueryType()) { + case wgpu::QueryType::Occlusion: + queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION; + break; + case wgpu::QueryType::PipelineStatistics: + queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS; + break; + case wgpu::QueryType::Timestamp: + queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP; + break; + default: + UNREACHABLE(); + break; + } + queryHeapDesc.Count = GetQueryCount(); + + ID3D12Device* d3d12Device = ToBackend(GetDevice())->GetD3D12Device(); + return CheckOutOfMemoryHRESULT( + d3d12Device->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&mQueryHeap)), + "ID3D12Device::CreateQueryHeap"); + } + + ID3D12QueryHeap* QuerySet::GetQueryHeap() const { + return mQueryHeap.Get(); + } + + QuerySet::~QuerySet() { + DestroyInternal(); + } + + void QuerySet::DestroyImpl() { + ToBackend(GetDevice())->ReferenceUntilUnused(mQueryHeap); + } + +}} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/d3d12/QuerySetD3D12.h b/src/dawn_native/d3d12/QuerySetD3D12.h new file mode 100644 index 0000000000..7b24cceb67 --- /dev/null +++ b/src/dawn_native/d3d12/QuerySetD3D12.h @@ -0,0 +1,45 @@ +// Copyright 2020 The Dawn Authors +// +// 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. + +#ifndef DAWNNATIVE_D3D12_QUERYSETD3D12_H_ +#define DAWNNATIVE_D3D12_QUERYSETD3D12_H_ + +#include "dawn_native/QuerySet.h" +#include "dawn_native/d3d12/d3d12_platform.h" + +namespace dawn_native { namespace d3d12 { + + class Device; + + class QuerySet : public QuerySetBase { + public: + static ResultOrError Create(Device* device, + const QuerySetDescriptor* descriptor); + + ID3D12QueryHeap* GetQueryHeap() const; + + private: + ~QuerySet() override; + using QuerySetBase::QuerySetBase; + MaybeError Initialize(); + + // Dawn API + void DestroyImpl() override; + + ComPtr mQueryHeap; + }; + +}} // namespace dawn_native::d3d12 + +#endif // DAWNNATIVE_D3D12_QUERYSETD3D12_H_ diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn index fa8e1b8b17..06875e68d7 100644 --- a/src/tests/BUILD.gn +++ b/src/tests/BUILD.gn @@ -294,6 +294,7 @@ source_set("dawn_end2end_tests_sources") { "end2end/OpArrayLengthTests.cpp", "end2end/PipelineLayoutTests.cpp", "end2end/PrimitiveTopologyTests.cpp", + "end2end/QueryTests.cpp", "end2end/QueueTests.cpp", "end2end/RenderBundleTests.cpp", "end2end/RenderPassLoadOpTests.cpp", diff --git a/src/tests/end2end/QueryTests.cpp b/src/tests/end2end/QueryTests.cpp new file mode 100644 index 0000000000..fc244f21c3 --- /dev/null +++ b/src/tests/end2end/QueryTests.cpp @@ -0,0 +1,103 @@ +// Copyright 2020 The Dawn Authors +// +// 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. + +// This file contains test for deprecated parts of Dawn's API while following WebGPU's evolution. +// It contains test for the "old" behavior that will be deleted once users are migrated, tests that +// a deprecation warning is emitted when the "old" behavior is used, and tests that an error is +// emitted when both the old and the new behavior are used (when applicable). + +#include "tests/DawnTest.h" + +class OcclusionQueryTests : public DawnTest {}; + +// Test creating query set with the type of Occlusion +TEST_P(OcclusionQueryTests, QuerySetCreation) { + wgpu::QuerySetDescriptor descriptor; + descriptor.count = 1; + descriptor.type = wgpu::QueryType::Occlusion; + device.CreateQuerySet(&descriptor); +} + +// Test destroying query set +TEST_P(OcclusionQueryTests, QuerySetDestroy) { + wgpu::QuerySetDescriptor descriptor; + descriptor.count = 1; + descriptor.type = wgpu::QueryType::Occlusion; + wgpu::QuerySet querySet = device.CreateQuerySet(&descriptor); + querySet.Destroy(); +} + +DAWN_INSTANTIATE_TEST(OcclusionQueryTests, D3D12Backend()); + +class PipelineStatisticsQueryTests : public DawnTest { + protected: + void SetUp() override { + DawnTest::SetUp(); + + // Skip all tests if pipeline statistics extension is not supported + DAWN_SKIP_TEST_IF(!SupportsExtensions({"pipeline_statistics_query"})); + } + + std::vector GetRequiredExtensions() override { + std::vector requiredExtensions = {}; + if (SupportsExtensions({"pipeline_statistics_query"})) { + requiredExtensions.push_back("pipeline_statistics_query"); + } + + return requiredExtensions; + } +}; + +// Test creating query set with the type of PipelineStatistics +TEST_P(PipelineStatisticsQueryTests, QuerySetCreation) { + wgpu::QuerySetDescriptor descriptor; + descriptor.count = 1; + descriptor.type = wgpu::QueryType::PipelineStatistics; + wgpu::PipelineStatisticName pipelineStatistics[2] = { + wgpu::PipelineStatisticName::ClipperInvocations, + wgpu::PipelineStatisticName::VertexShaderInvocations}; + descriptor.pipelineStatistics = pipelineStatistics; + descriptor.pipelineStatisticsCount = 2; + device.CreateQuerySet(&descriptor); +} + +DAWN_INSTANTIATE_TEST(PipelineStatisticsQueryTests, D3D12Backend()); + +class TimestampQueryTests : public DawnTest { + protected: + void SetUp() override { + DawnTest::SetUp(); + + // Skip all tests if timestamp extension is not supported + DAWN_SKIP_TEST_IF(!SupportsExtensions({"timestamp_query"})); + } + + std::vector GetRequiredExtensions() override { + std::vector requiredExtensions = {}; + if (SupportsExtensions({"timestamp_query"})) { + requiredExtensions.push_back("timestamp_query"); + } + return requiredExtensions; + } +}; + +// Test creating query set with the type of Timestamp +TEST_P(TimestampQueryTests, QuerySetCreation) { + wgpu::QuerySetDescriptor descriptor; + descriptor.count = 1; + descriptor.type = wgpu::QueryType::Timestamp; + device.CreateQuerySet(&descriptor); +} + +DAWN_INSTANTIATE_TEST(TimestampQueryTests, D3D12Backend());