dawn_native: Skip more validation if it is disabled.

Also cache the boolean for IsValidationEnabled in the
ProgrammablePassEncoder.

Bug: dawn:635
Change-Id: I5f095d003d28b84eacbc488a7f8f3c346c646187
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38521
Commit-Queue: Austin Eng <enga@chromium.org>
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Corentin Wallez 2021-01-23 00:07:46 +00:00 committed by Commit Bot service account
parent 0ac48eb9a4
commit f1f8394de0
5 changed files with 156 additions and 106 deletions

View File

@ -68,24 +68,28 @@ namespace dawn_native {
void ComputePassEncoder::DispatchIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset) { void ComputePassEncoder::DispatchIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); if (IsValidationEnabled()) {
DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));
// Indexed dispatches need a compute-shader based validation to check that the dispatch // Indexed dispatches need a compute-shader based validation to check that the
// sizes aren't too big. Disallow them as unsafe until the validation is implemented. // dispatch sizes aren't too big. Disallow them as unsafe until the validation is
if (GetDevice()->IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) { // implemented.
return DAWN_VALIDATION_ERROR( if (GetDevice()->IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) {
"DispatchIndirect is disallowed because it doesn't validate that the dispatch " return DAWN_VALIDATION_ERROR(
"size is valid yet."); "DispatchIndirect is disallowed because it doesn't validate that the "
} "dispatch "
"size is valid yet.");
}
if (indirectOffset % 4 != 0) { if (indirectOffset % 4 != 0) {
return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4"); return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4");
} }
if (indirectOffset >= indirectBuffer->GetSize() || if (indirectOffset >= indirectBuffer->GetSize() ||
indirectOffset + kDispatchIndirectSize > indirectBuffer->GetSize()) { indirectOffset + kDispatchIndirectSize > indirectBuffer->GetSize()) {
return DAWN_VALIDATION_ERROR("Indirect offset out of bounds"); return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
}
} }
DispatchIndirectCmd* dispatch = DispatchIndirectCmd* dispatch =
@ -101,7 +105,9 @@ namespace dawn_native {
void ComputePassEncoder::SetPipeline(ComputePipelineBase* pipeline) { void ComputePassEncoder::SetPipeline(ComputePipelineBase* pipeline) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(pipeline)); if (IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(pipeline));
}
SetComputePipelineCmd* cmd = SetComputePipelineCmd* cmd =
allocator->Allocate<SetComputePipelineCmd>(Command::SetComputePipeline); allocator->Allocate<SetComputePipelineCmd>(Command::SetComputePipeline);
@ -113,7 +119,7 @@ namespace dawn_native {
void ComputePassEncoder::WriteTimestamp(QuerySetBase* querySet, uint32_t queryIndex) { void ComputePassEncoder::WriteTimestamp(QuerySetBase* querySet, uint32_t queryIndex) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (GetDevice()->IsValidationEnabled()) { if (IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(querySet)); DAWN_TRY(GetDevice()->ValidateObject(querySet));
DAWN_TRY(ValidateTimestampQuery(querySet, queryIndex)); DAWN_TRY(ValidateTimestampQuery(querySet, queryIndex));
} }

View File

@ -84,14 +84,24 @@ namespace dawn_native {
ProgrammablePassEncoder::ProgrammablePassEncoder(DeviceBase* device, ProgrammablePassEncoder::ProgrammablePassEncoder(DeviceBase* device,
EncodingContext* encodingContext, EncodingContext* encodingContext,
PassType passType) PassType passType)
: ObjectBase(device), mEncodingContext(encodingContext), mUsageTracker(passType) { : ObjectBase(device),
mEncodingContext(encodingContext),
mUsageTracker(passType),
mValidationEnabled(device->IsValidationEnabled()) {
} }
ProgrammablePassEncoder::ProgrammablePassEncoder(DeviceBase* device, ProgrammablePassEncoder::ProgrammablePassEncoder(DeviceBase* device,
EncodingContext* encodingContext, EncodingContext* encodingContext,
ErrorTag errorTag, ErrorTag errorTag,
PassType passType) PassType passType)
: ObjectBase(device, errorTag), mEncodingContext(encodingContext), mUsageTracker(passType) { : ObjectBase(device, errorTag),
mEncodingContext(encodingContext),
mUsageTracker(passType),
mValidationEnabled(false) {
}
bool ProgrammablePassEncoder::IsValidationEnabled() const {
return mValidationEnabled;
} }
void ProgrammablePassEncoder::InsertDebugMarker(const char* groupLabel) { void ProgrammablePassEncoder::InsertDebugMarker(const char* groupLabel) {
@ -135,7 +145,7 @@ namespace dawn_native {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
BindGroupIndex groupIndex(groupIndexIn); BindGroupIndex groupIndex(groupIndexIn);
if (GetDevice()->IsValidationEnabled()) { if (IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(group)); DAWN_TRY(GetDevice()->ValidateObject(group));
if (groupIndex >= kMaxBindGroupsTyped) { if (groupIndex >= kMaxBindGroupsTyped) {

View File

@ -44,6 +44,8 @@ namespace dawn_native {
const uint32_t* dynamicOffsets = nullptr); const uint32_t* dynamicOffsets = nullptr);
protected: protected:
bool IsValidationEnabled() const;
// Construct an "error" programmable pass encoder. // Construct an "error" programmable pass encoder.
ProgrammablePassEncoder(DeviceBase* device, ProgrammablePassEncoder(DeviceBase* device,
EncodingContext* encodingContext, EncodingContext* encodingContext,
@ -52,6 +54,9 @@ namespace dawn_native {
EncodingContext* mEncodingContext = nullptr; EncodingContext* mEncodingContext = nullptr;
PassResourceUsageTracker mUsageTracker; PassResourceUsageTracker mUsageTracker;
private:
const bool mValidationEnabled;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -47,8 +47,10 @@ namespace dawn_native {
uint32_t firstVertex, uint32_t firstVertex,
uint32_t firstInstance) { uint32_t firstInstance) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (mDisableBaseInstance && firstInstance != 0) { if (IsValidationEnabled()) {
return DAWN_VALIDATION_ERROR("Non-zero first instance not supported"); if (mDisableBaseInstance && firstInstance != 0) {
return DAWN_VALIDATION_ERROR("Non-zero first instance not supported");
}
} }
DrawCmd* draw = allocator->Allocate<DrawCmd>(Command::Draw); DrawCmd* draw = allocator->Allocate<DrawCmd>(Command::Draw);
@ -67,11 +69,13 @@ namespace dawn_native {
int32_t baseVertex, int32_t baseVertex,
uint32_t firstInstance) { uint32_t firstInstance) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (mDisableBaseInstance && firstInstance != 0) { if (IsValidationEnabled()) {
return DAWN_VALIDATION_ERROR("Non-zero first instance not supported"); if (mDisableBaseInstance && firstInstance != 0) {
} return DAWN_VALIDATION_ERROR("Non-zero first instance not supported");
if (mDisableBaseVertex && baseVertex != 0) { }
return DAWN_VALIDATION_ERROR("Non-zero base vertex not supported"); if (mDisableBaseVertex && baseVertex != 0) {
return DAWN_VALIDATION_ERROR("Non-zero base vertex not supported");
}
} }
DrawIndexedCmd* draw = allocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed); DrawIndexedCmd* draw = allocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed);
@ -87,16 +91,18 @@ namespace dawn_native {
void RenderEncoderBase::DrawIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset) { void RenderEncoderBase::DrawIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); if (IsValidationEnabled()) {
DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));
if (indirectOffset % 4 != 0) { if (indirectOffset % 4 != 0) {
return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4"); return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4");
} }
if (indirectOffset >= indirectBuffer->GetSize() || if (indirectOffset >= indirectBuffer->GetSize() ||
indirectOffset + kDrawIndirectSize > indirectBuffer->GetSize()) { indirectOffset + kDrawIndirectSize > indirectBuffer->GetSize()) {
return DAWN_VALIDATION_ERROR("Indirect offset out of bounds"); return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
}
} }
DrawIndirectCmd* cmd = allocator->Allocate<DrawIndirectCmd>(Command::DrawIndirect); DrawIndirectCmd* cmd = allocator->Allocate<DrawIndirectCmd>(Command::DrawIndirect);
@ -112,25 +118,28 @@ namespace dawn_native {
void RenderEncoderBase::DrawIndexedIndirect(BufferBase* indirectBuffer, void RenderEncoderBase::DrawIndexedIndirect(BufferBase* indirectBuffer,
uint64_t indirectOffset) { uint64_t indirectOffset) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); if (IsValidationEnabled()) {
DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));
// Indexed indirect draws need a compute-shader based validation check that the range of // Indexed indirect draws need a compute-shader based validation check that the
// indices is contained inside the index buffer on Metal. Disallow them as unsafe until // range of indices is contained inside the index buffer on Metal. Disallow them as
// the validation is implemented. // unsafe until the validation is implemented.
if (GetDevice()->IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) { if (GetDevice()->IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"DrawIndexedIndirect is disallowed because it doesn't validate that the index " "DrawIndexedIndirect is disallowed because it doesn't validate that the "
"range is valid yet."); "index "
} "range is valid yet.");
}
if (indirectOffset % 4 != 0) { if (indirectOffset % 4 != 0) {
return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4"); return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4");
} }
if ((indirectOffset >= indirectBuffer->GetSize() || if ((indirectOffset >= indirectBuffer->GetSize() ||
indirectOffset + kDrawIndexedIndirectSize > indirectBuffer->GetSize())) { indirectOffset + kDrawIndexedIndirectSize > indirectBuffer->GetSize())) {
return DAWN_VALIDATION_ERROR("Indirect offset out of bounds"); return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
}
} }
DrawIndexedIndirectCmd* cmd = DrawIndexedIndirectCmd* cmd =
@ -146,7 +155,9 @@ namespace dawn_native {
void RenderEncoderBase::SetPipeline(RenderPipelineBase* pipeline) { void RenderEncoderBase::SetPipeline(RenderPipelineBase* pipeline) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(pipeline)); if (IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(pipeline));
}
SetRenderPipelineCmd* cmd = SetRenderPipelineCmd* cmd =
allocator->Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline); allocator->Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
@ -169,25 +180,31 @@ namespace dawn_native {
uint64_t offset, uint64_t offset,
uint64_t size) { uint64_t size) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(buffer)); if (IsValidationEnabled()) {
DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Index)); DAWN_TRY(GetDevice()->ValidateObject(buffer));
DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Index));
DAWN_TRY(ValidateIndexFormat(format)); DAWN_TRY(ValidateIndexFormat(format));
if (format == wgpu::IndexFormat::Undefined) { if (format == wgpu::IndexFormat::Undefined) {
return DAWN_VALIDATION_ERROR("Index format must be specified"); return DAWN_VALIDATION_ERROR("Index format must be specified");
} }
uint64_t bufferSize = buffer->GetSize(); uint64_t bufferSize = buffer->GetSize();
if (offset > bufferSize) { if (offset > bufferSize) {
return DAWN_VALIDATION_ERROR("Offset larger than the buffer size"); return DAWN_VALIDATION_ERROR("Offset larger than the buffer size");
} }
uint64_t remainingSize = bufferSize - offset; uint64_t remainingSize = bufferSize - offset;
if (size == 0) { if (size == 0) {
size = remainingSize; size = remainingSize;
} else {
if (size > remainingSize) {
return DAWN_VALIDATION_ERROR("Size + offset larger than the buffer size");
}
}
} else { } else {
if (size > remainingSize) { if (size == 0) {
return DAWN_VALIDATION_ERROR("Size + offset larger than the buffer size"); size = buffer->GetSize() - offset;
} }
} }
@ -209,24 +226,30 @@ namespace dawn_native {
uint64_t offset, uint64_t offset,
uint64_t size) { uint64_t size) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
DAWN_TRY(GetDevice()->ValidateObject(buffer)); if (IsValidationEnabled()) {
DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Vertex)); DAWN_TRY(GetDevice()->ValidateObject(buffer));
DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Vertex));
if (slot >= kMaxVertexBuffers) { if (slot >= kMaxVertexBuffers) {
return DAWN_VALIDATION_ERROR("Vertex buffer slot out of bounds"); return DAWN_VALIDATION_ERROR("Vertex buffer slot out of bounds");
} }
uint64_t bufferSize = buffer->GetSize(); uint64_t bufferSize = buffer->GetSize();
if (offset > bufferSize) { if (offset > bufferSize) {
return DAWN_VALIDATION_ERROR("Offset larger than the buffer size"); return DAWN_VALIDATION_ERROR("Offset larger than the buffer size");
} }
uint64_t remainingSize = bufferSize - offset; uint64_t remainingSize = bufferSize - offset;
if (size == 0) { if (size == 0) {
size = remainingSize; size = remainingSize;
} else {
if (size > remainingSize) {
return DAWN_VALIDATION_ERROR("Size + offset larger than the buffer size");
}
}
} else { } else {
if (size > remainingSize) { if (size == 0) {
return DAWN_VALIDATION_ERROR("Size + offset larger than the buffer size"); size = buffer->GetSize() - offset;
} }
} }

View File

@ -96,7 +96,7 @@ namespace dawn_native {
if (mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { if (mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
allocator->Allocate<EndRenderPassCmd>(Command::EndRenderPass); allocator->Allocate<EndRenderPassCmd>(Command::EndRenderPass);
if (GetDevice()->IsValidationEnabled()) { if (IsValidationEnabled()) {
if (mOcclusionQueryActive) { if (mOcclusionQueryActive) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"The occlusion query must be ended before endPass."); "The occlusion query must be ended before endPass.");
@ -135,24 +135,26 @@ namespace dawn_native {
float minDepth, float minDepth,
float maxDepth) { float maxDepth) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if ((isnan(x) || isnan(y) || isnan(width) || isnan(height) || isnan(minDepth) || if (IsValidationEnabled()) {
isnan(maxDepth))) { if ((isnan(x) || isnan(y) || isnan(width) || isnan(height) || isnan(minDepth) ||
return DAWN_VALIDATION_ERROR("NaN is not allowed."); isnan(maxDepth))) {
} return DAWN_VALIDATION_ERROR("NaN is not allowed.");
}
if (x < 0 || y < 0 || width < 0 || height < 0) { if (x < 0 || y < 0 || width < 0 || height < 0) {
return DAWN_VALIDATION_ERROR("X, Y, width and height must be non-negative."); return DAWN_VALIDATION_ERROR("X, Y, width and height must be non-negative.");
} }
if (x + width > mRenderTargetWidth || y + height > mRenderTargetHeight) { if (x + width > mRenderTargetWidth || y + height > mRenderTargetHeight) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"The viewport must be contained in the render targets"); "The viewport must be contained in the render targets");
} }
// Check for depths being in [0, 1] and min <= max in 3 checks instead of 5. // Check for depths being in [0, 1] and min <= max in 3 checks instead of 5.
if (minDepth < 0 || minDepth > maxDepth || maxDepth > 1) { if (minDepth < 0 || minDepth > maxDepth || maxDepth > 1) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"minDepth and maxDepth must be in [0, 1] and minDepth <= maxDepth."); "minDepth and maxDepth must be in [0, 1] and minDepth <= maxDepth.");
}
} }
SetViewportCmd* cmd = allocator->Allocate<SetViewportCmd>(Command::SetViewport); SetViewportCmd* cmd = allocator->Allocate<SetViewportCmd>(Command::SetViewport);
@ -172,10 +174,12 @@ namespace dawn_native {
uint32_t width, uint32_t width,
uint32_t height) { uint32_t height) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (width > mRenderTargetWidth || height > mRenderTargetHeight || if (IsValidationEnabled()) {
x > mRenderTargetWidth - width || y > mRenderTargetHeight - height) { if (width > mRenderTargetWidth || height > mRenderTargetHeight ||
return DAWN_VALIDATION_ERROR( x > mRenderTargetWidth - width || y > mRenderTargetHeight - height) {
"The scissor rect must be contained in the render targets"); return DAWN_VALIDATION_ERROR(
"The scissor rect must be contained in the render targets");
}
} }
SetScissorRectCmd* cmd = SetScissorRectCmd* cmd =
@ -191,8 +195,10 @@ namespace dawn_native {
void RenderPassEncoder::ExecuteBundles(uint32_t count, RenderBundleBase* const* renderBundles) { void RenderPassEncoder::ExecuteBundles(uint32_t count, RenderBundleBase* const* renderBundles) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
for (uint32_t i = 0; i < count; ++i) { if (IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(renderBundles[i])); for (uint32_t i = 0; i < count; ++i) {
DAWN_TRY(GetDevice()->ValidateObject(renderBundles[i]));
}
} }
ExecuteBundlesCmd* cmd = ExecuteBundlesCmd* cmd =
@ -219,7 +225,7 @@ namespace dawn_native {
void RenderPassEncoder::BeginOcclusionQuery(uint32_t queryIndex) { void RenderPassEncoder::BeginOcclusionQuery(uint32_t queryIndex) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (GetDevice()->IsValidationEnabled()) { if (IsValidationEnabled()) {
if (mOcclusionQuerySet.Get() == nullptr) { if (mOcclusionQuerySet.Get() == nullptr) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"The occlusionQuerySet in RenderPassDescriptor must be set."); "The occlusionQuerySet in RenderPassDescriptor must be set.");
@ -258,7 +264,7 @@ namespace dawn_native {
void RenderPassEncoder::EndOcclusionQuery() { void RenderPassEncoder::EndOcclusionQuery() {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (GetDevice()->IsValidationEnabled()) { if (IsValidationEnabled()) {
if (!mOcclusionQueryActive) { if (!mOcclusionQueryActive) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"EndOcclusionQuery cannot be called without corresponding " "EndOcclusionQuery cannot be called without corresponding "
@ -280,7 +286,7 @@ namespace dawn_native {
void RenderPassEncoder::WriteTimestamp(QuerySetBase* querySet, uint32_t queryIndex) { void RenderPassEncoder::WriteTimestamp(QuerySetBase* querySet, uint32_t queryIndex) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (GetDevice()->IsValidationEnabled()) { if (IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(querySet)); DAWN_TRY(GetDevice()->ValidateObject(querySet));
DAWN_TRY(ValidateTimestampQuery(querySet, queryIndex)); DAWN_TRY(ValidateTimestampQuery(querySet, queryIndex));
DAWN_TRY( DAWN_TRY(