Query API: Timestamp Query on Metal
- Add WriteTimestamp and ResolveQuerySet on Metal - Enable end2end tests of timestamp query on Metal - Lazy initialize the distination buffer in ResolveQuerySet - Update part of end2end tests to test from render pass instead of command encoder due to we cannot write timestamp on CommandEncoder without any copy commands on Metal. Bug: dawn:434 Change-Id: Ie9217e1f5a00bc252d6293ef7521c2e343ba9259 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/29020 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jiawei Shao <jiawei.shao@intel.com> Commit-Queue: Hao Li <hao.x.li@intel.com>
This commit is contained in:
parent
6c3da3dc5b
commit
936ef0a5f2
|
@ -23,6 +23,7 @@
|
||||||
#include "dawn_native/metal/ComputePipelineMTL.h"
|
#include "dawn_native/metal/ComputePipelineMTL.h"
|
||||||
#include "dawn_native/metal/DeviceMTL.h"
|
#include "dawn_native/metal/DeviceMTL.h"
|
||||||
#include "dawn_native/metal/PipelineLayoutMTL.h"
|
#include "dawn_native/metal/PipelineLayoutMTL.h"
|
||||||
|
#include "dawn_native/metal/QuerySetMTL.h"
|
||||||
#include "dawn_native/metal/RenderPipelineMTL.h"
|
#include "dawn_native/metal/RenderPipelineMTL.h"
|
||||||
#include "dawn_native/metal/SamplerMTL.h"
|
#include "dawn_native/metal/SamplerMTL.h"
|
||||||
#include "dawn_native/metal/TextureMTL.h"
|
#include "dawn_native/metal/TextureMTL.h"
|
||||||
|
@ -736,11 +737,39 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::ResolveQuerySet: {
|
case Command::ResolveQuerySet: {
|
||||||
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
|
ResolveQuerySetCmd* cmd = mCommands.NextCommand<ResolveQuerySetCmd>();
|
||||||
|
QuerySet* querySet = ToBackend(cmd->querySet.Get());
|
||||||
|
Buffer* destination = ToBackend(cmd->destination.Get());
|
||||||
|
|
||||||
|
destination->EnsureDataInitializedAsDestination(
|
||||||
|
commandContext, cmd->destinationOffset, cmd->queryCount * sizeof(uint64_t));
|
||||||
|
|
||||||
|
if (@available(macos 10.15, iOS 14.0, *)) {
|
||||||
|
[commandContext->EnsureBlit()
|
||||||
|
resolveCounters:querySet->GetCounterSampleBuffer()
|
||||||
|
inRange:NSMakeRange(cmd->firstQuery,
|
||||||
|
cmd->firstQuery + cmd->queryCount)
|
||||||
|
destinationBuffer:destination->GetMTLBuffer()
|
||||||
|
destinationOffset:NSUInteger(cmd->destinationOffset)];
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::WriteTimestamp: {
|
case Command::WriteTimestamp: {
|
||||||
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
|
WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();
|
||||||
|
QuerySet* querySet = ToBackend(cmd->querySet.Get());
|
||||||
|
|
||||||
|
if (@available(macos 10.15, iOS 14.0, *)) {
|
||||||
|
[commandContext->EnsureBlit()
|
||||||
|
sampleCountersInBuffer:querySet->GetCounterSampleBuffer()
|
||||||
|
atSampleIndex:NSUInteger(cmd->queryIndex)
|
||||||
|
withBarrier:YES];
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::InsertDebugMarker: {
|
case Command::InsertDebugMarker: {
|
||||||
|
@ -872,7 +901,17 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::WriteTimestamp: {
|
case Command::WriteTimestamp: {
|
||||||
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
|
WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();
|
||||||
|
QuerySet* querySet = ToBackend(cmd->querySet.Get());
|
||||||
|
|
||||||
|
if (@available(macos 10.15, iOS 14.0, *)) {
|
||||||
|
[encoder sampleCountersInBuffer:querySet->GetCounterSampleBuffer()
|
||||||
|
atSampleIndex:NSUInteger(cmd->queryIndex)
|
||||||
|
withBarrier:YES];
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
@ -1263,7 +1302,17 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::WriteTimestamp: {
|
case Command::WriteTimestamp: {
|
||||||
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
|
WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();
|
||||||
|
QuerySet* querySet = ToBackend(cmd->querySet.Get());
|
||||||
|
|
||||||
|
if (@available(macos 10.15, iOS 14.0, *)) {
|
||||||
|
[encoder sampleCountersInBuffer:querySet->GetCounterSampleBuffer()
|
||||||
|
atSampleIndex:NSUInteger(cmd->queryIndex)
|
||||||
|
withBarrier:YES];
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -1120,7 +1120,7 @@ TEST_P(BufferZeroInitTest, SetIndexBuffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the buffer will be lazily intialized correctly when its first use is an indirect buffer for
|
// Test the buffer will be lazily initialized correctly when its first use is an indirect buffer for
|
||||||
// DrawIndirect.
|
// DrawIndirect.
|
||||||
TEST_P(BufferZeroInitTest, IndirectBufferForDrawIndirect) {
|
TEST_P(BufferZeroInitTest, IndirectBufferForDrawIndirect) {
|
||||||
// Bind the whole buffer as an indirect buffer.
|
// Bind the whole buffer as an indirect buffer.
|
||||||
|
@ -1136,7 +1136,7 @@ TEST_P(BufferZeroInitTest, IndirectBufferForDrawIndirect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the buffer will be lazily intialized correctly when its first use is an indirect buffer for
|
// Test the buffer will be lazily initialized correctly when its first use is an indirect buffer for
|
||||||
// DrawIndexedIndirect.
|
// DrawIndexedIndirect.
|
||||||
TEST_P(BufferZeroInitTest, IndirectBufferForDrawIndexedIndirect) {
|
TEST_P(BufferZeroInitTest, IndirectBufferForDrawIndexedIndirect) {
|
||||||
// Bind the whole buffer as an indirect buffer.
|
// Bind the whole buffer as an indirect buffer.
|
||||||
|
@ -1152,7 +1152,7 @@ TEST_P(BufferZeroInitTest, IndirectBufferForDrawIndexedIndirect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the buffer will be lazily intialized correctly when its first use is an indirect buffer for
|
// Test the buffer will be lazily initialized correctly when its first use is an indirect buffer for
|
||||||
// DispatchIndirect.
|
// DispatchIndirect.
|
||||||
TEST_P(BufferZeroInitTest, IndirectBufferForDispatchIndirect) {
|
TEST_P(BufferZeroInitTest, IndirectBufferForDispatchIndirect) {
|
||||||
// Bind the whole buffer as an indirect buffer.
|
// Bind the whole buffer as an indirect buffer.
|
||||||
|
@ -1168,13 +1168,14 @@ TEST_P(BufferZeroInitTest, IndirectBufferForDispatchIndirect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the buffer will be lazily intialized correctly when its first use is in resolveQuerySet
|
// Test the buffer will be lazily initialized correctly when its first use is in resolveQuerySet
|
||||||
TEST_P(BufferZeroInitTest, ResolveQuerySet) {
|
TEST_P(BufferZeroInitTest, ResolveQuerySet) {
|
||||||
// Timestamp query is not supported on OpenGL
|
// Timestamp query is not supported on OpenGL
|
||||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||||
|
|
||||||
// TODO(hao.x.li@intel.com): Remove it after timestamp query is implementated on Metal
|
// TODO(hao.x.li@intel.com): Crash occurs if we only call WriteTimestamp in a command encoder
|
||||||
DAWN_SKIP_TEST_IF(IsMetal());
|
// without any copy commands on Metal on AMD GPU. See https://crbug.com/dawn/545.
|
||||||
|
DAWN_SKIP_TEST_IF(IsMetal() && IsAMD());
|
||||||
|
|
||||||
// Skip if timestamp extension is not supported on device
|
// Skip if timestamp extension is not supported on device
|
||||||
DAWN_SKIP_TEST_IF(!SupportsExtensions({"timestamp_query"}));
|
DAWN_SKIP_TEST_IF(!SupportsExtensions({"timestamp_query"}));
|
||||||
|
|
|
@ -141,8 +141,9 @@ TEST_P(TimestampQueryTests, QuerySetCreation) {
|
||||||
|
|
||||||
// Test calling timestamp query from command encoder
|
// Test calling timestamp query from command encoder
|
||||||
TEST_P(TimestampQueryTests, TimestampOnCommandEncoder) {
|
TEST_P(TimestampQueryTests, TimestampOnCommandEncoder) {
|
||||||
// TODO(hao.x.li@intel.com): Waiting for timestamp query implementation on Metal
|
// TODO(hao.x.li@intel.com): Crash occurs if we only call WriteTimestamp in a command encoder
|
||||||
DAWN_SKIP_TEST_IF(IsMetal());
|
// without any copy commands on Metal on AMD GPU. See https://crbug.com/dawn/545.
|
||||||
|
DAWN_SKIP_TEST_IF(IsMetal() && IsAMD());
|
||||||
|
|
||||||
constexpr uint32_t kQueryCount = 2;
|
constexpr uint32_t kQueryCount = 2;
|
||||||
|
|
||||||
|
@ -161,9 +162,6 @@ TEST_P(TimestampQueryTests, TimestampOnCommandEncoder) {
|
||||||
|
|
||||||
// Test calling timestamp query from render pass encoder
|
// Test calling timestamp query from render pass encoder
|
||||||
TEST_P(TimestampQueryTests, TimestampOnRenderPass) {
|
TEST_P(TimestampQueryTests, TimestampOnRenderPass) {
|
||||||
// TODO(hao.x.li@intel.com): Waiting for timestamp query implementation on Metal
|
|
||||||
DAWN_SKIP_TEST_IF(IsMetal());
|
|
||||||
|
|
||||||
constexpr uint32_t kQueryCount = 2;
|
constexpr uint32_t kQueryCount = 2;
|
||||||
|
|
||||||
wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
|
wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
|
||||||
|
@ -184,9 +182,6 @@ TEST_P(TimestampQueryTests, TimestampOnRenderPass) {
|
||||||
|
|
||||||
// Test calling timestamp query from compute pass encoder
|
// Test calling timestamp query from compute pass encoder
|
||||||
TEST_P(TimestampQueryTests, TimestampOnComputePass) {
|
TEST_P(TimestampQueryTests, TimestampOnComputePass) {
|
||||||
// TODO(hao.x.li@intel.com): Waiting for timestamp query implementation on Metal
|
|
||||||
DAWN_SKIP_TEST_IF(IsMetal());
|
|
||||||
|
|
||||||
constexpr uint32_t kQueryCount = 2;
|
constexpr uint32_t kQueryCount = 2;
|
||||||
|
|
||||||
wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
|
wgpu::QuerySet querySet = CreateQuerySetForTimestamp(kQueryCount);
|
||||||
|
@ -206,11 +201,14 @@ TEST_P(TimestampQueryTests, TimestampOnComputePass) {
|
||||||
|
|
||||||
// Test resolving timestamp query to one slot in the buffer
|
// Test resolving timestamp query to one slot in the buffer
|
||||||
TEST_P(TimestampQueryTests, ResolveToBufferWithOffset) {
|
TEST_P(TimestampQueryTests, ResolveToBufferWithOffset) {
|
||||||
// TODO(hao.x.li@intel.com): Failed on old Intel Vulkan driver on Windows, need investigation.
|
// TODO(hao.x.li@intel.com): Fail to resolve query to buffer with offset on Windows Vulkan and
|
||||||
|
// Metal on Intel platforms, need investigation.
|
||||||
DAWN_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
|
DAWN_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
|
||||||
|
DAWN_SKIP_TEST_IF(IsIntel() && IsMetal());
|
||||||
|
|
||||||
// TODO(hao.x.li@intel.com): Waiting for timestamp query implementation on Metal
|
// TODO(hao.x.li@intel.com): Crash occurs if we only call WriteTimestamp in a command encoder
|
||||||
DAWN_SKIP_TEST_IF(IsMetal());
|
// without any copy commands on Metal on AMD GPU. See https://crbug.com/dawn/545.
|
||||||
|
DAWN_SKIP_TEST_IF(IsMetal() && IsAMD());
|
||||||
|
|
||||||
constexpr uint32_t kQueryCount = 2;
|
constexpr uint32_t kQueryCount = 2;
|
||||||
constexpr uint64_t kZero = 0;
|
constexpr uint64_t kZero = 0;
|
||||||
|
|
Loading…
Reference in New Issue