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>
This commit is contained in:
parent
e366dcf747
commit
74f6bc7e40
|
@ -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": {
|
||||
|
|
|
@ -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 ValidateSyncScopeResourceUsage(const SyncScopeResourceUsage& scope) {
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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 ValidateSyncScopeResourceUsage(const SyncScopeResourceUsage& usage);
|
|||
|
||||
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,
|
||||
|
|
|
@ -433,7 +433,8 @@ void ComputePassEncoder::APIWriteTimestamp(QuerySetBase* querySet, uint32_t quer
|
|||
this,
|
||||
[&](CommandAllocator* allocator) -> MaybeError {
|
||||
if (IsValidationEnabled()) {
|
||||
DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex));
|
||||
DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex,
|
||||
Feature::TimestampQueryInsidePasses));
|
||||
}
|
||||
|
||||
mCommandEncoder->TrackQueryAvailability(querySet, queryIndex);
|
||||
|
|
|
@ -51,6 +51,10 @@ static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {{
|
|||
{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 @@ Feature FromAPIFeature(wgpu::FeatureName feature) {
|
|||
|
||||
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 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
|||
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:
|
||||
|
|
|
@ -32,6 +32,7 @@ enum class Feature {
|
|||
TextureCompressionASTC,
|
||||
PipelineStatisticsQuery,
|
||||
TimestampQuery,
|
||||
TimestampQueryInsidePasses,
|
||||
DepthClipControl,
|
||||
Depth32FloatStencil8,
|
||||
ChromiumExperimentalDp4a,
|
||||
|
|
|
@ -82,7 +82,8 @@ MaybeError ValidateQuerySetDescriptor(DeviceBase* device, const QuerySetDescript
|
|||
"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,
|
||||
|
|
|
@ -400,7 +400,8 @@ void RenderPassEncoder::APIWriteTimestamp(QuerySetBase* querySet, uint32_t query
|
|||
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,
|
||||
|
|
|
@ -131,6 +131,7 @@ bool Adapter::AreTimestampQueriesSupported() const {
|
|||
MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||
if (AreTimestampQueriesSupported()) {
|
||||
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
||||
mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
|
||||
}
|
||||
mSupportedFeatures.EnableFeature(Feature::TextureCompressionBC);
|
||||
mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
|
||||
|
|
|
@ -339,6 +339,12 @@ class Adapter : public AdapterBase {
|
|||
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 @@ class Adapter : public AdapterBase {
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
|||
if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE &&
|
||||
!IsAndroidQualcomm()) {
|
||||
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
||||
mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
|
||||
}
|
||||
|
||||
if (IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT)) {
|
||||
|
|
|
@ -445,8 +445,6 @@ TEST_P(OcclusionQueryTests, ResolveToBufferWithOffset) {
|
|||
}
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(OcclusionQueryTests, D3D12Backend(), MetalBackend(), VulkanBackend());
|
||||
|
||||
class PipelineStatisticsQueryTests : public QueryTests {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
|
@ -490,13 +488,6 @@ TEST_P(PipelineStatisticsQueryTests, QuerySetCreation) {
|
|||
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_P(TimestampQueryTests, TimestampOnCommandEncoder) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 @@ TEST_P(TimestampQueryTests, ResolveTwiceToSameBuffer) {
|
|||
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());
|
||||
|
|
|
@ -562,8 +562,30 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnCommandEncoder) {
|
|||
}
|
||||
}
|
||||
|
||||
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_F(TimestampQueryValidationTest, WriteTimestampOnComputePassEncoder) {
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
|
|
@ -27,6 +27,7 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
|||
return false;
|
||||
case WGPUFeatureName_Depth32FloatStencil8:
|
||||
case WGPUFeatureName_TimestampQuery:
|
||||
case WGPUFeatureName_TimestampQueryInsidePasses:
|
||||
case WGPUFeatureName_PipelineStatisticsQuery:
|
||||
case WGPUFeatureName_TextureCompressionBC:
|
||||
case WGPUFeatureName_TextureCompressionETC2:
|
||||
|
|
Loading…
Reference in New Issue