[WebGPU backend] Skip draw indirect gpu validation
Add virtual NeedsIndirectDrawGPUValidation() and returns false
for WebGPUBackend to skip indirect draw gpu validation so that
indirect buffer won't change and the inner render bundle is created
at creation time of the upper render bundle.
Bug: 413053623
Change-Id: I92a14865d412fcd2b1a29cad8285e51d3da50114
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/273735
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Shrek Shao <shrekshao@google.com>
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index e39c772..e415026 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -2557,6 +2557,10 @@
return true;
}
+bool DeviceBase::NeedsIndirectDrawGPUValidation() const {
+ return true;
+}
+
uint64_t DeviceBase::GetBufferCopyOffsetAlignmentForDepthStencil() const {
// For depth-stencil texture, buffer offset must be a multiple of 4, which is required
// by WebGPU and Vulkan SPEC.
diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h
index 1f5b01e..2f1787d 100644
--- a/src/dawn/native/Device.h
+++ b/src/dawn/native/Device.h
@@ -409,6 +409,9 @@
wgpu::BufferUsage originalUsage,
size_t bufferSize) const;
+ // Whether the backend needs to validate the indirect buffer on GPU compute pass.
+ virtual bool NeedsIndirectDrawGPUValidation() const;
+
bool HasFeature(Feature feature) const;
const CombinedLimits& GetLimits() const;
diff --git a/src/dawn/native/ProgrammableEncoder.cpp b/src/dawn/native/ProgrammableEncoder.cpp
index 8d1e379..8833883 100644
--- a/src/dawn/native/ProgrammableEncoder.cpp
+++ b/src/dawn/native/ProgrammableEncoder.cpp
@@ -48,7 +48,8 @@
EncodingContext* encodingContext)
: ApiObjectBase(device, label),
mEncodingContext(encodingContext),
- mValidationEnabled(device->IsValidationEnabled()) {}
+ mValidationEnabled(device->IsValidationEnabled()),
+ mNeedsIndirectDrawGPUValidation(device->NeedsIndirectDrawGPUValidation()) {}
ProgrammableEncoder::ProgrammableEncoder(DeviceBase* device,
EncodingContext* encodingContext,
@@ -56,12 +57,17 @@
StringView label)
: ApiObjectBase(device, errorTag, label),
mEncodingContext(encodingContext),
- mValidationEnabled(device->IsValidationEnabled()) {}
+ mValidationEnabled(device->IsValidationEnabled()),
+ mNeedsIndirectDrawGPUValidation(device->NeedsIndirectDrawGPUValidation()) {}
bool ProgrammableEncoder::IsValidationEnabled() const {
return mValidationEnabled;
}
+bool ProgrammableEncoder::NeedsIndirectDrawGPUValidation() const {
+ return mNeedsIndirectDrawGPUValidation;
+}
+
MaybeError ProgrammableEncoder::ValidateProgrammableEncoderEnd() const {
DAWN_INVALID_IF(mDebugGroupStackSize != 0,
"PushDebugGroup called %u time(s) without a corresponding PopDebugGroup.",
diff --git a/src/dawn/native/ProgrammableEncoder.h b/src/dawn/native/ProgrammableEncoder.h
index f654a25..2950b84 100644
--- a/src/dawn/native/ProgrammableEncoder.h
+++ b/src/dawn/native/ProgrammableEncoder.h
@@ -55,6 +55,7 @@
protected:
bool IsValidationEnabled() const;
+ bool NeedsIndirectDrawGPUValidation() const;
MaybeError ValidateProgrammableEncoderEnd() const;
// Compute and render passes do different things on SetBindGroup. These are helper functions
@@ -83,6 +84,7 @@
private:
const bool mValidationEnabled;
+ const bool mNeedsIndirectDrawGPUValidation;
};
} // namespace dawn::native
diff --git a/src/dawn/native/RenderEncoderBase.cpp b/src/dawn/native/RenderEncoderBase.cpp
index 3148872..5c93a44 100644
--- a/src/dawn/native/RenderEncoderBase.cpp
+++ b/src/dawn/native/RenderEncoderBase.cpp
@@ -223,7 +223,8 @@
bool duplicateBaseVertexInstance =
GetDevice()->ShouldDuplicateParametersForDrawIndirect(
mCommandBufferState.GetRenderPipeline());
- if (IsValidationEnabled() || duplicateBaseVertexInstance) {
+ if (NeedsIndirectDrawGPUValidation() &&
+ (IsValidationEnabled() || duplicateBaseVertexInstance)) {
// Later, EncodeIndirectDrawValidationCommands will allocate a scratch storage
// buffer which will store the validated or duplicated indirect data. The buffer
// and offset will be updated to point to it.
@@ -285,8 +286,9 @@
mCommandBufferState.GetRenderPipeline());
bool applyIndexBufferOffsetToFirstIndex =
GetDevice()->ShouldApplyIndexBufferOffsetToFirstIndex();
- if (IsValidationEnabled() || duplicateBaseVertexInstance ||
- applyIndexBufferOffsetToFirstIndex) {
+ if (NeedsIndirectDrawGPUValidation() &&
+ (IsValidationEnabled() || duplicateBaseVertexInstance ||
+ applyIndexBufferOffsetToFirstIndex)) {
// Later, EncodeIndirectDrawValidationCommands will allocate a scratch storage
// buffer which will store the validated or duplicated indirect data. The buffer
// and offset will be updated to point to it.
@@ -397,8 +399,9 @@
mCommandBufferState.GetRenderPipeline()->GetPrimitiveTopology(),
duplicateBaseVertexInstance, cmd);
- if (GetDevice()->IsValidationEnabled() ||
- GetDevice()->MayRequireDuplicationOfIndirectParameters()) {
+ if (NeedsIndirectDrawGPUValidation() &&
+ (IsValidationEnabled() ||
+ GetDevice()->MayRequireDuplicationOfIndirectParameters())) {
// We only set usage as `kIndirectBufferForFrontendValidation` because
// `indirectBuffer` may not be used as an indirect buffer. The usage of
// `indirectBuffer` may be updated in `EncodeIndirectDrawValidationCommands()` in
@@ -506,8 +509,9 @@
mCommandBufferState.GetRenderPipeline()->GetPrimitiveTopology(),
duplicateBaseVertexInstance, cmd);
- if (GetDevice()->IsValidationEnabled() ||
- GetDevice()->MayRequireDuplicationOfIndirectParameters()) {
+ if (NeedsIndirectDrawGPUValidation() &&
+ (IsValidationEnabled() ||
+ GetDevice()->MayRequireDuplicationOfIndirectParameters())) {
// We only set usage as `kIndirectBufferForFrontendValidation` because
// `indirectBuffer` may not be used as an indirect buffer. The usage of
// `indirectBuffer` may be updated in `EncodeIndirectDrawValidationCommands()` in
diff --git a/src/dawn/native/webgpu/DeviceWGPU.cpp b/src/dawn/native/webgpu/DeviceWGPU.cpp
index 67b4630..21598b3f 100644
--- a/src/dawn/native/webgpu/DeviceWGPU.cpp
+++ b/src/dawn/native/webgpu/DeviceWGPU.cpp
@@ -302,6 +302,12 @@
return true;
}
+bool Device::NeedsIndirectDrawGPUValidation() const {
+ // WebGPU backend never actually dispatch compute pass to validate indirect draw cmds,
+ // since the inner backend will take care of it.
+ return false;
+}
+
void Device::StartCapture(CaptureStream& commandStream, CaptureStream& contentStream) {
MaybeError result = ToBackend(GetQueue())
->SetCaptureContext(std::unique_ptr<CaptureContext>(
diff --git a/src/dawn/native/webgpu/DeviceWGPU.h b/src/dawn/native/webgpu/DeviceWGPU.h
index fa9da0e..2f400b9 100644
--- a/src/dawn/native/webgpu/DeviceWGPU.h
+++ b/src/dawn/native/webgpu/DeviceWGPU.h
@@ -58,6 +58,8 @@
float GetTimestampPeriodInNS() const override;
+ bool NeedsIndirectDrawGPUValidation() const override;
+
WGPUInstance GetInnerInstance() const;
void StartCapture(CaptureStream& commandStream, CaptureStream& contentStream);
diff --git a/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp b/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp
index 613459b..2d1d24a 100644
--- a/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp
+++ b/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp
@@ -515,8 +515,6 @@
TEST_P(DrawIndexedIndirectTest, ValidateWithBundlesInSamePass) {
// TODO(crbug.com/dawn/789): Test is failing under SwANGLE on Windows only.
DAWN_SUPPRESS_TEST_IF(IsANGLE() && IsWindows());
- // TODO(crbug.com/413053623): Fix indirect buffer validation for WebGPU backend.
- DAWN_SUPPRESS_TEST_IF(IsWebGPUOnWebGPU());
// It doesn't make sense to test invalid inputs when validation is disabled.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));
@@ -568,8 +566,6 @@
TEST_P(DrawIndexedIndirectTest, ValidateWithBundlesInDifferentPasses) {
// TODO(crbug.com/dawn/789): Test is failing under SwANGLE on Windows only.
DAWN_SUPPRESS_TEST_IF(IsANGLE() && IsWindows());
- // TODO(crbug.com/413053623): Fix indirect buffer validation for WebGPU backend.
- DAWN_SUPPRESS_TEST_IF(IsWebGPUOnWebGPU());
// It doesn't make sense to test invalid inputs when validation is disabled.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));
@@ -638,9 +634,6 @@
// TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());
- // TODO(crbug.com/413053623): Fix indirect buffer validation for WebGPU backend.
- DAWN_SUPPRESS_TEST_IF(IsWebGPUOnWebGPU());
-
// It doesn't make sense to test invalid inputs when validation is disabled.
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));