Move timestamp query inside compute/render passes to new feature
Feature::TimestampQuery is used for timestamp query in command encoder
and compute/render descriptor to match WebGPU SPEC.
Add a new feature timestamp-query-inside-passes for writeTimestamp API
on compute pass and render pass.
Split timestamp query tests in dawn_end2end_tests and dawn_unit_tests.
Bug: dawn:1193, dawn:1250
Change-Id: I8dd66c1d40939877e37ec2b979a573cc4812c21f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/106500
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Hao Li <hao.x.li@intel.com>
diff --git a/dawn.json b/dawn.json
index 554a95e..f58121f 100644
--- a/dawn.json
+++ b/dawn.json
@@ -1400,7 +1400,8 @@
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
{"value": 1004, "name": "dawn native", "tags": ["dawn", "native"]},
- {"value": 1005, "name": "chromium experimental dp4a", "tags": ["dawn"]}
+ {"value": 1005, "name": "chromium experimental dp4a", "tags": ["dawn"]},
+ {"value": 1006, "name": "timestamp query inside passes", "tags": ["dawn"]}
]
},
"filter mode": {
diff --git a/src/dawn/native/CommandValidation.cpp b/src/dawn/native/CommandValidation.cpp
index a3929f3..836c811 100644
--- a/src/dawn/native/CommandValidation.cpp
+++ b/src/dawn/native/CommandValidation.cpp
@@ -19,11 +19,13 @@
#include <utility>
#include "dawn/common/BitSetIterator.h"
+#include "dawn/native/Adapter.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/CommandBufferStateTracker.h"
#include "dawn/native/Commands.h"
#include "dawn/native/Device.h"
+#include "dawn/native/Instance.h"
#include "dawn/native/PassResourceUsage.h"
#include "dawn/native/QuerySet.h"
#include "dawn/native/RenderBundle.h"
@@ -68,9 +70,17 @@
MaybeError ValidateTimestampQuery(const DeviceBase* device,
const QuerySetBase* querySet,
- uint32_t queryIndex) {
+ uint32_t queryIndex,
+ Feature requiredFeature) {
DAWN_TRY(device->ValidateObject(querySet));
+ DAWN_INVALID_IF(!device->HasFeature(requiredFeature),
+ "Timestamp queries used without the %s feature enabled.",
+ device->GetAdapter()
+ ->GetInstance()
+ ->GetFeatureInfo(FeatureEnumToAPIFeature(requiredFeature))
+ ->name);
+
DAWN_INVALID_IF(querySet->GetQueryType() != wgpu::QueryType::Timestamp,
"The type of %s is not %s.", querySet, wgpu::QueryType::Timestamp);
diff --git a/src/dawn/native/CommandValidation.h b/src/dawn/native/CommandValidation.h
index bf4e8aa..d4f66d7 100644
--- a/src/dawn/native/CommandValidation.h
+++ b/src/dawn/native/CommandValidation.h
@@ -19,6 +19,7 @@
#include "dawn/native/CommandAllocator.h"
#include "dawn/native/Error.h"
+#include "dawn/native/Features.h"
#include "dawn/native/Texture.h"
#include "dawn/native/UsageValidationMode.h"
@@ -32,7 +33,8 @@
MaybeError ValidateTimestampQuery(const DeviceBase* device,
const QuerySetBase* querySet,
- uint32_t queryIndex);
+ uint32_t queryIndex,
+ Feature requiredFeature = Feature::TimestampQuery);
MaybeError ValidateWriteBuffer(const DeviceBase* device,
const BufferBase* buffer,
diff --git a/src/dawn/native/ComputePassEncoder.cpp b/src/dawn/native/ComputePassEncoder.cpp
index 4c8d9ca..2b9a8ce 100644
--- a/src/dawn/native/ComputePassEncoder.cpp
+++ b/src/dawn/native/ComputePassEncoder.cpp
@@ -433,7 +433,8 @@
this,
[&](CommandAllocator* allocator) -> MaybeError {
if (IsValidationEnabled()) {
- DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex));
+ DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex,
+ Feature::TimestampQueryInsidePasses));
}
mCommandEncoder->TrackQueryAvailability(querySet, queryIndex);
diff --git a/src/dawn/native/Features.cpp b/src/dawn/native/Features.cpp
index c7d00b7..d839bd2 100644
--- a/src/dawn/native/Features.cpp
+++ b/src/dawn/native/Features.cpp
@@ -51,6 +51,10 @@
{Feature::TimestampQuery,
{"timestamp-query", "Support Timestamp Query",
"https://bugs.chromium.org/p/dawn/issues/detail?id=434", FeatureInfo::FeatureState::Stable}},
+ {Feature::TimestampQueryInsidePasses,
+ {"timestamp-query-inside-passes", "Support Timestamp Query inside render/compute pass",
+ "https://bugs.chromium.org/p/dawn/issues/detail?id=434",
+ FeatureInfo::FeatureState::Experimental}},
{Feature::DepthClipControl,
{"depth-clip-control", "Disable depth clipping of primitives to the clip volume",
"https://bugs.chromium.org/p/dawn/issues/detail?id=1178", FeatureInfo::FeatureState::Stable}},
@@ -100,6 +104,8 @@
case wgpu::FeatureName::TimestampQuery:
return Feature::TimestampQuery;
+ case wgpu::FeatureName::TimestampQueryInsidePasses:
+ return Feature::TimestampQueryInsidePasses;
case wgpu::FeatureName::PipelineStatisticsQuery:
return Feature::PipelineStatisticsQuery;
case wgpu::FeatureName::TextureCompressionBC:
@@ -142,6 +148,8 @@
return wgpu::FeatureName::PipelineStatisticsQuery;
case Feature::TimestampQuery:
return wgpu::FeatureName::TimestampQuery;
+ case Feature::TimestampQueryInsidePasses:
+ return wgpu::FeatureName::TimestampQueryInsidePasses;
case Feature::DepthClipControl:
return wgpu::FeatureName::DepthClipControl;
case Feature::Depth32FloatStencil8:
diff --git a/src/dawn/native/Features.h b/src/dawn/native/Features.h
index 4bcb93a..2a35963 100644
--- a/src/dawn/native/Features.h
+++ b/src/dawn/native/Features.h
@@ -32,6 +32,7 @@
TextureCompressionASTC,
PipelineStatisticsQuery,
TimestampQuery,
+ TimestampQueryInsidePasses,
DepthClipControl,
Depth32FloatStencil8,
ChromiumExperimentalDp4a,
diff --git a/src/dawn/native/QuerySet.cpp b/src/dawn/native/QuerySet.cpp
index 2776ddd..0682495 100644
--- a/src/dawn/native/QuerySet.cpp
+++ b/src/dawn/native/QuerySet.cpp
@@ -82,7 +82,8 @@
"Timestamp queries are disallowed because they may expose precise "
"timing information.");
- DAWN_INVALID_IF(!device->HasFeature(Feature::TimestampQuery),
+ DAWN_INVALID_IF(!device->HasFeature(Feature::TimestampQuery) &&
+ !device->HasFeature(Feature::TimestampQueryInsidePasses),
"Timestamp query set created without the feature being enabled.");
DAWN_INVALID_IF(descriptor->pipelineStatisticsCount != 0,
diff --git a/src/dawn/native/RenderPassEncoder.cpp b/src/dawn/native/RenderPassEncoder.cpp
index 6965f12..8967c91 100644
--- a/src/dawn/native/RenderPassEncoder.cpp
+++ b/src/dawn/native/RenderPassEncoder.cpp
@@ -400,7 +400,8 @@
this,
[&](CommandAllocator* allocator) -> MaybeError {
if (IsValidationEnabled()) {
- DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex));
+ DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex,
+ Feature::TimestampQueryInsidePasses));
DAWN_TRY_CONTEXT(ValidateQueryIndexOverwrite(
querySet, queryIndex, mUsageTracker.GetQueryAvailabilityMap()),
"validating the timestamp query index (%u) of %s", queryIndex,
diff --git a/src/dawn/native/d3d12/AdapterD3D12.cpp b/src/dawn/native/d3d12/AdapterD3D12.cpp
index 3f61a40..a5da117 100644
--- a/src/dawn/native/d3d12/AdapterD3D12.cpp
+++ b/src/dawn/native/d3d12/AdapterD3D12.cpp
@@ -131,6 +131,7 @@
MaybeError Adapter::InitializeSupportedFeaturesImpl() {
if (AreTimestampQueriesSupported()) {
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
+ mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
}
mSupportedFeatures.EnableFeature(Feature::TextureCompressionBC);
mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
diff --git a/src/dawn/native/metal/BackendMTL.mm b/src/dawn/native/metal/BackendMTL.mm
index c2e75af..63321e0 100644
--- a/src/dawn/native/metal/BackendMTL.mm
+++ b/src/dawn/native/metal/BackendMTL.mm
@@ -339,6 +339,12 @@
if (IsGPUCounterSupported(*mDevice, MTLCommonCounterSetTimestamp,
{MTLCommonCounterTimestamp})) {
bool enableTimestampQuery = true;
+ bool enableTimestampQueryInsidePasses = true;
+
+ if (@available(macOS 11.0, iOS 14.0, *)) {
+ enableTimestampQueryInsidePasses =
+ SupportCounterSamplingAtCommandBoundary(*mDevice);
+ }
#if DAWN_PLATFORM_IS(MACOS)
// Disable timestamp query on < macOS 11.0 on AMD GPU because WriteTimestamp
@@ -346,12 +352,17 @@
// has been fixed on macOS 11.0. See crbug.com/dawn/545.
if (gpu_info::IsAMD(mVendorId) && !IsMacOSVersionAtLeast(11)) {
enableTimestampQuery = false;
+ enableTimestampQueryInsidePasses = false;
}
#endif
if (enableTimestampQuery) {
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
}
+
+ if (enableTimestampQueryInsidePasses) {
+ mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
+ }
}
}
diff --git a/src/dawn/native/vulkan/AdapterVk.cpp b/src/dawn/native/vulkan/AdapterVk.cpp
index 3779f9b..b05f03e 100644
--- a/src/dawn/native/vulkan/AdapterVk.cpp
+++ b/src/dawn/native/vulkan/AdapterVk.cpp
@@ -152,6 +152,7 @@
if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE &&
!IsAndroidQualcomm()) {
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
+ mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
}
if (IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT)) {
diff --git a/src/dawn/tests/end2end/QueryTests.cpp b/src/dawn/tests/end2end/QueryTests.cpp
index 6638875..f8cf53c 100644
--- a/src/dawn/tests/end2end/QueryTests.cpp
+++ b/src/dawn/tests/end2end/QueryTests.cpp
@@ -445,8 +445,6 @@
}
}
-DAWN_INSTANTIATE_TEST(OcclusionQueryTests, D3D12Backend(), MetalBackend(), VulkanBackend());
-
class PipelineStatisticsQueryTests : public QueryTests {
protected:
void SetUp() override {
@@ -490,13 +488,6 @@
wgpu::PipelineStatisticName::VertexShaderInvocations});
}
-DAWN_INSTANTIATE_TEST(PipelineStatisticsQueryTests,
- D3D12Backend(),
- MetalBackend(),
- OpenGLBackend(),
- OpenGLESBackend(),
- VulkanBackend());
-
class TimestampExpectation : public detail::Expectation {
public:
~TimestampExpectation() override = default;
@@ -744,122 +735,6 @@
}
}
-// Test calling timestamp query from render pass encoder
-TEST_P(TimestampQueryTests, TimestampOnRenderPass) {
- // TODO (dawn:1250): Split writeTimestamp() to another extension which is not supported on Apple
- // devices
- DAWN_TEST_UNSUPPORTED_IF(IsMacOS() && IsMetal() && IsApple());
-
- constexpr uint32_t kQueryCount = 2;
-
- // Write timestamp with different query indexes
- {
- wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
- wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
-
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
- wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
- pass.WriteTimestamp(querySet, 0);
- pass.WriteTimestamp(querySet, 1);
- pass.End();
- encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
- wgpu::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
- }
-
- // Write timestamp with same query index, not need test rewrite inside render pass due to it's
- // not allowed
- {
- wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
- wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
-
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- encoder.WriteTimestamp(querySet, 0);
- encoder.WriteTimestamp(querySet, 1);
-
- utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
- wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
- pass.WriteTimestamp(querySet, 0);
- pass.WriteTimestamp(querySet, 1);
- pass.End();
- encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
- wgpu::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
- }
-}
-
-// Test calling timestamp query from compute pass encoder
-TEST_P(TimestampQueryTests, TimestampOnComputePass) {
- // TODO (dawn:1250): Split writeTimestamp() to another extension which is not supported on Apple
- // devices
- DAWN_TEST_UNSUPPORTED_IF(IsMacOS() && IsMetal() && IsApple());
-
- constexpr uint32_t kQueryCount = 2;
-
- // Write timestamp with different query indexes
- {
- wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
- wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
-
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
- pass.WriteTimestamp(querySet, 0);
- pass.WriteTimestamp(querySet, 1);
- pass.End();
- encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
- wgpu::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
- }
-
- // Write timestamp with same query index on both the outside and the inside of the compute pass
- {
- wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
- wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
-
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- encoder.WriteTimestamp(querySet, 0);
- encoder.WriteTimestamp(querySet, 1);
-
- wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
- pass.WriteTimestamp(querySet, 0);
- pass.WriteTimestamp(querySet, 1);
- pass.End();
-
- encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
- wgpu::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
- }
-
- // Write timestamp with same query index inside compute pass
- {
- wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
- wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
-
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
- pass.WriteTimestamp(querySet, 0);
- pass.WriteTimestamp(querySet, 1);
- pass.WriteTimestamp(querySet, 0);
- pass.WriteTimestamp(querySet, 1);
- pass.End();
-
- encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
- wgpu::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
- }
-}
-
// Test timestampWrites with query set in compute pass descriptor
TEST_P(TimestampQueryTests, TimestampWritesQuerySetOnComputePass) {
// TODO(dawn:1489): Fails on Intel Windows Vulkan due to a driver issue that
@@ -1203,9 +1078,153 @@
EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
}
+class TimestampQueryInsidePassesTests : public TimestampQueryTests {
+ protected:
+ void SetUp() override {
+ DawnTest::SetUp();
+
+ // Skip all tests if timestamp feature is not supported
+ DAWN_TEST_UNSUPPORTED_IF(
+ !SupportsFeatures({wgpu::FeatureName::TimestampQueryInsidePasses}));
+ }
+
+ std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
+ std::vector<wgpu::FeatureName> requiredFeatures = {};
+ if (SupportsFeatures({wgpu::FeatureName::TimestampQueryInsidePasses})) {
+ requiredFeatures.push_back(wgpu::FeatureName::TimestampQueryInsidePasses);
+ // The timestamp query feature must be supported if the timestamp query inside passes
+ // feature is supported. Enable timestamp query for testing queries overwrite inside and
+ // outside of the passes.
+ requiredFeatures.push_back(wgpu::FeatureName::TimestampQuery);
+ }
+ return requiredFeatures;
+ }
+};
+
+// Test calling timestamp query from render pass encoder
+TEST_P(TimestampQueryInsidePassesTests, FromOnRenderPass) {
+ constexpr uint32_t kQueryCount = 2;
+
+ // Write timestamp with different query indexes
+ {
+ wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
+ wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
+ wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+ pass.WriteTimestamp(querySet, 0);
+ pass.WriteTimestamp(querySet, 1);
+ pass.End();
+ encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
+ }
+
+ // Write timestamp with same query index, not need test rewrite inside render pass due to it's
+ // not allowed
+ {
+ wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
+ wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ encoder.WriteTimestamp(querySet, 0);
+ encoder.WriteTimestamp(querySet, 1);
+
+ utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
+ wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+ pass.WriteTimestamp(querySet, 0);
+ pass.WriteTimestamp(querySet, 1);
+ pass.End();
+ encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
+ }
+}
+
+// Test calling timestamp query from compute pass encoder
+TEST_P(TimestampQueryInsidePassesTests, FromComputePass) {
+ constexpr uint32_t kQueryCount = 2;
+
+ // Write timestamp with different query indexes
+ {
+ wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
+ wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
+ pass.WriteTimestamp(querySet, 0);
+ pass.WriteTimestamp(querySet, 1);
+ pass.End();
+ encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
+ }
+
+ // Write timestamp with same query index on both the outside and the inside of the compute pass
+ {
+ wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
+ wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ encoder.WriteTimestamp(querySet, 0);
+ encoder.WriteTimestamp(querySet, 1);
+
+ wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
+ pass.WriteTimestamp(querySet, 0);
+ pass.WriteTimestamp(querySet, 1);
+ pass.End();
+
+ encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
+ }
+
+ // Write timestamp with same query index inside compute pass
+ {
+ wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
+ wgpu::Buffer destination = CreateResolveBuffer(kQueryCount * sizeof(uint64_t));
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
+ pass.WriteTimestamp(querySet, 0);
+ pass.WriteTimestamp(querySet, 1);
+ pass.WriteTimestamp(querySet, 0);
+ pass.WriteTimestamp(querySet, 1);
+ pass.End();
+
+ encoder.ResolveQuerySet(querySet, 0, kQueryCount, destination, 0);
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ EXPECT_BUFFER(destination, 0, kQueryCount * sizeof(uint64_t), new TimestampExpectation);
+ }
+}
+
+DAWN_INSTANTIATE_TEST(OcclusionQueryTests, D3D12Backend(), MetalBackend(), VulkanBackend());
+DAWN_INSTANTIATE_TEST(PipelineStatisticsQueryTests,
+ D3D12Backend(),
+ MetalBackend(),
+ OpenGLBackend(),
+ OpenGLESBackend(),
+ VulkanBackend());
DAWN_INSTANTIATE_TEST(TimestampQueryTests,
D3D12Backend(),
MetalBackend(),
OpenGLBackend(),
OpenGLESBackend(),
VulkanBackend());
+DAWN_INSTANTIATE_TEST(TimestampQueryInsidePassesTests,
+ D3D12Backend(),
+ MetalBackend(),
+ OpenGLBackend(),
+ OpenGLESBackend(),
+ VulkanBackend());
diff --git a/src/dawn/tests/unittests/validation/QueryValidationTests.cpp b/src/dawn/tests/unittests/validation/QueryValidationTests.cpp
index 5088351..d0289e2 100644
--- a/src/dawn/tests/unittests/validation/QueryValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/QueryValidationTests.cpp
@@ -562,8 +562,30 @@
}
}
+class TimestampQueryInsidePassesValidationTest : public QuerySetValidationTest {
+ protected:
+ WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
+ wgpu::DeviceDescriptor descriptor;
+ // The timestamp query feature must be supported if the timestamp query inside passes
+ // feature is supported. Enable timestamp query for validating queries overwrite inside and
+ // outside of the passes.
+ wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::TimestampQuery,
+ wgpu::FeatureName::TimestampQueryInsidePasses};
+ descriptor.requiredFeatures = requiredFeatures;
+ descriptor.requiredFeaturesCount = 2;
+
+ wgpu::DawnTogglesDeviceDescriptor togglesDesc;
+ descriptor.nextInChain = &togglesDesc;
+ const char* forceDisabledToggles[1] = {"disallow_unsafe_apis"};
+ togglesDesc.forceDisabledToggles = forceDisabledToggles;
+ togglesDesc.forceDisabledTogglesCount = 1;
+
+ return dawnAdapter.CreateDevice(&descriptor);
+ }
+};
+
// Test write timestamp on compute pass encoder
-TEST_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
+TEST_F(TimestampQueryInsidePassesValidationTest, WriteTimestampOnComputePassEncoder) {
wgpu::QuerySet timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
wgpu::QuerySet occlusionQuerySet = CreateQuerySet(device, wgpu::QueryType::Occlusion, 2);
@@ -609,7 +631,7 @@
}
// Test write timestamp on render pass encoder
-TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
+TEST_F(TimestampQueryInsidePassesValidationTest, WriteTimestampOnRenderPassEncoder) {
PlaceholderRenderPass renderPass(device);
wgpu::QuerySet timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
diff --git a/src/dawn/wire/SupportedFeatures.cpp b/src/dawn/wire/SupportedFeatures.cpp
index 59ab14f..1003dcd 100644
--- a/src/dawn/wire/SupportedFeatures.cpp
+++ b/src/dawn/wire/SupportedFeatures.cpp
@@ -27,6 +27,7 @@
return false;
case WGPUFeatureName_Depth32FloatStencil8:
case WGPUFeatureName_TimestampQuery:
+ case WGPUFeatureName_TimestampQueryInsidePasses:
case WGPUFeatureName_PipelineStatisticsQuery:
case WGPUFeatureName_TextureCompressionBC:
case WGPUFeatureName_TextureCompressionETC2: