mirror of
				https://github.com/encounter/dawn-cmake.git
				synced 2025-10-28 12:39:52 +00:00 
			
		
		
		
	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user