Query API: QuerySet on Vulkan
- Implement QuerySet on Vulkan backend. - Enable end2end tests on Vulkan. The timestamp tests will be enabled in following CL which implement timestamp query. Bug: dawn:434 Change-Id: I7ee04380c5f6b5af561cc23e28637dcae70bc7b9 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/26360 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Hao Li <hao.x.li@intel.com>
This commit is contained in:
parent
2f6e4ec6c0
commit
eff9ef0f22
|
@ -499,6 +499,8 @@ source_set("dawn_native_sources") {
|
|||
"vulkan/NativeSwapChainImplVk.h",
|
||||
"vulkan/PipelineLayoutVk.cpp",
|
||||
"vulkan/PipelineLayoutVk.h",
|
||||
"vulkan/QuerySetVk.cpp",
|
||||
"vulkan/QuerySetVk.h",
|
||||
"vulkan/QueueVk.cpp",
|
||||
"vulkan/QueueVk.h",
|
||||
"vulkan/RenderPassCache.cpp",
|
||||
|
|
|
@ -396,6 +396,8 @@ if (DAWN_ENABLE_VULKAN)
|
|||
"vulkan/NativeSwapChainImplVk.h"
|
||||
"vulkan/PipelineLayoutVk.cpp"
|
||||
"vulkan/PipelineLayoutVk.h"
|
||||
"vulkan/QuerySetVk.cpp"
|
||||
"vulkan/QuerySetVk.h"
|
||||
"vulkan/QueueVk.cpp"
|
||||
"vulkan/QueueVk.h"
|
||||
"vulkan/RenderPassCache.cpp"
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "dawn_native/vulkan/ComputePipelineVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
||||
#include "dawn_native/vulkan/QuerySetVk.h"
|
||||
#include "dawn_native/vulkan/QueueVk.h"
|
||||
#include "dawn_native/vulkan/RenderPassCache.h"
|
||||
#include "dawn_native/vulkan/RenderPipelineVk.h"
|
||||
|
@ -125,7 +126,7 @@ namespace dawn_native { namespace vulkan {
|
|||
return PipelineLayout::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<QuerySetBase*> Device::CreateQuerySetImpl(const QuerySetDescriptor* descriptor) {
|
||||
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation");
|
||||
return QuerySet::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
|
@ -318,6 +319,12 @@ namespace dawn_native { namespace vulkan {
|
|||
usedKnobs.features.textureCompressionBC = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(Extension::PipelineStatisticsQuery)) {
|
||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.pipelineStatisticsQuery ==
|
||||
VK_TRUE);
|
||||
usedKnobs.features.pipelineStatisticsQuery = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(Extension::ShaderFloat16)) {
|
||||
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||
ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace dawn_native { namespace vulkan {
|
|||
ASSERT(mMemoriesToDelete.Empty());
|
||||
ASSERT(mPipelinesToDelete.Empty());
|
||||
ASSERT(mPipelineLayoutsToDelete.Empty());
|
||||
ASSERT(mQueryPoolsToDelete.Empty());
|
||||
ASSERT(mRenderPassesToDelete.Empty());
|
||||
ASSERT(mSamplersToDelete.Empty());
|
||||
ASSERT(mSemaphoresToDelete.Empty());
|
||||
|
@ -70,6 +71,10 @@ namespace dawn_native { namespace vulkan {
|
|||
mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetPendingCommandSerial());
|
||||
}
|
||||
|
||||
void FencedDeleter::DeleteWhenUnused(VkQueryPool querypool) {
|
||||
mQueryPoolsToDelete.Enqueue(querypool, mDevice->GetPendingCommandSerial());
|
||||
}
|
||||
|
||||
void FencedDeleter::DeleteWhenUnused(VkRenderPass renderPass) {
|
||||
mRenderPassesToDelete.Enqueue(renderPass, mDevice->GetPendingCommandSerial());
|
||||
}
|
||||
|
@ -164,6 +169,11 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
mDescriptorPoolsToDelete.ClearUpTo(completedSerial);
|
||||
|
||||
for (VkQueryPool pool : mQueryPoolsToDelete.IterateUpTo(completedSerial)) {
|
||||
mDevice->fn.DestroyQueryPool(vkDevice, pool, nullptr);
|
||||
}
|
||||
mQueryPoolsToDelete.ClearUpTo(completedSerial);
|
||||
|
||||
for (VkSampler sampler : mSamplersToDelete.IterateUpTo(completedSerial)) {
|
||||
mDevice->fn.DestroySampler(vkDevice, sampler, nullptr);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace dawn_native { namespace vulkan {
|
|||
void DeleteWhenUnused(VkPipelineLayout layout);
|
||||
void DeleteWhenUnused(VkRenderPass renderPass);
|
||||
void DeleteWhenUnused(VkPipeline pipeline);
|
||||
void DeleteWhenUnused(VkQueryPool querypool);
|
||||
void DeleteWhenUnused(VkSampler sampler);
|
||||
void DeleteWhenUnused(VkSemaphore semaphore);
|
||||
void DeleteWhenUnused(VkShaderModule module);
|
||||
|
@ -54,6 +55,7 @@ namespace dawn_native { namespace vulkan {
|
|||
SerialQueue<VkImageView> mImageViewsToDelete;
|
||||
SerialQueue<VkPipeline> mPipelinesToDelete;
|
||||
SerialQueue<VkPipelineLayout> mPipelineLayoutsToDelete;
|
||||
SerialQueue<VkQueryPool> mQueryPoolsToDelete;
|
||||
SerialQueue<VkRenderPass> mRenderPassesToDelete;
|
||||
SerialQueue<VkSampler> mSamplersToDelete;
|
||||
SerialQueue<VkSemaphore> mSemaphoresToDelete;
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
// 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/vulkan/QuerySetVk.h"
|
||||
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/VulkanError.h"
|
||||
#include "dawn_platform/DawnPlatform.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
namespace {
|
||||
VkQueryType VulkanQueryType(wgpu::QueryType type) {
|
||||
switch (type) {
|
||||
case wgpu::QueryType::Occlusion:
|
||||
return VK_QUERY_TYPE_OCCLUSION;
|
||||
case wgpu::QueryType::PipelineStatistics:
|
||||
return VK_QUERY_TYPE_PIPELINE_STATISTICS;
|
||||
case wgpu::QueryType::Timestamp:
|
||||
return VK_QUERY_TYPE_TIMESTAMP;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
VkQueryPipelineStatisticFlags VulkanQueryPipelineStatisticFlags(
|
||||
std::vector<wgpu::PipelineStatisticName> pipelineStatisticsSet) {
|
||||
VkQueryPipelineStatisticFlags pipelineStatistics = 0;
|
||||
for (size_t i = 0; i < pipelineStatisticsSet.size(); ++i) {
|
||||
switch (pipelineStatisticsSet[i]) {
|
||||
case wgpu::PipelineStatisticName::ClipperInvocations:
|
||||
pipelineStatistics |= VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT;
|
||||
break;
|
||||
case wgpu::PipelineStatisticName::ClipperPrimitivesOut:
|
||||
pipelineStatistics |= VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT;
|
||||
break;
|
||||
case wgpu::PipelineStatisticName::ComputeShaderInvocations:
|
||||
pipelineStatistics |=
|
||||
VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT;
|
||||
break;
|
||||
case wgpu::PipelineStatisticName::FragmentShaderInvocations:
|
||||
pipelineStatistics |=
|
||||
VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT;
|
||||
break;
|
||||
case wgpu::PipelineStatisticName::VertexShaderInvocations:
|
||||
pipelineStatistics |=
|
||||
VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pipelineStatistics;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
ResultOrError<QuerySet*> QuerySet::Create(Device* device,
|
||||
const QuerySetDescriptor* descriptor) {
|
||||
Ref<QuerySet> queryset = AcquireRef(new QuerySet(device, descriptor));
|
||||
DAWN_TRY(queryset->Initialize());
|
||||
return queryset.Detach();
|
||||
}
|
||||
|
||||
MaybeError QuerySet::Initialize() {
|
||||
VkQueryPoolCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.queryType = VulkanQueryType(GetQueryType());
|
||||
createInfo.queryCount = GetQueryCount();
|
||||
if (GetQueryType() == wgpu::QueryType::PipelineStatistics) {
|
||||
createInfo.pipelineStatistics =
|
||||
VulkanQueryPipelineStatisticFlags(GetPipelineStatistics());
|
||||
}
|
||||
|
||||
Device* device = ToBackend(GetDevice());
|
||||
return CheckVkOOMThenSuccess(
|
||||
device->fn.CreateQueryPool(device->GetVkDevice(), &createInfo, nullptr, &*mHandle),
|
||||
"vkCreateQueryPool");
|
||||
}
|
||||
|
||||
VkQueryPool QuerySet::GetHandle() const {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
QuerySet::~QuerySet() {
|
||||
DestroyInternal();
|
||||
}
|
||||
|
||||
void QuerySet::DestroyImpl() {
|
||||
if (mHandle != VK_NULL_HANDLE) {
|
||||
ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
mHandle = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
|
@ -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_VULKAN_QUERYSETVK_H_
|
||||
#define DAWNNATIVE_VULKAN_QUERYSETVK_H_
|
||||
|
||||
#include "dawn_native/QuerySet.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Device;
|
||||
|
||||
class QuerySet final : public QuerySetBase {
|
||||
public:
|
||||
static ResultOrError<QuerySet*> Create(Device* device,
|
||||
const QuerySetDescriptor* descriptor);
|
||||
|
||||
VkQueryPool GetHandle() const;
|
||||
|
||||
private:
|
||||
~QuerySet() override;
|
||||
using QuerySetBase::QuerySetBase;
|
||||
MaybeError Initialize();
|
||||
|
||||
void DestroyImpl() override;
|
||||
|
||||
VkQueryPool mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
#endif // DAWNNATIVE_VULKAN_QUERYSETVK_H_
|
|
@ -57,7 +57,7 @@ TEST_P(OcclusionQueryTests, QuerySetDestroy) {
|
|||
querySet.Destroy();
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(OcclusionQueryTests, D3D12Backend());
|
||||
DAWN_INSTANTIATE_TEST(OcclusionQueryTests, D3D12Backend(), VulkanBackend());
|
||||
|
||||
class PipelineStatisticsQueryTests : public QueryTests {
|
||||
protected:
|
||||
|
@ -91,7 +91,7 @@ TEST_P(PipelineStatisticsQueryTests, QuerySetCreation) {
|
|||
device.CreateQuerySet(&descriptor);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(PipelineStatisticsQueryTests, D3D12Backend());
|
||||
DAWN_INSTANTIATE_TEST(PipelineStatisticsQueryTests, D3D12Backend(), VulkanBackend());
|
||||
|
||||
class TimestampExpectation : public detail::Expectation {
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue