mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-26 16:33:33 +00:00
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": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
||||||
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
||||||
{"value": 1004, "name": "dawn native", "tags": ["dawn", "native"]},
|
{"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": {
|
"filter mode": {
|
||||||
|
@ -19,11 +19,13 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "dawn/common/BitSetIterator.h"
|
#include "dawn/common/BitSetIterator.h"
|
||||||
|
#include "dawn/native/Adapter.h"
|
||||||
#include "dawn/native/BindGroup.h"
|
#include "dawn/native/BindGroup.h"
|
||||||
#include "dawn/native/Buffer.h"
|
#include "dawn/native/Buffer.h"
|
||||||
#include "dawn/native/CommandBufferStateTracker.h"
|
#include "dawn/native/CommandBufferStateTracker.h"
|
||||||
#include "dawn/native/Commands.h"
|
#include "dawn/native/Commands.h"
|
||||||
#include "dawn/native/Device.h"
|
#include "dawn/native/Device.h"
|
||||||
|
#include "dawn/native/Instance.h"
|
||||||
#include "dawn/native/PassResourceUsage.h"
|
#include "dawn/native/PassResourceUsage.h"
|
||||||
#include "dawn/native/QuerySet.h"
|
#include "dawn/native/QuerySet.h"
|
||||||
#include "dawn/native/RenderBundle.h"
|
#include "dawn/native/RenderBundle.h"
|
||||||
@ -68,9 +70,17 @@ MaybeError ValidateSyncScopeResourceUsage(const SyncScopeResourceUsage& scope) {
|
|||||||
|
|
||||||
MaybeError ValidateTimestampQuery(const DeviceBase* device,
|
MaybeError ValidateTimestampQuery(const DeviceBase* device,
|
||||||
const QuerySetBase* querySet,
|
const QuerySetBase* querySet,
|
||||||
uint32_t queryIndex) {
|
uint32_t queryIndex,
|
||||||
|
Feature requiredFeature) {
|
||||||
DAWN_TRY(device->ValidateObject(querySet));
|
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,
|
DAWN_INVALID_IF(querySet->GetQueryType() != wgpu::QueryType::Timestamp,
|
||||||
"The type of %s is not %s.", querySet, 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/CommandAllocator.h"
|
||||||
#include "dawn/native/Error.h"
|
#include "dawn/native/Error.h"
|
||||||
|
#include "dawn/native/Features.h"
|
||||||
#include "dawn/native/Texture.h"
|
#include "dawn/native/Texture.h"
|
||||||
#include "dawn/native/UsageValidationMode.h"
|
#include "dawn/native/UsageValidationMode.h"
|
||||||
|
|
||||||
@ -32,7 +33,8 @@ MaybeError ValidateSyncScopeResourceUsage(const SyncScopeResourceUsage& usage);
|
|||||||
|
|
||||||
MaybeError ValidateTimestampQuery(const DeviceBase* device,
|
MaybeError ValidateTimestampQuery(const DeviceBase* device,
|
||||||
const QuerySetBase* querySet,
|
const QuerySetBase* querySet,
|
||||||
uint32_t queryIndex);
|
uint32_t queryIndex,
|
||||||
|
Feature requiredFeature = Feature::TimestampQuery);
|
||||||
|
|
||||||
MaybeError ValidateWriteBuffer(const DeviceBase* device,
|
MaybeError ValidateWriteBuffer(const DeviceBase* device,
|
||||||
const BufferBase* buffer,
|
const BufferBase* buffer,
|
||||||
|
@ -433,7 +433,8 @@ void ComputePassEncoder::APIWriteTimestamp(QuerySetBase* querySet, uint32_t quer
|
|||||||
this,
|
this,
|
||||||
[&](CommandAllocator* allocator) -> MaybeError {
|
[&](CommandAllocator* allocator) -> MaybeError {
|
||||||
if (IsValidationEnabled()) {
|
if (IsValidationEnabled()) {
|
||||||
DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex));
|
DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex,
|
||||||
|
Feature::TimestampQueryInsidePasses));
|
||||||
}
|
}
|
||||||
|
|
||||||
mCommandEncoder->TrackQueryAvailability(querySet, queryIndex);
|
mCommandEncoder->TrackQueryAvailability(querySet, queryIndex);
|
||||||
|
@ -51,6 +51,10 @@ static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {{
|
|||||||
{Feature::TimestampQuery,
|
{Feature::TimestampQuery,
|
||||||
{"timestamp-query", "Support Timestamp Query",
|
{"timestamp-query", "Support Timestamp Query",
|
||||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=434", FeatureInfo::FeatureState::Stable}},
|
"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,
|
{Feature::DepthClipControl,
|
||||||
{"depth-clip-control", "Disable depth clipping of primitives to the clip volume",
|
{"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}},
|
"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:
|
case wgpu::FeatureName::TimestampQuery:
|
||||||
return Feature::TimestampQuery;
|
return Feature::TimestampQuery;
|
||||||
|
case wgpu::FeatureName::TimestampQueryInsidePasses:
|
||||||
|
return Feature::TimestampQueryInsidePasses;
|
||||||
case wgpu::FeatureName::PipelineStatisticsQuery:
|
case wgpu::FeatureName::PipelineStatisticsQuery:
|
||||||
return Feature::PipelineStatisticsQuery;
|
return Feature::PipelineStatisticsQuery;
|
||||||
case wgpu::FeatureName::TextureCompressionBC:
|
case wgpu::FeatureName::TextureCompressionBC:
|
||||||
@ -142,6 +148,8 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
|||||||
return wgpu::FeatureName::PipelineStatisticsQuery;
|
return wgpu::FeatureName::PipelineStatisticsQuery;
|
||||||
case Feature::TimestampQuery:
|
case Feature::TimestampQuery:
|
||||||
return wgpu::FeatureName::TimestampQuery;
|
return wgpu::FeatureName::TimestampQuery;
|
||||||
|
case Feature::TimestampQueryInsidePasses:
|
||||||
|
return wgpu::FeatureName::TimestampQueryInsidePasses;
|
||||||
case Feature::DepthClipControl:
|
case Feature::DepthClipControl:
|
||||||
return wgpu::FeatureName::DepthClipControl;
|
return wgpu::FeatureName::DepthClipControl;
|
||||||
case Feature::Depth32FloatStencil8:
|
case Feature::Depth32FloatStencil8:
|
||||||
|
@ -32,6 +32,7 @@ enum class Feature {
|
|||||||
TextureCompressionASTC,
|
TextureCompressionASTC,
|
||||||
PipelineStatisticsQuery,
|
PipelineStatisticsQuery,
|
||||||
TimestampQuery,
|
TimestampQuery,
|
||||||
|
TimestampQueryInsidePasses,
|
||||||
DepthClipControl,
|
DepthClipControl,
|
||||||
Depth32FloatStencil8,
|
Depth32FloatStencil8,
|
||||||
ChromiumExperimentalDp4a,
|
ChromiumExperimentalDp4a,
|
||||||
|
@ -82,7 +82,8 @@ MaybeError ValidateQuerySetDescriptor(DeviceBase* device, const QuerySetDescript
|
|||||||
"Timestamp queries are disallowed because they may expose precise "
|
"Timestamp queries are disallowed because they may expose precise "
|
||||||
"timing information.");
|
"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.");
|
"Timestamp query set created without the feature being enabled.");
|
||||||
|
|
||||||
DAWN_INVALID_IF(descriptor->pipelineStatisticsCount != 0,
|
DAWN_INVALID_IF(descriptor->pipelineStatisticsCount != 0,
|
||||||
|
@ -400,7 +400,8 @@ void RenderPassEncoder::APIWriteTimestamp(QuerySetBase* querySet, uint32_t query
|
|||||||
this,
|
this,
|
||||||
[&](CommandAllocator* allocator) -> MaybeError {
|
[&](CommandAllocator* allocator) -> MaybeError {
|
||||||
if (IsValidationEnabled()) {
|
if (IsValidationEnabled()) {
|
||||||
DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex));
|
DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex,
|
||||||
|
Feature::TimestampQueryInsidePasses));
|
||||||
DAWN_TRY_CONTEXT(ValidateQueryIndexOverwrite(
|
DAWN_TRY_CONTEXT(ValidateQueryIndexOverwrite(
|
||||||
querySet, queryIndex, mUsageTracker.GetQueryAvailabilityMap()),
|
querySet, queryIndex, mUsageTracker.GetQueryAvailabilityMap()),
|
||||||
"validating the timestamp query index (%u) of %s", queryIndex,
|
"validating the timestamp query index (%u) of %s", queryIndex,
|
||||||
|
@ -131,6 +131,7 @@ bool Adapter::AreTimestampQueriesSupported() const {
|
|||||||
MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
if (AreTimestampQueriesSupported()) {
|
if (AreTimestampQueriesSupported()) {
|
||||||
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
|
||||||
}
|
}
|
||||||
mSupportedFeatures.EnableFeature(Feature::TextureCompressionBC);
|
mSupportedFeatures.EnableFeature(Feature::TextureCompressionBC);
|
||||||
mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
|
mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
|
||||||
|
@ -339,6 +339,12 @@ class Adapter : public AdapterBase {
|
|||||||
if (IsGPUCounterSupported(*mDevice, MTLCommonCounterSetTimestamp,
|
if (IsGPUCounterSupported(*mDevice, MTLCommonCounterSetTimestamp,
|
||||||
{MTLCommonCounterTimestamp})) {
|
{MTLCommonCounterTimestamp})) {
|
||||||
bool enableTimestampQuery = true;
|
bool enableTimestampQuery = true;
|
||||||
|
bool enableTimestampQueryInsidePasses = true;
|
||||||
|
|
||||||
|
if (@available(macOS 11.0, iOS 14.0, *)) {
|
||||||
|
enableTimestampQueryInsidePasses =
|
||||||
|
SupportCounterSamplingAtCommandBoundary(*mDevice);
|
||||||
|
}
|
||||||
|
|
||||||
#if DAWN_PLATFORM_IS(MACOS)
|
#if DAWN_PLATFORM_IS(MACOS)
|
||||||
// Disable timestamp query on < macOS 11.0 on AMD GPU because WriteTimestamp
|
// 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.
|
// has been fixed on macOS 11.0. See crbug.com/dawn/545.
|
||||||
if (gpu_info::IsAMD(mVendorId) && !IsMacOSVersionAtLeast(11)) {
|
if (gpu_info::IsAMD(mVendorId) && !IsMacOSVersionAtLeast(11)) {
|
||||||
enableTimestampQuery = false;
|
enableTimestampQuery = false;
|
||||||
|
enableTimestampQueryInsidePasses = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (enableTimestampQuery) {
|
if (enableTimestampQuery) {
|
||||||
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enableTimestampQueryInsidePasses) {
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +152,7 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
|||||||
if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE &&
|
if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE &&
|
||||||
!IsAndroidQualcomm()) {
|
!IsAndroidQualcomm()) {
|
||||||
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::TimestampQueryInsidePasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT)) {
|
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 {
|
class PipelineStatisticsQueryTests : public QueryTests {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
@ -490,13 +488,6 @@ TEST_P(PipelineStatisticsQueryTests, QuerySetCreation) {
|
|||||||
wgpu::PipelineStatisticName::VertexShaderInvocations});
|
wgpu::PipelineStatisticName::VertexShaderInvocations});
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(PipelineStatisticsQueryTests,
|
|
||||||
D3D12Backend(),
|
|
||||||
MetalBackend(),
|
|
||||||
OpenGLBackend(),
|
|
||||||
OpenGLESBackend(),
|
|
||||||
VulkanBackend());
|
|
||||||
|
|
||||||
class TimestampExpectation : public detail::Expectation {
|
class TimestampExpectation : public detail::Expectation {
|
||||||
public:
|
public:
|
||||||
~TimestampExpectation() override = default;
|
~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 timestampWrites with query set in compute pass descriptor
|
||||||
TEST_P(TimestampQueryTests, TimestampWritesQuerySetOnComputePass) {
|
TEST_P(TimestampQueryTests, TimestampWritesQuerySetOnComputePass) {
|
||||||
// TODO(dawn:1489): Fails on Intel Windows Vulkan due to a driver issue that
|
// 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);
|
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,
|
DAWN_INSTANTIATE_TEST(TimestampQueryTests,
|
||||||
D3D12Backend(),
|
D3D12Backend(),
|
||||||
MetalBackend(),
|
MetalBackend(),
|
||||||
OpenGLBackend(),
|
OpenGLBackend(),
|
||||||
OpenGLESBackend(),
|
OpenGLESBackend(),
|
||||||
VulkanBackend());
|
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 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 timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
|
||||||
wgpu::QuerySet occlusionQuerySet = CreateQuerySet(device, wgpu::QueryType::Occlusion, 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 write timestamp on render pass encoder
|
||||||
TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
|
TEST_F(TimestampQueryInsidePassesValidationTest, WriteTimestampOnRenderPassEncoder) {
|
||||||
PlaceholderRenderPass renderPass(device);
|
PlaceholderRenderPass renderPass(device);
|
||||||
|
|
||||||
wgpu::QuerySet timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
|
wgpu::QuerySet timestampQuerySet = CreateQuerySet(device, wgpu::QueryType::Timestamp, 2);
|
||||||
|
@ -27,6 +27,7 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
|||||||
return false;
|
return false;
|
||||||
case WGPUFeatureName_Depth32FloatStencil8:
|
case WGPUFeatureName_Depth32FloatStencil8:
|
||||||
case WGPUFeatureName_TimestampQuery:
|
case WGPUFeatureName_TimestampQuery:
|
||||||
|
case WGPUFeatureName_TimestampQueryInsidePasses:
|
||||||
case WGPUFeatureName_PipelineStatisticsQuery:
|
case WGPUFeatureName_PipelineStatisticsQuery:
|
||||||
case WGPUFeatureName_TextureCompressionBC:
|
case WGPUFeatureName_TextureCompressionBC:
|
||||||
case WGPUFeatureName_TextureCompressionETC2:
|
case WGPUFeatureName_TextureCompressionETC2:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user