Query API: Non Precise Occlusion Query

- Add BeginOcclusionQuery and EndOcclusionQuery in frontend
- Set occlusion query as unsafe APIs
- Add validation tests

Bug: dawn:434
Change-Id: I3d1cefed780812dd62fb082287ff71530b76ebee
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/31321
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Hao Li
2020-11-18 09:47:52 +00:00
committed by Commit Bot service account
parent 55f251dffe
commit 01e4450729
13 changed files with 373 additions and 4 deletions

View File

@@ -324,7 +324,19 @@ namespace dawn_native {
}
if (descriptor->occlusionQuerySet != nullptr) {
return DAWN_VALIDATION_ERROR("occlusionQuerySet not implemented");
DAWN_TRY(device->ValidateObject(descriptor->occlusionQuerySet));
// Occlusion query has not been implemented completely. Disallow it as unsafe until
// the implementaion is completed.
if (device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) {
return DAWN_VALIDATION_ERROR(
"Occlusion query is disallowed because it has not been implemented "
"completely.");
}
if (descriptor->occlusionQuerySet->GetQueryType() != wgpu::QueryType::Occlusion) {
return DAWN_VALIDATION_ERROR("The type of query set must be Occlusion");
}
}
if (descriptor->colorAttachmentCount == 0 &&
@@ -508,8 +520,9 @@ namespace dawn_native {
});
if (success) {
RenderPassEncoder* passEncoder = new RenderPassEncoder(
device, this, &mEncodingContext, std::move(usageTracker), width, height);
RenderPassEncoder* passEncoder =
new RenderPassEncoder(device, this, &mEncodingContext, std::move(usageTracker),
descriptor->occlusionQuerySet, width, height);
mEncodingContext.EnterPass(passEncoder);
return passEncoder;
}

View File

@@ -159,6 +159,16 @@ namespace dawn_native {
Command type;
while (commands->NextCommandId(&type)) {
switch (type) {
case Command::BeginOcclusionQuery: {
commands->NextCommand<BeginOcclusionQueryCmd>();
break;
}
case Command::EndOcclusionQuery: {
commands->NextCommand<EndOcclusionQueryCmd>();
break;
}
case Command::EndRenderPass: {
commands->NextCommand<EndRenderPassCmd>();
DAWN_TRY(ValidateFinalDebugGroupStackSize(debugGroupStackSize));

View File

@@ -36,6 +36,11 @@ namespace dawn_native {
begin->~BeginComputePassCmd();
break;
}
case Command::BeginOcclusionQuery: {
BeginOcclusionQueryCmd* begin = commands->NextCommand<BeginOcclusionQueryCmd>();
begin->~BeginOcclusionQueryCmd();
break;
}
case Command::BeginRenderPass: {
BeginRenderPassCmd* begin = commands->NextCommand<BeginRenderPassCmd>();
begin->~BeginRenderPassCmd();
@@ -97,6 +102,11 @@ namespace dawn_native {
cmd->~EndComputePassCmd();
break;
}
case Command::EndOcclusionQuery: {
EndOcclusionQueryCmd* cmd = commands->NextCommand<EndOcclusionQueryCmd>();
cmd->~EndOcclusionQueryCmd();
break;
}
case Command::EndRenderPass: {
EndRenderPassCmd* cmd = commands->NextCommand<EndRenderPassCmd>();
cmd->~EndRenderPassCmd();
@@ -198,6 +208,10 @@ namespace dawn_native {
commands->NextCommand<BeginComputePassCmd>();
break;
case Command::BeginOcclusionQuery:
commands->NextCommand<BeginOcclusionQueryCmd>();
break;
case Command::BeginRenderPass:
commands->NextCommand<BeginRenderPassCmd>();
break;
@@ -246,6 +260,10 @@ namespace dawn_native {
commands->NextCommand<EndComputePassCmd>();
break;
case Command::EndOcclusionQuery:
commands->NextCommand<EndOcclusionQueryCmd>();
break;
case Command::EndRenderPass:
commands->NextCommand<EndRenderPassCmd>();
break;

View File

@@ -34,6 +34,7 @@ namespace dawn_native {
enum class Command {
BeginComputePass,
BeginOcclusionQuery,
BeginRenderPass,
CopyBufferToBuffer,
CopyBufferToTexture,
@@ -46,6 +47,7 @@ namespace dawn_native {
DrawIndirect,
DrawIndexedIndirect,
EndComputePass,
EndOcclusionQuery,
EndRenderPass,
ExecuteBundles,
InsertDebugMarker,
@@ -66,6 +68,11 @@ namespace dawn_native {
struct BeginComputePassCmd {};
struct BeginOcclusionQueryCmd {
Ref<QuerySetBase> querySet;
uint32_t queryIndex;
};
struct RenderPassColorAttachmentInfo {
Ref<TextureViewBase> view;
Ref<TextureViewBase> resolveTarget;
@@ -173,6 +180,11 @@ namespace dawn_native {
struct EndComputePassCmd {};
struct EndOcclusionQueryCmd {
Ref<QuerySetBase> querySet;
uint32_t queryIndex;
};
struct EndRenderPassCmd {};
struct ExecuteBundlesCmd {

View File

@@ -52,12 +52,14 @@ namespace dawn_native {
CommandEncoder* commandEncoder,
EncodingContext* encodingContext,
PassResourceUsageTracker usageTracker,
QuerySetBase* occlusionQuerySet,
uint32_t renderTargetWidth,
uint32_t renderTargetHeight)
: RenderEncoderBase(device, encodingContext),
mCommandEncoder(commandEncoder),
mRenderTargetWidth(renderTargetWidth),
mRenderTargetHeight(renderTargetHeight) {
mRenderTargetHeight(renderTargetHeight),
mOcclusionQuerySet(occlusionQuerySet) {
mUsageTracker = std::move(usageTracker);
}
@@ -94,6 +96,13 @@ namespace dawn_native {
if (mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
allocator->Allocate<EndRenderPassCmd>(Command::EndRenderPass);
if (GetDevice()->IsValidationEnabled()) {
if (mOcclusionQueryActive) {
return DAWN_VALIDATION_ERROR(
"The occlusion query must be ended before endPass.");
}
}
return {};
})) {
mEncodingContext->ExitPass(this, mUsageTracker.AcquireResourceUsage());
@@ -208,6 +217,67 @@ namespace dawn_native {
});
}
void RenderPassEncoder::BeginOcclusionQuery(uint32_t queryIndex) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (GetDevice()->IsValidationEnabled()) {
if (mOcclusionQuerySet.Get() == nullptr) {
return DAWN_VALIDATION_ERROR(
"The occlusionQuerySet in RenderPassDescriptor must be set.");
}
// The type of querySet has been validated by ValidateRenderPassDescriptor
if (queryIndex >= mOcclusionQuerySet->GetQueryCount()) {
return DAWN_VALIDATION_ERROR(
"Query index exceeds the number of queries in query set.");
}
if (mOcclusionQueryActive) {
return DAWN_VALIDATION_ERROR(
"Only a single occlusion query can be begun at a time.");
}
DAWN_TRY(ValidateQueryIndexOverwrite(mOcclusionQuerySet.Get(), queryIndex,
GetQueryAvailabilityMap()));
mCommandEncoder->TrackUsedQuerySet(mOcclusionQuerySet.Get());
}
// Record the current query index for endOcclusionQuery.
mCurrentOcclusionQueryIndex = queryIndex;
mOcclusionQueryActive = true;
BeginOcclusionQueryCmd* cmd =
allocator->Allocate<BeginOcclusionQueryCmd>(Command::BeginOcclusionQuery);
cmd->querySet = mOcclusionQuerySet.Get();
cmd->queryIndex = queryIndex;
return {};
});
}
void RenderPassEncoder::EndOcclusionQuery() {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (GetDevice()->IsValidationEnabled()) {
if (!mOcclusionQueryActive) {
return DAWN_VALIDATION_ERROR(
"EndOcclusionQuery cannot be called without corresponding "
"BeginOcclusionQuery.");
}
}
TrackQueryAvailability(mOcclusionQuerySet.Get(), mCurrentOcclusionQueryIndex);
mOcclusionQueryActive = false;
EndOcclusionQueryCmd* cmd =
allocator->Allocate<EndOcclusionQueryCmd>(Command::EndOcclusionQuery);
cmd->querySet = mOcclusionQuerySet.Get();
cmd->queryIndex = mCurrentOcclusionQueryIndex;
return {};
});
}
void RenderPassEncoder::WriteTimestamp(QuerySetBase* querySet, uint32_t queryIndex) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (GetDevice()->IsValidationEnabled()) {

View File

@@ -28,6 +28,7 @@ namespace dawn_native {
CommandEncoder* commandEncoder,
EncodingContext* encodingContext,
PassResourceUsageTracker usageTracker,
QuerySetBase* occlusionQuerySet,
uint32_t renderTargetWidth,
uint32_t renderTargetHeight);
@@ -51,6 +52,9 @@ namespace dawn_native {
void SetScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
void ExecuteBundles(uint32_t count, RenderBundleBase* const* renderBundles);
void BeginOcclusionQuery(uint32_t queryIndex);
void EndOcclusionQuery();
void WriteTimestamp(QuerySetBase* querySet, uint32_t queryIndex);
protected:
@@ -71,6 +75,11 @@ namespace dawn_native {
// query cannot be written twice in same render pass, so each render pass also need to have
// its own query availability map.
QueryAvailabilityMap mQueryAvailabilityMap;
// The resources for occlusion query
Ref<QuerySetBase> mOcclusionQuerySet;
uint32_t mCurrentOcclusionQueryIndex = 0;
bool mOcclusionQueryActive = false;
};
} // namespace dawn_native

View File

@@ -1482,6 +1482,14 @@ namespace dawn_native { namespace d3d12 {
break;
}
case Command::BeginOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
}
case Command::EndOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
}
case Command::WriteTimestamp: {
WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();

View File

@@ -1294,6 +1294,14 @@ namespace dawn_native { namespace metal {
break;
}
case Command::BeginOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
}
case Command::EndOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
}
case Command::WriteTimestamp: {
WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();
QuerySet* querySet = ToBackend(cmd->querySet.Get());

View File

@@ -1221,6 +1221,14 @@ namespace dawn_native { namespace opengl {
break;
}
case Command::BeginOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("BeginOcclusionQuery unimplemented.");
}
case Command::EndOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("EndOcclusionQuery unimplemented.");
}
case Command::WriteTimestamp:
return DAWN_UNIMPLEMENTED_ERROR("WriteTimestamp unimplemented");

View File

@@ -1222,6 +1222,14 @@ namespace dawn_native { namespace vulkan {
break;
}
case Command::BeginOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
}
case Command::EndOcclusionQuery: {
return DAWN_UNIMPLEMENTED_ERROR("Waiting for implementation.");
}
case Command::WriteTimestamp: {
WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();