[WebGPU backend] Add BackendWGPU

A Dawn WebGPU backend is an "intermediate" layer
that forwards WebGPU API calls to the wgpu* C API calls
to the underlying "real" backend. Having such a backend
can help us make the developer tool by enabling accessing
to internal states of dawn objects (inspect), serialize
the API calls relative states to disk files (capture)
and deserialize them later to help debug (replay)

This CL is the start of adding such a Dawn WebGPU backend.
It sets up the build config and adds the BackendWGPU.

Bug: 413053623
Change-Id: I4042378d042baa17a7a02649b64fdc6035fcf6ae
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/241814
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Shrek Shao <shrekshao@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b56fbb7..42d6ddd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,6 +77,7 @@
 set(ENABLE_D3D12 OFF)
 set(ENABLE_METAL OFF)
 set(ENABLE_NULL ON)
+set(ENABLE_WEBGPU_ON_WEBGPU OFF)
 set(ENABLE_OPENGLES OFF)
 set(ENABLE_DESKTOP_GL OFF)
 set(ENABLE_VULKAN OFF)
@@ -93,6 +94,7 @@
   set(BUILD_SAMPLES ON)
   set(BUILD_TESTS ON)
   set(ENABLE_NULL OFF)
+  set(ENABLE_WEBGPU_ON_WEBGPU OFF)
 elseif (WIN32)
   set(ENABLE_D3D11 ON)
   set(USE_WINDOWS_UI ON)
@@ -143,6 +145,7 @@
 option(DAWN_ENABLE_D3D12 "Enable compilation of the D3D12 backend" ${ENABLE_D3D12})
 option(DAWN_ENABLE_METAL "Enable compilation of the Metal backend" ${ENABLE_METAL})
 option(DAWN_ENABLE_NULL "Enable compilation of the Null backend" ${ENABLE_NULL})
+option(DAWN_ENABLE_WEBGPU_ON_WEBGPU "Enable compilation of the WebGPU backend" ${ENABLE_WEBGPU_ON_WEBGPU})
 option(DAWN_ENABLE_DESKTOP_GL "Enable compilation of the OpenGL backend" ${ENABLE_DESKTOP_GL})
 option(DAWN_ENABLE_OPENGLES "Enable compilation of the OpenGL ES backend" ${ENABLE_OPENGLES})
 option(DAWN_ENABLE_VULKAN "Enable compilation of the Vulkan backend" ${ENABLE_VULKAN})
@@ -400,6 +403,9 @@
 if (DAWN_ENABLE_NULL)
     target_compile_definitions(dawn_internal_config INTERFACE "DAWN_ENABLE_BACKEND_NULL")
 endif()
+if (DAWN_ENABLE_WEBGPU_ON_WEBGPU)
+    target_compile_definitions(dawn_internal_config INTERFACE "DAWN_ENABLE_BACKEND_WEBGPU")
+endif()
 if (DAWN_ENABLE_DESKTOP_GL)
     target_compile_definitions(dawn_internal_config INTERFACE "DAWN_ENABLE_BACKEND_DESKTOP_GL")
 endif()
diff --git a/include/dawn/native/WebGPUBackend.h b/include/dawn/native/WebGPUBackend.h
new file mode 100644
index 0000000..0bef6ad
--- /dev/null
+++ b/include/dawn/native/WebGPUBackend.h
@@ -0,0 +1,35 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef INCLUDE_DAWN_NATIVE_WEBGPUBACKEND_H_
+#define INCLUDE_DAWN_NATIVE_WEBGPUBACKEND_H_
+
+#include "dawn/native/DawnNative.h"
+
+namespace dawn::native::webgpu {}  // namespace dawn::native::webgpu
+
+#endif  // INCLUDE_DAWN_NATIVE_WEBGPUBACKEND_H_
diff --git a/scripts/dawn_features.gni b/scripts/dawn_features.gni
index 8f0bd1f..873d516 100644
--- a/scripts/dawn_features.gni
+++ b/scripts/dawn_features.gni
@@ -85,6 +85,10 @@
   # (required for unittests, obviously non-conformant)
   dawn_enable_null = true
 
+  # Enables the compilation of Dawn's WebGPU backend
+  # (used for debugging purpose, capture and replay)
+  dawn_enable_webgpu_on_webgpu = dawn_standalone
+
   # Enables the compilation of Dawn's OpenGL backend
   # (best effort, non-conformant)
   dawn_enable_desktop_gl = is_linux && !is_chromeos
diff --git a/src/dawn/common/BUILD.gn b/src/dawn/common/BUILD.gn
index 39decd6..a938ef0 100644
--- a/src/dawn/common/BUILD.gn
+++ b/src/dawn/common/BUILD.gn
@@ -84,6 +84,9 @@
   if (dawn_enable_null) {
     defines += [ "DAWN_ENABLE_BACKEND_NULL" ]
   }
+  if (dawn_enable_webgpu_on_webgpu) {
+    defines += [ "DAWN_ENABLE_BACKEND_WEBGPU" ]
+  }
   if (dawn_enable_opengl) {
     defines += [ "DAWN_ENABLE_BACKEND_OPENGL" ]
   }
diff --git a/src/dawn/native/BUILD.gn b/src/dawn/native/BUILD.gn
index 9164aa8..1f9a792 100644
--- a/src/dawn/native/BUILD.gn
+++ b/src/dawn/native/BUILD.gn
@@ -160,6 +160,7 @@
     "${dawn_root}/include/dawn/native/NullBackend.h",
     "${dawn_root}/include/dawn/native/OpenGLBackend.h",
     "${dawn_root}/include/dawn/native/VulkanBackend.h",
+    "${dawn_root}/include/dawn/native/WebGPUBackend.h",
   ]
 }
 
@@ -701,6 +702,14 @@
     ]
   }
 
+  if (dawn_enable_webgpu_on_webgpu) {
+    sources += [
+      "webgpu/BackendWGPU.cpp",
+      "webgpu/BackendWGPU.h",
+      "webgpu/Forward.h",
+    ]
+  }
+
   if ((dawn_enable_opengl || dawn_enable_vulkan) &&
       dawn_enable_spirv_validation) {
     sources += [
@@ -956,6 +965,9 @@
   if (dawn_enable_null) {
     sources += [ "null/NullBackend.cpp" ]
   }
+  if (dawn_enable_webgpu_on_webgpu) {
+    sources += [ "webgpu/WebGPUBackend.cpp" ]
+  }
   if (dawn_enable_opengl) {
     sources += [ "opengl/OpenGLBackend.cpp" ]
   }
diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt
index 291f351..9613aea 100644
--- a/src/dawn/native/CMakeLists.txt
+++ b/src/dawn/native/CMakeLists.txt
@@ -565,6 +565,19 @@
     )
 endif()
 
+if (DAWN_ENABLE_WEBGPU_ON_WEBGPU)
+    list(APPEND headers
+        "${DAWN_INCLUDE_DIR}/dawn/native/WebGPUBackend.h"
+    )
+    list(APPEND private_headers
+        "webgpu/BackendWGPU.h"
+        "webgpu/Forward.h"
+    )
+    list(APPEND sources
+        "webgpu/BackendWGPU.cpp"
+    )
+endif()
+
 if ((DAWN_ENABLE_OPENGL OR DAWN_ENABLE_VULKAN) AND DAWN_ENABLE_SPIRV_VALIDATION)
     list(APPEND private_headers
         "SpirvValidation.h"
@@ -800,6 +813,9 @@
 if (DAWN_ENABLE_NULL)
     list(APPEND dawn_component_srcs "null/NullBackend.cpp")
 endif()
+if (DAWN_ENABLE_WEBGPU_ON_WEBGPU)
+    list(APPEND dawn_component_srcs "webgpu/WebGPUBackend.cpp")
+endif()
 if (DAWN_ENABLE_OPENGL)
     list(APPEND dawn_component_srcs "opengl/OpenGLBackend.cpp")
 endif()
diff --git a/src/dawn/native/Instance.cpp b/src/dawn/native/Instance.cpp
index 0cc3dd3..b76362a 100644
--- a/src/dawn/native/Instance.cpp
+++ b/src/dawn/native/Instance.cpp
@@ -90,6 +90,11 @@
 BackendConnection* Connect(InstanceBase* instance);
 }
 #endif  // defined(DAWN_ENABLE_BACKEND_NULL)
+#if defined(DAWN_ENABLE_BACKEND_WEBGPU)
+namespace webgpu {
+BackendConnection* Connect(InstanceBase* instance);
+}
+#endif  // defined(DAWN_ENABLE_BACKEND_WEBGPU)
 #if defined(DAWN_ENABLE_BACKEND_OPENGL)
 namespace opengl {
 BackendConnection* Connect(InstanceBase* instance, wgpu::BackendType backendType);
@@ -398,6 +403,12 @@
             break;
 #endif  // defined(DAWN_ENABLE_BACKEND_NULL)
 
+#if defined(DAWN_ENABLE_BACKEND_WEBGPU)
+        case wgpu::BackendType::WebGPU:
+            Register(webgpu::Connect(this), wgpu::BackendType::WebGPU);
+            break;
+#endif  // defined(DAWN_ENABLE_BACKEND_WEBGPU)
+
 #if defined(DAWN_ENABLE_BACKEND_D3D11)
         case wgpu::BackendType::D3D11:
             Register(d3d11::Connect(this), wgpu::BackendType::D3D11);
diff --git a/src/dawn/native/webgpu/BackendWGPU.cpp b/src/dawn/native/webgpu/BackendWGPU.cpp
new file mode 100644
index 0000000..d0e7ec1
--- /dev/null
+++ b/src/dawn/native/webgpu/BackendWGPU.cpp
@@ -0,0 +1,54 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/native/webgpu/BackendWGPU.h"
+
+#include "dawn/dawn_proc_table.h"
+#include "dawn/native/Instance.h"
+
+namespace dawn::native::webgpu {
+
+Backend::Backend(InstanceBase* instance, wgpu::BackendType backendType)
+    : BackendConnection(instance, backendType) {
+    mDawnProcs = dawn::native::GetProcs();
+}
+
+std::vector<Ref<PhysicalDeviceBase>> Backend::DiscoverPhysicalDevices(
+    const UnpackedPtr<RequestAdapterOptions>& options) {
+    // TODO(crbug.com/413053623): placeholder implementation for now.
+    return {};
+}
+
+const DawnProcTable& Backend::GetFunctions() const {
+    return mDawnProcs;
+}
+
+BackendConnection* Connect(InstanceBase* instance) {
+    return new Backend(instance, wgpu::BackendType::WebGPU);
+}
+
+}  // namespace dawn::native::webgpu
diff --git a/src/dawn/native/webgpu/BackendWGPU.h b/src/dawn/native/webgpu/BackendWGPU.h
new file mode 100644
index 0000000..3a3a4dd
--- /dev/null
+++ b/src/dawn/native/webgpu/BackendWGPU.h
@@ -0,0 +1,57 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_NATIVE_WEBGPU_BACKENDWGPU_H_
+#define SRC_DAWN_NATIVE_WEBGPU_BACKENDWGPU_H_
+
+#include <vector>
+
+#include "dawn/native/BackendConnection.h"
+
+namespace dawn::native::webgpu {
+
+class PhysicalDevice;
+
+class Backend : public BackendConnection {
+  public:
+    Backend(InstanceBase* instance, wgpu::BackendType backendType);
+    ~Backend() override = default;
+
+    std::vector<Ref<PhysicalDeviceBase>> DiscoverPhysicalDevices(
+        const UnpackedPtr<RequestAdapterOptions>& options) override;
+
+    const DawnProcTable& GetFunctions() const;
+
+  private:
+    // The dawn proc table used as the underlying backend. It can be specified when creating the
+    // backend. This is different from the static global gProcTable.
+    DawnProcTable mDawnProcs;
+};
+
+}  // namespace dawn::native::webgpu
+
+#endif  // SRC_DAWN_NATIVE_WEBGPU_BACKENDWGPU_H_
diff --git a/src/dawn/native/webgpu/Forward.h b/src/dawn/native/webgpu/Forward.h
new file mode 100644
index 0000000..8e1b595
--- /dev/null
+++ b/src/dawn/native/webgpu/Forward.h
@@ -0,0 +1,79 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_NATIVE_WEBGPU_FORWARD_H_
+#define SRC_DAWN_NATIVE_WEBGPU_FORWARD_H_
+
+#include "dawn/native/ToBackend.h"
+
+namespace dawn::native::webgpu {
+
+class Backend;
+class BindGroup;
+class BindGroupLayout;
+class Buffer;
+class CommandBuffer;
+class ComputePipeline;
+class Device;
+class PhysicalDevice;
+class PipelineLayout;
+class QuerySet;
+class Queue;
+class RenderPipeline;
+class Sampler;
+class ShaderModule;
+class SwapChain;
+class Texture;
+class TextureView;
+
+struct WebGPUBackendTraits {
+    using BindGroupType = BindGroup;
+    using BindGroupLayoutType = BindGroupLayout;
+    using BufferType = Buffer;
+    using CommandBufferType = CommandBuffer;
+    using ComputePipelineType = ComputePipeline;
+    using DeviceType = Device;
+    using PhysicalDeviceType = PhysicalDevice;
+    using PipelineLayoutType = PipelineLayout;
+    using QuerySetType = QuerySet;
+    using QueueType = Queue;
+    using RenderPipelineType = RenderPipeline;
+    using SamplerType = Sampler;
+    using ShaderModuleType = ShaderModule;
+    using SwapChainType = SwapChain;
+    using TextureType = Texture;
+    using TextureViewType = TextureView;
+};
+
+template <typename T>
+auto ToBackend(T&& common) -> decltype(ToBackendBase<WebGPUBackendTraits>(common)) {
+    return ToBackendBase<WebGPUBackendTraits>(common);
+}
+
+}  // namespace dawn::native::webgpu
+
+#endif  // SRC_DAWN_NATIVE_WEBGPU_FORWARD_H_
diff --git a/src/dawn/native/webgpu/WebGPUBackend.cpp b/src/dawn/native/webgpu/WebGPUBackend.cpp
new file mode 100644
index 0000000..7615a71
--- /dev/null
+++ b/src/dawn/native/webgpu/WebGPUBackend.cpp
@@ -0,0 +1,33 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// WebGPUBackend.cpp: contains the definition of symbols exported by WebGPUBackend.h so that they
+// can be compiled twice: once export (shared library), once not exported (static library)
+
+#include "dawn/native/WebGPUBackend.h"
+
+namespace dawn::native::webgpu {}  // namespace dawn::native::webgpu
diff --git a/src/dawn/tests/AdapterTestConfig.cpp b/src/dawn/tests/AdapterTestConfig.cpp
index 22ecd3b..82df45f 100644
--- a/src/dawn/tests/AdapterTestConfig.cpp
+++ b/src/dawn/tests/AdapterTestConfig.cpp
@@ -67,6 +67,12 @@
                              forceDisabledWorkarounds);
 }
 
+BackendTestConfig WebGPUBackend(std::initializer_list<const char*> forceEnabledWorkarounds,
+                                std::initializer_list<const char*> forceDisabledWorkarounds) {
+    return BackendTestConfig(wgpu::BackendType::WebGPU, forceEnabledWorkarounds,
+                             forceDisabledWorkarounds);
+}
+
 BackendTestConfig OpenGLBackend(std::initializer_list<const char*> forceEnabledWorkarounds,
                                 std::initializer_list<const char*> forceDisabledWorkarounds) {
     return BackendTestConfig(wgpu::BackendType::OpenGL, forceEnabledWorkarounds,
@@ -115,6 +121,8 @@
             return "OpenGLES";
         case wgpu::BackendType::Vulkan:
             return "Vulkan";
+        case wgpu::BackendType::WebGPU:
+            return "WebGPU";
         case wgpu::BackendType::Undefined:
         default:
             DAWN_UNREACHABLE();
diff --git a/src/dawn/tests/AdapterTestConfig.h b/src/dawn/tests/AdapterTestConfig.h
index 3295815..6824edf 100644
--- a/src/dawn/tests/AdapterTestConfig.h
+++ b/src/dawn/tests/AdapterTestConfig.h
@@ -87,6 +87,9 @@
 BackendTestConfig NullBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                               std::initializer_list<const char*> forceDisabledWorkarounds = {});
 
+BackendTestConfig WebGPUBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
+                                std::initializer_list<const char*> forceDisabledWorkarounds = {});
+
 BackendTestConfig OpenGLBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                                 std::initializer_list<const char*> forceDisabledWorkarounds = {});
 
diff --git a/src/dawn/tests/DawnTest.cpp b/src/dawn/tests/DawnTest.cpp
index ac04e86..7295e49 100644
--- a/src/dawn/tests/DawnTest.cpp
+++ b/src/dawn/tests/DawnTest.cpp
@@ -848,6 +848,10 @@
     return mParam.adapterProperties.backendType == wgpu::BackendType::Null;
 }
 
+bool DawnTestBase::IsWebGPUOnWebGPU() const {
+    return mParam.adapterProperties.backendType == wgpu::BackendType::WebGPU;
+}
+
 bool DawnTestBase::IsOpenGL() const {
     return mParam.adapterProperties.backendType == wgpu::BackendType::OpenGL;
 }
diff --git a/src/dawn/tests/DawnTest.h b/src/dawn/tests/DawnTest.h
index 0f53976..9ad890b 100644
--- a/src/dawn/tests/DawnTest.h
+++ b/src/dawn/tests/DawnTest.h
@@ -253,6 +253,7 @@
     bool IsD3D12() const;
     bool IsMetal() const;
     bool IsNull() const;
+    bool IsWebGPUOnWebGPU() const;
     bool IsOpenGL() const;
     bool IsOpenGLES() const;
     bool IsVulkan() const;