Query API: Non-precise occlusion query on Metal

- Add occlusionQuerySet to BeginRenderPassCmd
- Implement BeginOcclusionQuery/EndOcclusionQuery on Metal
- Enable occlusion end2end tests on Metal

Bug: dawn:434
Change-Id: I6c6ed74c77eb7e66f21fc5b8aa97b80eddb1111f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38784
Commit-Queue: Hao Li <hao.x.li@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Hao Li 2021-02-02 05:30:50 +00:00 committed by Commit Bot service account
parent 9a2174a37c
commit d11f4c3d05
4 changed files with 35 additions and 15 deletions

View File

@ -563,6 +563,8 @@ namespace dawn_native {
cmd->width = width; cmd->width = width;
cmd->height = height; cmd->height = height;
cmd->occlusionQuerySet = descriptor->occlusionQuerySet;
return {}; return {};
}); });

View File

@ -100,6 +100,8 @@ namespace dawn_native {
// Cache the width and height of all attachments for convenience // Cache the width and height of all attachments for convenience
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
Ref<QuerySetBase> occlusionQuerySet;
}; };
struct BufferCopy { struct BufferCopy {

View File

@ -176,6 +176,11 @@ namespace dawn_native { namespace metal {
} }
} }
if (renderPass->occlusionQuerySet.Get() != nullptr) {
descriptor.visibilityResultBuffer =
ToBackend(renderPass->occlusionQuerySet.Get())->GetVisibilityBuffer();
}
return descriptorRef; return descriptorRef;
} }
@ -756,15 +761,24 @@ namespace dawn_native { namespace metal {
destination->EnsureDataInitializedAsDestination( destination->EnsureDataInitializedAsDestination(
commandContext, cmd->destinationOffset, cmd->queryCount * sizeof(uint64_t)); commandContext, cmd->destinationOffset, cmd->queryCount * sizeof(uint64_t));
if (@available(macos 10.15, iOS 14.0, *)) { if (querySet->GetQueryType() == wgpu::QueryType::Occlusion) {
[commandContext->EnsureBlit() [commandContext->EnsureBlit()
resolveCounters:querySet->GetCounterSampleBuffer() copyFromBuffer:querySet->GetVisibilityBuffer()
inRange:NSMakeRange(cmd->firstQuery, sourceOffset:NSUInteger(cmd->firstQuery * sizeof(uint64_t))
cmd->firstQuery + cmd->queryCount) toBuffer:destination->GetMTLBuffer()
destinationBuffer:destination->GetMTLBuffer() destinationOffset:NSUInteger(cmd->destinationOffset)
destinationOffset:NSUInteger(cmd->destinationOffset)]; size:NSUInteger(cmd->queryCount * sizeof(uint64_t))];
} else { } else {
UNREACHABLE(); 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; break;
} }
@ -1284,11 +1298,19 @@ namespace dawn_native { namespace metal {
} }
case Command::BeginOcclusionQuery: { case Command::BeginOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation."); BeginOcclusionQueryCmd* cmd = mCommands.NextCommand<BeginOcclusionQueryCmd>();
[encoder setVisibilityResultMode:MTLVisibilityResultModeBoolean
offset:cmd->queryIndex * sizeof(uint64_t)];
break;
} }
case Command::EndOcclusionQuery: { case Command::EndOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation."); EndOcclusionQueryCmd* cmd = mCommands.NextCommand<EndOcclusionQueryCmd>();
[encoder setVisibilityResultMode:MTLVisibilityResultModeDisabled
offset:cmd->queryIndex * sizeof(uint64_t)];
break;
} }
case Command::WriteTimestamp: { case Command::WriteTimestamp: {

View File

@ -227,9 +227,6 @@ TEST_P(OcclusionQueryTests, QuerySetDestroy) {
// zero indicates that no sample passed depth/stencil testing, // zero indicates that no sample passed depth/stencil testing,
// non-zero indicates that at least one sample passed depth/stencil testing. // non-zero indicates that at least one sample passed depth/stencil testing.
TEST_P(OcclusionQueryTests, QueryWithDepthStencilTest) { TEST_P(OcclusionQueryTests, QueryWithDepthStencilTest) {
// TODO(hao.x.li@intel.com): Implement non-precise occlusion on Metal
DAWN_SKIP_TEST_IF(IsMetal());
// Disable depth/stencil testing, the samples always pass the testing, the expected occlusion // Disable depth/stencil testing, the samples always pass the testing, the expected occlusion
// result is non-zero. // result is non-zero.
TestOcclusionQueryWithDepthStencilTest(false, false, OcclusionExpectation::Result::NonZero); TestOcclusionQueryWithDepthStencilTest(false, false, OcclusionExpectation::Result::NonZero);
@ -248,9 +245,6 @@ TEST_P(OcclusionQueryTests, QueryWithDepthStencilTest) {
// zero indicates that no sample passed scissor testing, // zero indicates that no sample passed scissor testing,
// non-zero indicates that at least one sample passed scissor testing. // non-zero indicates that at least one sample passed scissor testing.
TEST_P(OcclusionQueryTests, QueryWithScissorTest) { TEST_P(OcclusionQueryTests, QueryWithScissorTest) {
// TODO(hao.x.li@intel.com): Implement non-precise occlusion on Metal
DAWN_SKIP_TEST_IF(IsMetal());
// Test there are samples passed scissor testing, the expected occlusion result is non-zero. // Test there are samples passed scissor testing, the expected occlusion result is non-zero.
TestOcclusionQueryWithScissorTest({2, 1, 2, 1}, OcclusionExpectation::Result::NonZero); TestOcclusionQueryWithScissorTest({2, 1, 2, 1}, OcclusionExpectation::Result::NonZero);