Add maxStorage(Buffers/Textures)in(Fragment/Vertex)Stage

In compat mode these default to 0. In core they default
to the same value as maxStorage(Buffers/Textures)PerShaderStage.

The are not checked in core. In core they are always the same
as whatever was selected for maxStorage(Buffers/Textures)PerShaderStage.

Bug: 383157198,381214210
Fixed: 383157198,381214210
Change-Id: I6ab3d9f6be07c6488a944ef9d816917347ff19ee
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/218934
Auto-Submit: Gregg Tavares <gman@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 7b36f06..c225730 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -1808,7 +1808,11 @@
             {"name": "max compute workgroup size x", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max compute workgroup size y", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max compute workgroup size z", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
-            {"name": "max compute workgroups per dimension", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"}
+            {"name": "max compute workgroups per dimension", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
+            {"name": "max storage buffers in vertex stage", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
+            {"name": "max storage textures in vertex stage", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
+            {"name": "max storage buffers in fragment stage", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
+            {"name": "max storage textures in fragment stage", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"}
         ]
     },
     "adapter properties subgroups": {
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index 48f29e6..eb1089b 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -285,6 +285,59 @@
         outDescriptor->layout = layoutRef.Get();
     }
 
+    if (device->IsCompatibilityMode()) {
+        const auto& limits = device->GetLimits();
+
+        {
+            auto requestedLimit = outDescriptor->layout->GetNumStorageBufferBindingsInVertexStage();
+            auto maxStorageBuffersInVertexStage = limits.v1.maxStorageBuffersInVertexStage;
+            DAWN_INVALID_IF(
+                requestedLimit > maxStorageBuffersInVertexStage,
+                "number of storage buffers used in vertex stage (%u) exceeds "
+                "maxStorageBuffersInVertexStage (%u).%s",
+                requestedLimit, maxStorageBuffersInVertexStage,
+                DAWN_INCREASE_LIMIT_MESSAGE(device->GetAdapter(), maxStorageBuffersInVertexStage,
+                                            requestedLimit));
+        }
+        {
+            auto requestedLimit =
+                outDescriptor->layout->GetNumStorageTextureBindingsInVertexStage();
+            auto maxStorageTexturesInVertexStage = limits.v1.maxStorageTexturesInVertexStage;
+            DAWN_INVALID_IF(
+                requestedLimit > maxStorageTexturesInVertexStage,
+                "number of storage textures used in vertex stage (%u) exceeds "
+                "maxStorageTexturesInVertexStage (%u).%s",
+                requestedLimit, maxStorageTexturesInVertexStage,
+                DAWN_INCREASE_LIMIT_MESSAGE(device->GetAdapter(), maxStorageTexturesInVertexStage,
+                                            requestedLimit));
+        }
+        {
+            auto requestedLimit =
+                outDescriptor->layout->GetNumStorageBufferBindingsInFragmentStage();
+            auto maxStorageBuffersInFragmentStage = limits.v1.maxStorageBuffersInFragmentStage;
+            DAWN_INVALID_IF(
+                requestedLimit > maxStorageBuffersInFragmentStage,
+                "number of storage buffers used in fragment stage (%u) exceeds "
+                "maxStorageBuffersInFragmentStage (%u).%s",
+                requestedLimit, maxStorageBuffersInFragmentStage,
+                DAWN_INCREASE_LIMIT_MESSAGE(device->GetAdapter(), maxStorageBuffersInFragmentStage,
+                                            requestedLimit));
+        }
+        {
+            auto requestedLimit =
+                outDescriptor->layout->GetNumStorageTextureBindingsInFragmentStage();
+            auto maxStorageTexturesInFragmentStage = limits.v1.maxStorageTexturesInFragmentStage;
+
+            DAWN_INVALID_IF(
+                requestedLimit > maxStorageTexturesInFragmentStage,
+                "number of storage textures used in fragment stage (%u) exceeds "
+                "maxStorageTexturesInFragmentStage (%u).%s",
+                requestedLimit, maxStorageTexturesInFragmentStage,
+                DAWN_INCREASE_LIMIT_MESSAGE(device->GetAdapter(), maxStorageTexturesInFragmentStage,
+                                            requestedLimit));
+        }
+    }
+
     return layoutRef;
 }
 
@@ -469,6 +522,26 @@
         mMutex = nullptr;
     }
 
+    if (!IsCompatibilityMode()) {
+        // In core mode the maxStorageXXXInYYYStage are always set to maxStorageXXXPerShaderStage
+        // In compat they can vary but validation will fail if usage is >
+        // maxStorageXXXPerShaderStage In other words:
+        //   In compat, user requests 5 and 4 respectively so result:
+        //     device.limits.maxStorageBuffersInFragmentStage = 5;
+        //     device.limits.maxStorageBuffersPerShaderStage = 4;
+        //     It's ok to use 4 storage buffers in fragment stage but fails if 5 used.
+        //   In core, user requests 5 and 4 respectively so result:
+        //     device.limits.maxStorageBuffersInFragmentStage = 4;
+        //     device.limits.maxStorageBuffersPerShaderStage = 4;
+        //     It's ok to use 4 storage buffers in fragment stage but fails if 5 used.
+        //
+        // Note: these 4 limits are ignored in core validation.
+        mLimits.v1.maxStorageBuffersInFragmentStage = mLimits.v1.maxStorageBuffersPerShaderStage;
+        mLimits.v1.maxStorageTexturesInFragmentStage = mLimits.v1.maxStorageTexturesPerShaderStage;
+        mLimits.v1.maxStorageBuffersInVertexStage = mLimits.v1.maxStorageBuffersPerShaderStage;
+        mLimits.v1.maxStorageTexturesInVertexStage = mLimits.v1.maxStorageTexturesPerShaderStage;
+    }
+
     mAdapter->GetInstance()->AddDevice(this);
 
     return {};
diff --git a/src/dawn/native/Limits.cpp b/src/dawn/native/Limits.cpp
index f109bdc..0c19a43 100644
--- a/src/dawn/native/Limits.cpp
+++ b/src/dawn/native/Limits.cpp
@@ -72,6 +72,8 @@
     X(Maximum,            maxSampledTexturesPerShaderStage,        16,        16,         16) \
     X(Maximum,                   maxSamplersPerShaderStage,        16,        16,         16) \
     X(Maximum,            maxStorageTexturesPerShaderStage,         4,         4,          8) \
+    X(Maximum,           maxStorageTexturesInFragmentStage,         0,         4,          8) \
+    X(Maximum,             maxStorageTexturesInVertexStage,         0,         4,          8) \
     X(Maximum,             maxUniformBuffersPerShaderStage,        12,        12,         12)
 
 // Tiers for limits related to storage buffer bindings. Should probably be merged with
@@ -79,8 +81,10 @@
 // TODO(crbug.com/dawn/685): Define these better. For now, use two tiers where one
 // offers slightly better than default limits.
 //
-#define LIMITS_STORAGE_BUFFER_BINDINGS(X)                                                           \
-    X(Maximum,             maxStorageBuffersPerShaderStage,         4,         8,          10)
+#define LIMITS_STORAGE_BUFFER_BINDINGS(X)                                                      \
+    X(Maximum,             maxStorageBuffersPerShaderStage,         4,         8,          10) \
+    X(Maximum,             maxStorageBuffersInFragmentStage,        0,         8,          10) \
+    X(Maximum,             maxStorageBuffersInVertexStage,          0,         8,          10)
 
 // TODO(crbug.com/dawn/685):
 // These limits aren't really tiered and could probably be grouped better.
@@ -346,6 +350,14 @@
         std::min(limits->maxStorageBuffersPerShaderStage, kMaxStorageBuffersPerShaderStage);
     limits->maxStorageTexturesPerShaderStage =
         std::min(limits->maxStorageTexturesPerShaderStage, kMaxStorageTexturesPerShaderStage);
+    limits->maxStorageBuffersInVertexStage =
+        std::min(limits->maxStorageBuffersInVertexStage, kMaxStorageBuffersPerShaderStage);
+    limits->maxStorageTexturesInVertexStage =
+        std::min(limits->maxStorageTexturesInVertexStage, kMaxStorageTexturesPerShaderStage);
+    limits->maxStorageBuffersInFragmentStage =
+        std::min(limits->maxStorageBuffersInFragmentStage, kMaxStorageBuffersPerShaderStage);
+    limits->maxStorageTexturesInFragmentStage =
+        std::min(limits->maxStorageTexturesInFragmentStage, kMaxStorageTexturesPerShaderStage);
     limits->maxUniformBuffersPerShaderStage =
         std::min(limits->maxUniformBuffersPerShaderStage, kMaxUniformBuffersPerShaderStage);
 
diff --git a/src/dawn/native/PipelineLayout.cpp b/src/dawn/native/PipelineLayout.cpp
index 91a26e1..c914a3a 100644
--- a/src/dawn/native/PipelineLayout.cpp
+++ b/src/dawn/native/PipelineLayout.cpp
@@ -162,6 +162,23 @@
             mStorageAttachmentSlots[slot] = pls->storageAttachments[i].format;
         }
     }
+
+    BindingCounts bindingCounts = {};
+    for (uint32_t i = 0; i < descriptor->bindGroupLayoutCount; ++i) {
+        if (descriptor->bindGroupLayouts[i]) {
+            AccumulateBindingCounts(&bindingCounts, descriptor->bindGroupLayouts[i]
+                                                        ->GetInternalBindGroupLayout()
+                                                        ->GetBindingCountInfo());
+        }
+    }
+    mNumStorageBufferBindingsInVertexStage =
+        bindingCounts.perStage[SingleShaderStage::Vertex].storageBufferCount;
+    mNumStorageTextureBindingsInVertexStage =
+        bindingCounts.perStage[SingleShaderStage::Vertex].storageTextureCount;
+    mNumStorageBufferBindingsInFragmentStage =
+        bindingCounts.perStage[SingleShaderStage::Fragment].storageBufferCount;
+    mNumStorageTextureBindingsInFragmentStage =
+        bindingCounts.perStage[SingleShaderStage::Fragment].storageTextureCount;
 }
 
 PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device,
@@ -546,4 +563,20 @@
     return mImmediateDataRangeByteSize;
 }
 
+uint32_t PipelineLayoutBase::GetNumStorageBufferBindingsInVertexStage() const {
+    return mNumStorageBufferBindingsInVertexStage;
+}
+
+uint32_t PipelineLayoutBase::GetNumStorageTextureBindingsInVertexStage() const {
+    return mNumStorageTextureBindingsInVertexStage;
+}
+
+uint32_t PipelineLayoutBase::GetNumStorageBufferBindingsInFragmentStage() const {
+    return mNumStorageBufferBindingsInFragmentStage;
+}
+
+uint32_t PipelineLayoutBase::GetNumStorageTextureBindingsInFragmentStage() const {
+    return mNumStorageTextureBindingsInFragmentStage;
+}
+
 }  // namespace dawn::native
diff --git a/src/dawn/native/PipelineLayout.h b/src/dawn/native/PipelineLayout.h
index 9e75510..e742c76 100644
--- a/src/dawn/native/PipelineLayout.h
+++ b/src/dawn/native/PipelineLayout.h
@@ -95,6 +95,10 @@
     bool HasPixelLocalStorage() const;
     const std::vector<wgpu::TextureFormat>& GetStorageAttachmentSlots() const;
     bool HasAnyStorageAttachments() const;
+    uint32_t GetNumStorageBufferBindingsInVertexStage() const;
+    uint32_t GetNumStorageTextureBindingsInVertexStage() const;
+    uint32_t GetNumStorageBufferBindingsInFragmentStage() const;
+    uint32_t GetNumStorageTextureBindingsInFragmentStage() const;
 
     // Utility functions to compute inherited bind groups.
     // Returns the inherited bind groups as a mask.
@@ -120,6 +124,10 @@
     PerBindGroup<Ref<BindGroupLayoutBase>> mBindGroupLayouts;
     BindGroupMask mMask;
     bool mHasPLS = false;
+    uint32_t mNumStorageBufferBindingsInVertexStage = 0;
+    uint32_t mNumStorageTextureBindingsInVertexStage = 0;
+    uint32_t mNumStorageBufferBindingsInFragmentStage = 0;
+    uint32_t mNumStorageTextureBindingsInFragmentStage = 0;
     std::vector<wgpu::TextureFormat> mStorageAttachmentSlots;
     uint32_t mImmediateDataRangeByteSize = 0;
 };
diff --git a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
index c4d6fb9..67a5733 100644
--- a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
+++ b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
@@ -222,6 +222,10 @@
     // Allocate half of the UAVs to storage buffers, and half to storage textures.
     limits->v1.maxStorageTexturesPerShaderStage = maxUAVsPerStage / 2;
     limits->v1.maxStorageBuffersPerShaderStage = maxUAVsPerStage / 2;
+    limits->v1.maxStorageTexturesInFragmentStage = limits->v1.maxStorageTexturesPerShaderStage;
+    limits->v1.maxStorageBuffersInFragmentStage = limits->v1.maxStorageBuffersPerShaderStage;
+    limits->v1.maxStorageTexturesInVertexStage = limits->v1.maxStorageTexturesPerShaderStage;
+    limits->v1.maxStorageBuffersInVertexStage = limits->v1.maxStorageBuffersPerShaderStage;
     limits->v1.maxSampledTexturesPerShaderStage = D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT;
     limits->v1.maxSamplersPerShaderStage = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
     limits->v1.maxColorAttachments = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index 58789ae..2335340 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -279,6 +279,10 @@
     // Allocate half of the UAVs to storage buffers, and half to storage textures.
     limits->v1.maxStorageTexturesPerShaderStage = maxUAVsPerStage / 2;
     limits->v1.maxStorageBuffersPerShaderStage = maxUAVsPerStage - maxUAVsPerStage / 2;
+    limits->v1.maxStorageTexturesInFragmentStage = limits->v1.maxStorageTexturesPerShaderStage;
+    limits->v1.maxStorageBuffersInFragmentStage = limits->v1.maxStorageBuffersPerShaderStage;
+    limits->v1.maxStorageTexturesInVertexStage = limits->v1.maxStorageTexturesPerShaderStage;
+    limits->v1.maxStorageBuffersInVertexStage = limits->v1.maxStorageBuffersPerShaderStage;
     limits->v1.maxSampledTexturesPerShaderStage = maxSRVsPerStage;
     limits->v1.maxSamplersPerShaderStage = maxSamplersPerStage;
 
diff --git a/src/dawn/native/metal/PhysicalDeviceMTL.mm b/src/dawn/native/metal/PhysicalDeviceMTL.mm
index 8550549..0e96769 100644
--- a/src/dawn/native/metal/PhysicalDeviceMTL.mm
+++ b/src/dawn/native/metal/PhysicalDeviceMTL.mm
@@ -959,6 +959,11 @@
     limits->experimentalSubgroupLimits.minSubgroupSize = 4;
     limits->experimentalSubgroupLimits.maxSubgroupSize = 64;
 
+    limits->v1.maxStorageBuffersInFragmentStage = limits->v1.maxStorageBuffersPerShaderStage;
+    limits->v1.maxStorageTexturesInFragmentStage = limits->v1.maxStorageTexturesPerShaderStage;
+    limits->v1.maxStorageBuffersInVertexStage = limits->v1.maxStorageBuffersPerShaderStage;
+    limits->v1.maxStorageTexturesInVertexStage = limits->v1.maxStorageTexturesPerShaderStage;
+
     return {};
 }
 
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 8ee4e74..73b3bbc 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -320,7 +320,11 @@
     limits->v1.maxStorageBuffersPerShaderStage = Get(gl, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
     // TODO(crbug.com/dawn/1834): Note that OpenGLES allows an implementation to have zero vertex
     // image uniforms, so this isn't technically correct for vertex shaders.
-    limits->v1.maxStorageTexturesPerShaderStage = Get(gl, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
+    limits->v1.maxStorageTexturesPerShaderStage = Get(gl, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
+    limits->v1.maxStorageTexturesInFragmentStage = Get(gl, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
+    limits->v1.maxStorageBuffersInFragmentStage = Get(gl, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
+    limits->v1.maxStorageTexturesInVertexStage = Get(gl, GL_MAX_VERTEX_IMAGE_UNIFORMS);
+    limits->v1.maxStorageBuffersInVertexStage = Get(gl, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
 
     limits->v1.maxUniformBuffersPerShaderStage = Get(gl, GL_MAX_UNIFORM_BUFFER_BINDINGS);
     limits->v1.maxUniformBufferBindingSize = Get(gl, GL_MAX_UNIFORM_BLOCK_SIZE);
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 771eb30..972df71 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -562,6 +562,10 @@
             std::min(baseLimits.v1.maxStorageBuffersPerShaderStage + extraResources,
                      vkLimits.maxPerStageDescriptorStorageBuffers);
     }
+    limits->v1.maxStorageTexturesInFragmentStage = limits->v1.maxStorageTexturesPerShaderStage;
+    limits->v1.maxStorageBuffersInFragmentStage = limits->v1.maxStorageBuffersPerShaderStage;
+    limits->v1.maxStorageTexturesInVertexStage = limits->v1.maxStorageTexturesPerShaderStage;
+    limits->v1.maxStorageBuffersInVertexStage = limits->v1.maxStorageBuffersPerShaderStage;
 
     CHECK_AND_SET_V1_MIN_LIMIT(minUniformBufferOffsetAlignment, minUniformBufferOffsetAlignment);
     CHECK_AND_SET_V1_MIN_LIMIT(minStorageBufferOffsetAlignment, minStorageBufferOffsetAlignment);
diff --git a/src/dawn/node/binding/GPUAdapter.cpp b/src/dawn/node/binding/GPUAdapter.cpp
index 637c41f..b6bac8c 100644
--- a/src/dawn/node/binding/GPUAdapter.cpp
+++ b/src/dawn/node/binding/GPUAdapter.cpp
@@ -55,6 +55,10 @@
     X(maxDynamicStorageBuffersPerPipelineLayout) \
     X(maxSampledTexturesPerShaderStage)          \
     X(maxSamplersPerShaderStage)                 \
+    X(maxStorageBuffersInFragmentStage)          \
+    X(maxStorageTexturesInFragmentStage)         \
+    X(maxStorageBuffersInVertexStage)            \
+    X(maxStorageTexturesInVertexStage)           \
     X(maxStorageBuffersPerShaderStage)           \
     X(maxStorageTexturesPerShaderStage)          \
     X(maxUniformBuffersPerShaderStage)           \
diff --git a/src/dawn/node/binding/GPUSupportedLimits.cpp b/src/dawn/node/binding/GPUSupportedLimits.cpp
index aa7449c..caa4e6c 100644
--- a/src/dawn/node/binding/GPUSupportedLimits.cpp
+++ b/src/dawn/node/binding/GPUSupportedLimits.cpp
@@ -173,6 +173,30 @@
     return limits_.limits.maxComputeWorkgroupsPerDimension;
 }
 
+std::variant<uint32_t, interop::UndefinedType>
+GPUSupportedLimits::getMaxStorageBuffersInFragmentStage(Napi::Env) {
+    return std::variant<uint32_t, interop::UndefinedType>(
+        limits_.limits.maxStorageBuffersInFragmentStage);
+}
+
+std::variant<uint32_t, interop::UndefinedType>
+GPUSupportedLimits::getMaxStorageTexturesInFragmentStage(Napi::Env) {
+    return std::variant<uint32_t, interop::UndefinedType>(
+        limits_.limits.maxStorageTexturesInFragmentStage);
+}
+
+std::variant<uint32_t, interop::UndefinedType>
+GPUSupportedLimits::getMaxStorageBuffersInVertexStage(Napi::Env) {
+    return std::variant<uint32_t, interop::UndefinedType>(
+        limits_.limits.maxStorageBuffersInVertexStage);
+}
+
+std::variant<uint32_t, interop::UndefinedType>
+GPUSupportedLimits::getMaxStorageTexturesInVertexStage(Napi::Env) {
+    return std::variant<uint32_t, interop::UndefinedType>(
+        limits_.limits.maxStorageTexturesInVertexStage);
+}
+
 // TODO(crbug.com/354751907) Move to GPUAdapterInfo
 std::variant<uint32_t, interop::UndefinedType> GPUSupportedLimits::getMinSubgroupSize(Napi::Env) {
     if (subgroup_limits_.has_value()) {
diff --git a/src/dawn/node/binding/GPUSupportedLimits.h b/src/dawn/node/binding/GPUSupportedLimits.h
index f6c0201..0e8db81 100644
--- a/src/dawn/node/binding/GPUSupportedLimits.h
+++ b/src/dawn/node/binding/GPUSupportedLimits.h
@@ -73,6 +73,14 @@
     uint32_t getMaxComputeWorkgroupSizeY(Napi::Env) override;
     uint32_t getMaxComputeWorkgroupSizeZ(Napi::Env) override;
     uint32_t getMaxComputeWorkgroupsPerDimension(Napi::Env) override;
+    std::variant<uint32_t, interop::UndefinedType> getMaxStorageBuffersInFragmentStage(
+        Napi::Env) override;
+    std::variant<uint32_t, interop::UndefinedType> getMaxStorageTexturesInFragmentStage(
+        Napi::Env) override;
+    std::variant<uint32_t, interop::UndefinedType> getMaxStorageBuffersInVertexStage(
+        Napi::Env) override;
+    std::variant<uint32_t, interop::UndefinedType> getMaxStorageTexturesInVertexStage(
+        Napi::Env) override;
     // TODO(354751907) Move subgroup min and max sizes to AdapterInfo
     std::variant<uint32_t, interop::UndefinedType> getMinSubgroupSize(Napi::Env) override;
     std::variant<uint32_t, interop::UndefinedType> getMaxSubgroupSize(Napi::Env) override;
diff --git a/src/dawn/node/interop/DawnExtensions.idl b/src/dawn/node/interop/DawnExtensions.idl
index 71ddb15..2d178d4 100644
--- a/src/dawn/node/interop/DawnExtensions.idl
+++ b/src/dawn/node/interop/DawnExtensions.idl
@@ -79,4 +79,8 @@
 interface GPUSupportedLimits {
     readonly attribute (unsigned long or undefined) minSubgroupSize;
     readonly attribute (unsigned long or undefined) maxSubgroupSize;
+    readonly attribute (unsigned long or undefined) maxStorageBuffersInFragmentStage;
+    readonly attribute (unsigned long or undefined) maxStorageTexturesInFragmentStage;
+    readonly attribute (unsigned long or undefined) maxStorageBuffersInVertexStage;
+    readonly attribute (unsigned long or undefined) maxStorageTexturesInVertexStage;
 };
diff --git a/src/dawn/tests/end2end/BindGroupTests.cpp b/src/dawn/tests/end2end/BindGroupTests.cpp
index 89db8eb..ada6949 100644
--- a/src/dawn/tests/end2end/BindGroupTests.cpp
+++ b/src/dawn/tests/end2end/BindGroupTests.cpp
@@ -42,6 +42,16 @@
 
 class BindGroupTests : public DawnTest {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // TODO(crbug.com/383593270): Enable all the limits.
+        wgpu::RequiredLimits required = {};
+        required.limits.maxStorageBuffersInVertexStage =
+            supported.limits.maxStorageBuffersInVertexStage;
+        required.limits.maxStorageBuffersInFragmentStage =
+            supported.limits.maxStorageBuffersInFragmentStage;
+        return required;
+    }
+
     void SetUp() override {
         DawnTest::SetUp();
         mMinUniformBufferOffsetAlignment =
@@ -794,6 +804,8 @@
 
 // Test that bind groups set for one pipeline are still set when the pipeline changes.
 TEST_P(BindGroupTests, BindGroupsPersistAfterPipelineChange) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
     // Create a bind group layout which uses a single dynamic uniform buffer.
@@ -874,6 +886,7 @@
 TEST_P(BindGroupTests, DrawThenChangePipelineAndBindGroup) {
     // TODO(anglebug.com/3032): fix failure in ANGLE/D3D11
     DAWN_SUPPRESS_TEST_IF(IsANGLE() && IsWindows());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
@@ -1468,6 +1481,8 @@
 // This is a regression test for crbug.com/dawn/410 which tests that it can successfully compile and
 // execute the shader.
 TEST_P(BindGroupTests, ReadonlyStorage) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+
     utils::ComboRenderPipelineDescriptor pipelineDescriptor;
 
     pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
diff --git a/src/dawn/tests/end2end/BufferTests.cpp b/src/dawn/tests/end2end/BufferTests.cpp
index 1877348..5f79c9a 100644
--- a/src/dawn/tests/end2end/BufferTests.cpp
+++ b/src/dawn/tests/end2end/BufferTests.cpp
@@ -1211,6 +1211,14 @@
 
 class BufferMapExtendedUsagesTests : public DawnTest {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        wgpu::RequiredLimits required = {};
+        required.limits.maxStorageBuffersInVertexStage =
+            supported.limits.maxStorageBuffersInVertexStage;
+        return required;
+    }
+
+  protected:
     void SetUp() override {
         DawnTest::SetUp();
 
@@ -1617,6 +1625,8 @@
     const float kRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
     const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f};
 
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
+
     // Create buffer with initial red color data.
     wgpu::Buffer storageBuffer = CreateBufferFromData(
         &kRed, sizeof(kRed), wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::Storage);
@@ -1824,6 +1834,7 @@
 }
 
 TEST_P(BufferMapExtendedUsagesTests, MixMapWriteAndGPUWriteStorageBufferThenDraw) {
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
     MixMapWriteAndGPUWriteBufferThenDraw(ColorSrc::StorageBuffer);
 }
 
@@ -1834,6 +1845,8 @@
 // - draw using the storage buffer.
 TEST_P(BufferMapExtendedUsagesTests,
        MapWriteThenGPUWriteStorageBufferThenCopyFromAnotherBufferThenDraw) {
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
+
     const float kRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
     const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f};
     const float kFinalColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
diff --git a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
index 51d34cc..5057a55 100644
--- a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
@@ -58,6 +58,14 @@
 
 class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingTestParams> {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+
     enum class TestAspectAndSamplerType {
         DepthAsDepth,
         DepthAsFloat,
@@ -782,6 +790,7 @@
 TEST_P(DepthStencilSamplingTest, SampleExtraComponents) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
 
     wgpu::TextureFormat format = GetParam().mTextureFormat;
 
@@ -993,6 +1002,7 @@
 TEST_P(StencilSamplingTest, SampleStencilOnly) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
 
     wgpu::TextureFormat format = GetParam().mTextureFormat;
 
diff --git a/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp b/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp
index 30cf327..d738c99 100644
--- a/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp
+++ b/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp
@@ -43,9 +43,19 @@
 
 class DynamicBufferOffsetTests : public DawnTest {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // TODO(crbug.com/383593270): Enable all the limits.
+        wgpu::RequiredLimits required = {};
+        required.limits.maxStorageBuffersInFragmentStage =
+            supported.limits.maxStorageBuffersInFragmentStage;
+        return required;
+    }
+
     void SetUp() override {
         DawnTest::SetUp();
 
+        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+
         mMinUniformBufferOffsetAlignment =
             GetSupportedLimits().limits.minUniformBufferOffsetAlignment;
 
diff --git a/src/dawn/tests/end2end/ExternalTextureTests.cpp b/src/dawn/tests/end2end/ExternalTextureTests.cpp
index 30c81cc..6002ea1 100644
--- a/src/dawn/tests/end2end/ExternalTextureTests.cpp
+++ b/src/dawn/tests/end2end/ExternalTextureTests.cpp
@@ -160,7 +160,7 @@
                 outside : vec4f,
                 scale : f32,
             }
-            @group(0) @binding(0) var<storage> quad : QuadData;
+            @group(0) @binding(0) var<uniform> quad : QuadData;
             @fragment fn fs(@interpolate(perspective) @location(0) ndc : vec4f)
                                      -> @location(0) vec4f {
                 if abs(ndc.x) > quad.scale || abs(ndc.y) > quad.scale {
@@ -186,7 +186,7 @@
 
         // Make the storage buffer and the bind group containing it.
         wgpu::Buffer quadData = utils::CreateBufferFromData(this->device, &quad, sizeof(quad),
-                                                            wgpu::BufferUsage::Storage);
+                                                            wgpu::BufferUsage::Uniform);
         wgpu::BindGroup bg =
             utils::MakeBindGroup(this->device, quadPipeline.GetBindGroupLayout(0), {{0, quadData}});
 
@@ -671,6 +671,9 @@
 
     wgpu::Texture renderTexture = Create2DTexture(
         device, 2, 2, kFormat, wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);
+    wgpu::Texture dimensionTexture =
+        Create2DTexture(device, 2, 2, wgpu::TextureFormat::RG32Uint,
+                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);
 
     struct RotationExpectation {
         wgpu::ExternalTextureRotation rotation;
@@ -699,20 +702,23 @@
           utils::RGBA8::kBlack, utils::RGBA8::kRed, utils::RGBA8::kGreen}}};
 
     wgpu::ShaderModule loadModule = utils::CreateShaderModule(device, R"(
-        @group(0) @binding(0) var<storage, read_write> dimension : vec2u;
-        @group(0) @binding(1) var t : texture_external;
+        @group(0) @binding(0) var t : texture_external;
+
+        struct FragOut {
+          @location(0) color: vec4f,
+          @location(1) dimension: vec2u,
+        };
 
         @fragment fn main(@builtin(position) FragCoord : vec4f)
-                                 -> @location(0) vec4f {
-            dimension = textureDimensions(t);
-
-            var coords = textureDimensions(t) / 2 + vec2u(FragCoord.xy) - vec2(1, 1);
-            return textureLoad(t, coords);
+                                 -> FragOut {
+            let dimension = textureDimensions(t);
+            let coords = textureDimensions(t) / 2 + vec2u(FragCoord.xy) - vec2(1, 1);
+            return FragOut(textureLoad(t, coords), dimension);
         })");
 
     wgpu::BufferDescriptor dimensionBufferDesc;
-    dimensionBufferDesc.size = 8;
-    dimensionBufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
+    dimensionBufferDesc.size = 256;
+    dimensionBufferDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc;
     wgpu::Buffer dimensionBuffer = device.CreateBuffer(&dimensionBufferDesc);
 
     for (const RotationExpectation& exp : expectations) {
@@ -720,7 +726,9 @@
         utils::ComboRenderPipelineDescriptor descriptor;
         descriptor.vertex.module = vsModule;
         descriptor.cFragment.module = loadModule;
+        descriptor.cFragment.targetCount = 2;
         descriptor.cTargets[0].format = kFormat;
+        descriptor.cTargets[1].format = wgpu::TextureFormat::RG32Uint;
         wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
 
         // Import the external texture and make the bindgroup.
@@ -729,12 +737,13 @@
         externalDesc.mirrored = exp.mirrored;
 
         wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);
-        wgpu::BindGroup bindGroup = utils::MakeBindGroup(
-            device, pipeline.GetBindGroupLayout(0), {{1, externalTexture}, {0, dimensionBuffer}});
+        wgpu::BindGroup bindGroup =
+            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, externalTexture}});
 
         // Run the shader, which should sample from the external texture and draw a triangle into
         // the upper left corner of the render texture.
-        utils::ComboRenderPassDescriptor renderPass({renderTexture.CreateView()});
+        utils::ComboRenderPassDescriptor renderPass(
+            {renderTexture.CreateView(), dimensionTexture.CreateView()});
         wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
         wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
         pass.SetPipeline(pipeline);
@@ -742,6 +751,15 @@
         pass.Draw(6);
         pass.End();
 
+        {
+            wgpu::ImageCopyTexture imageCopyTexture =
+                utils::CreateImageCopyTexture(dimensionTexture, 0, {0, 0, 0});
+            wgpu::ImageCopyBuffer imageCopyBuffer =
+                utils::CreateImageCopyBuffer(dimensionBuffer, 0, 256, 1);
+            wgpu::Extent3D size = {1, 1, 1};
+            encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &size);
+        }
+
         wgpu::CommandBuffer commands = encoder.Finish();
         queue.Submit(1, &commands);
 
@@ -1047,18 +1065,24 @@
     // Create the test pipeline
     wgpu::ShaderModule blitAndOutputSize = utils::CreateShaderModule(this->device, R"(
         @group(0) @binding(0) var t : texture_external;
-        @group(0) @binding(1) var<storage, read_write> dimensions : vec2u;
+
+        struct FragOut {
+          @location(0) color: vec4f,
+          @location(1) dimension: vec2u,
+        };
 
         @fragment fn main(@builtin(position) FragCoord : vec4f)
-                                 -> @location(0) vec4f {
-            dimensions = textureDimensions(t);
-            return textureLoad(t, vec2u(FragCoord.xy));
+                                 -> FragOut {
+            let dimensions = textureDimensions(t);
+            return FragOut(textureLoad(t, vec2u(FragCoord.xy)), dimensions);
         })");
 
     utils::ComboRenderPipelineDescriptor descriptor;
     descriptor.vertex.module = vsModule;
     descriptor.cFragment.module = blitAndOutputSize;
+    descriptor.cFragment.targetCount = 2;
     descriptor.cTargets[0].format = kFormat;
+    descriptor.cTargets[1].format = wgpu::TextureFormat::RG32Uint;
     wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
 
     // The source texture will contain a quad and have a larger apparent size.
@@ -1076,18 +1100,23 @@
     wgpu::Texture renderTexture = Create2DTexture(
         device, externalDesc.apparentSize.width, externalDesc.apparentSize.height, kFormat,
         wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);
+    wgpu::Texture dimensionTexture =
+        Create2DTexture(device, externalDesc.apparentSize.width, externalDesc.apparentSize.height,
+                        wgpu::TextureFormat::RG32Uint,
+                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);
 
     // The buffer that will receive the result of `textureDimensions`
     wgpu::BufferDescriptor bufDesc;
-    bufDesc.size = 8;
-    bufDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
+    bufDesc.size = 256;
+    bufDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc;
     wgpu::Buffer dimensionBuffer = device.CreateBuffer(&bufDesc);
 
-    wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
-                                                     {{0, externalTexture}, {1, dimensionBuffer}});
+    wgpu::BindGroup bindGroup =
+        utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, externalTexture}});
 
     // Do the blit
-    utils::ComboRenderPassDescriptor renderPass({renderTexture.CreateView()});
+    utils::ComboRenderPassDescriptor renderPass(
+        {renderTexture.CreateView(), dimensionTexture.CreateView()});
     wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
     wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
     {
@@ -1097,6 +1126,15 @@
         pass.End();
     }
 
+    {
+        wgpu::ImageCopyTexture imageCopyTexture =
+            utils::CreateImageCopyTexture(dimensionTexture, 0, {0, 0, 0});
+        wgpu::ImageCopyBuffer imageCopyBuffer =
+            utils::CreateImageCopyBuffer(dimensionBuffer, 0, 256, 1);
+        wgpu::Extent3D size = {1, 1, 1};
+        encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &size);
+    }
+
     wgpu::CommandBuffer commands = encoder.Finish();
     queue.Submit(1, &commands);
 
@@ -1352,7 +1390,7 @@
             return vec4f(1);
         }
 
-        @group(0) @binding(1) var<storage, read_write> dimension : vec2u;
+        @group(0) @binding(1) var<uniform> dimension : vec2u;
         @group(0) @binding(0) var t : texture_external;
 
         @fragment fn main(@builtin(position) FragCoord : vec4f) -> @location(0) vec4f {
diff --git a/src/dawn/tests/end2end/FragDepthTests.cpp b/src/dawn/tests/end2end/FragDepthTests.cpp
index fb490b9..68ba894 100644
--- a/src/dawn/tests/end2end/FragDepthTests.cpp
+++ b/src/dawn/tests/end2end/FragDepthTests.cpp
@@ -99,14 +99,14 @@
             return vec4f(0.0, 0.0, 0.5, 1.0);
         }
 
-        @group(0) @binding(0) var<uniform> uniformDepth : f32;
-        @fragment fn fsUniform() -> @builtin(frag_depth) f32 {
-            return uniformDepth;
+        @group(0) @binding(0) var<uniform> uniformDepth1 : f32;
+        @fragment fn fsUniform1() -> @builtin(frag_depth) f32 {
+            return uniformDepth1;
         }
 
-        @group(0) @binding(0) var<storage, read> storageDepth : f32;
-        @fragment fn fsStorage() -> @builtin(frag_depth) f32 {
-            return storageDepth;
+        @group(0) @binding(0) var tex : texture_2d<f32>;
+        @fragment fn fsUniform2() -> @builtin(frag_depth) f32 {
+            return textureLoad(tex, vec2u(0), 0).r;
         }
     )");
 
@@ -115,7 +115,7 @@
     upDesc.vertex.module = module;
     upDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
     upDesc.cFragment.module = module;
-    upDesc.cFragment.entryPoint = "fsUniform";
+    upDesc.cFragment.entryPoint = "fsUniform1";
     upDesc.cFragment.targetCount = 0;
 
     wgpu::DepthStencilState* upDescDS = upDesc.EnableDepthStencil(kDepthFormat);
@@ -133,18 +133,29 @@
     spDesc.vertex.module = module;
     spDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
     spDesc.cFragment.module = module;
-    spDesc.cFragment.entryPoint = "fsStorage";
+    spDesc.cFragment.entryPoint = "fsUniform2";
     spDesc.cFragment.targetCount = 0;
 
     wgpu::DepthStencilState* spDescDS = spDesc.EnableDepthStencil(kDepthFormat);
     spDescDS->depthWriteEnabled = wgpu::OptionalBool::True;
     spDescDS->depthCompare = wgpu::CompareFunction::Always;
-    wgpu::RenderPipeline storagePipeline = device.CreateRenderPipeline(&spDesc);
+    wgpu::RenderPipeline texturePipeline = device.CreateRenderPipeline(&spDesc);
 
-    wgpu::Buffer storageBuffer =
-        utils::CreateBufferFromData<float>(device, wgpu::BufferUsage::Storage, {1.0});
-    wgpu::BindGroup storageBG =
-        utils::MakeBindGroup(device, storagePipeline.GetBindGroupLayout(0), {{0, storageBuffer}});
+    wgpu::TextureDescriptor texDesc = {};
+    texDesc.size = {1, 1, 1};
+    texDesc.format = wgpu::TextureFormat::R32Float;
+    texDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst;
+    wgpu::Texture texture = device.CreateTexture(&texDesc);
+
+    wgpu::ImageCopyTexture imageCopyTexture = utils::CreateImageCopyTexture(texture, 0, {0, 0, 0});
+    wgpu::TextureDataLayout textureDataLayout = utils::CreateTextureDataLayout(0, sizeof(float));
+    wgpu::Extent3D copyExtent = {1, 1, 1};
+
+    float one = 1.0;
+    queue.WriteTexture(&imageCopyTexture, &one, sizeof(float), &textureDataLayout, &copyExtent);
+
+    wgpu::BindGroup textureBG = utils::MakeBindGroup(device, texturePipeline.GetBindGroupLayout(0),
+                                                     {{0, texture.CreateView()}});
 
     // Create a depth-only render pass.
     wgpu::TextureDescriptor depthDesc;
@@ -168,8 +179,8 @@
     pass.Draw(1);
 
     // Writes 1.0 clamped to 0.5.
-    pass.SetPipeline(storagePipeline);
-    pass.SetBindGroup(0, storageBG);
+    pass.SetPipeline(texturePipeline);
+    pass.SetBindGroup(0, textureBG);
     pass.Draw(1);
 
     pass.End();
diff --git a/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp b/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp
index 782e402..bbfff47 100644
--- a/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp
+++ b/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp
@@ -40,6 +40,19 @@
 
 class GpuMemorySyncTests : public DawnTest {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+
+    void SetUp() override {
+        DawnTest::SetUp();
+        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    }
+
     wgpu::Buffer CreateBuffer() {
         wgpu::BufferDescriptor srcDesc;
         srcDesc.size = 4;
@@ -110,6 +123,8 @@
 // dependency chain. The test verifies that data in buffer among iterations in compute passes is
 // correctly synchronized.
 TEST_P(GpuMemorySyncTests, ComputePass) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+
     // Create pipeline, bind group, and buffer for compute pass.
     wgpu::Buffer buffer = CreateBuffer();
     auto [compute, bindGroup] = CreatePipelineAndBindGroupForCompute(buffer);
@@ -414,6 +429,20 @@
 
 class MultipleWriteThenMultipleReadTests : public DawnTest {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+
+    void SetUp() override {
+        DawnTest::SetUp();
+        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    }
+
+  protected:
     wgpu::Buffer CreateZeroedBuffer(uint64_t size, wgpu::BufferUsage usage) {
         wgpu::BufferDescriptor srcDesc;
         srcDesc.size = size;
diff --git a/src/dawn/tests/end2end/OpArrayLengthTests.cpp b/src/dawn/tests/end2end/OpArrayLengthTests.cpp
index b1569bd..18bddb6 100644
--- a/src/dawn/tests/end2end/OpArrayLengthTests.cpp
+++ b/src/dawn/tests/end2end/OpArrayLengthTests.cpp
@@ -37,6 +37,15 @@
 
 class OpArrayLengthTest : public DawnTest {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        // maxStorageBuffersInVertexStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+
     void SetUp() override {
         DawnTest::SetUp();
 
@@ -52,21 +61,6 @@
         bufferDesc.size = 512 + 256;
         mStorageBuffer512 = device.CreateBuffer(&bufferDesc);
 
-        // Put them all in a bind group for tests to bind them easily.
-        wgpu::ShaderStage kAllStages =
-            wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Compute;
-        mBindGroupLayout = utils::MakeBindGroupLayout(
-            device, {{0, kAllStages, wgpu::BufferBindingType::ReadOnlyStorage},
-                     {1, kAllStages, wgpu::BufferBindingType::ReadOnlyStorage},
-                     {2, kAllStages, wgpu::BufferBindingType::ReadOnlyStorage}});
-
-        mBindGroup = utils::MakeBindGroup(device, mBindGroupLayout,
-                                          {
-                                              {0, mStorageBuffer4, 0, 4},
-                                              {1, mStorageBuffer256, 0, wgpu::kWholeSize},
-                                              {2, mStorageBuffer512, 256, wgpu::kWholeSize},
-                                          });
-
         // Common shader code to use these buffers in shaders, assuming they are in bindgroup index
         // 0.
         mShaderInterface = R"(
@@ -98,12 +92,27 @@
         mExpectedLengths = {1, 64, 56};
     }
 
+    wgpu::BindGroupLayout MakeBindGroupLayout(wgpu::ShaderStage stages) {
+        // Put them all in a bind group for tests to bind them easily.
+        return utils::MakeBindGroupLayout(device,
+                                          {{0, stages, wgpu::BufferBindingType::ReadOnlyStorage},
+                                           {1, stages, wgpu::BufferBindingType::ReadOnlyStorage},
+                                           {2, stages, wgpu::BufferBindingType::ReadOnlyStorage}});
+    }
+
+    wgpu::BindGroup MakeBindGroup(wgpu::BindGroupLayout bindGroupLayout) {
+        return utils::MakeBindGroup(device, bindGroupLayout,
+                                    {
+                                        {0, mStorageBuffer4, 0, 4},
+                                        {1, mStorageBuffer256, 0, wgpu::kWholeSize},
+                                        {2, mStorageBuffer512, 256, wgpu::kWholeSize},
+                                    });
+    }
+
     wgpu::Buffer mStorageBuffer4;
     wgpu::Buffer mStorageBuffer256;
     wgpu::Buffer mStorageBuffer512;
 
-    wgpu::BindGroupLayout mBindGroupLayout;
-    wgpu::BindGroup mBindGroup;
     std::string mShaderInterface;
     std::array<uint32_t, 3> mExpectedLengths;
 };
@@ -131,7 +140,8 @@
         utils::MakeBindGroup(device, resultLayout, {{0, resultBuffer, 0, wgpu::kWholeSize}});
 
     // Create the compute pipeline that stores the length()s in the result buffer.
-    wgpu::BindGroupLayout bgls[] = {mBindGroupLayout, resultLayout};
+    wgpu::BindGroupLayout bindGroupLayout = MakeBindGroupLayout(wgpu::ShaderStage::Compute);
+    wgpu::BindGroupLayout bgls[] = {bindGroupLayout, resultLayout};
     wgpu::PipelineLayoutDescriptor plDesc;
     plDesc.bindGroupLayoutCount = 2;
     plDesc.bindGroupLayouts = bgls;
@@ -152,12 +162,13 @@
         })")
                                                                         .c_str());
     wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDesc);
+    wgpu::BindGroup bindGroup = MakeBindGroup(bindGroupLayout);
 
     // Run a single instance of the compute shader
     wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
     wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
     pass.SetPipeline(pipeline);
-    pass.SetBindGroup(0, mBindGroup);
+    pass.SetBindGroup(0, bindGroup);
     pass.SetBindGroup(1, resultBindGroup);
     pass.DispatchWorkgroups(1);
     pass.End();
@@ -178,6 +189,8 @@
     // (spurious but harmless) offset=64 that Tint/GLSL produces.
     DAWN_SUPPRESS_TEST_IF(IsIntel() && (IsOpenGL() || IsOpenGLES()));
 
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 3);
+
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
 
     // Create the pipeline that computes the length of the buffers and writes it to the only render
@@ -198,20 +211,24 @@
         })")
                                                                         .c_str());
 
+    wgpu::BindGroupLayout bindGroupLayout = MakeBindGroupLayout(wgpu::ShaderStage::Fragment);
+
     utils::ComboRenderPipelineDescriptor descriptor;
     descriptor.vertex.module = vsModule;
     descriptor.cFragment.module = fsModule;
     descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
     descriptor.cTargets[0].format = renderPass.colorFormat;
-    descriptor.layout = utils::MakeBasicPipelineLayout(device, &mBindGroupLayout);
+    descriptor.layout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
     wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
 
+    wgpu::BindGroup bindGroup = MakeBindGroup(bindGroupLayout);
+
     // "Draw" the lengths to the texture.
     wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
     {
         wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
         pass.SetPipeline(pipeline);
-        pass.SetBindGroup(0, mBindGroup);
+        pass.SetBindGroup(0, bindGroup);
         pass.Draw(1);
         pass.End();
     }
@@ -237,6 +254,8 @@
     // (spurious but harmless) offset=64 that Tint/GLSL produces.
     DAWN_SUPPRESS_TEST_IF(IsIntel() && IsOpenGL());
 
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 3);
+
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
 
     // Create the pipeline that computes the length of the buffers and writes it to the only render
@@ -265,20 +284,24 @@
             return color;
         })");
 
+    wgpu::BindGroupLayout bindGroupLayout = MakeBindGroupLayout(wgpu::ShaderStage::Vertex);
+
     utils::ComboRenderPipelineDescriptor descriptor;
     descriptor.vertex.module = vsModule;
     descriptor.cFragment.module = fsModule;
     descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
     descriptor.cTargets[0].format = renderPass.colorFormat;
-    descriptor.layout = utils::MakeBasicPipelineLayout(device, &mBindGroupLayout);
+    descriptor.layout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
     wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
 
+    wgpu::BindGroup bindGroup = MakeBindGroup(bindGroupLayout);
+
     // "Draw" the lengths to the texture.
     wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
     {
         wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
         pass.SetPipeline(pipeline);
-        pass.SetBindGroup(0, mBindGroup);
+        pass.SetBindGroup(0, bindGroup);
         pass.Draw(1);
         pass.End();
     }
diff --git a/src/dawn/tests/end2end/PipelineCachingTests.cpp b/src/dawn/tests/end2end/PipelineCachingTests.cpp
index 3b7f12f..5c793bb 100644
--- a/src/dawn/tests/end2end/PipelineCachingTests.cpp
+++ b/src/dawn/tests/end2end/PipelineCachingTests.cpp
@@ -128,7 +128,16 @@
     NiceMock<CachingInterfaceMock> mMockCache;
 };
 
-class SinglePipelineCachingTests : public PipelineCachingTests {};
+class SinglePipelineCachingTests : public PipelineCachingTests {
+  protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+};
 
 // Tests that pipeline creation works fine even if the cache is disabled.
 // Note: This tests needs to use more than 1 device since the frontend cache on each device
@@ -535,6 +544,8 @@
 // cached backends currently remap shader bindings based on the layout. It can be split
 // per-backend as needed.
 TEST_P(SinglePipelineCachingTests, RenderPipelineBlobCacheLayout) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+
     // First time should create and write out to the cache.
     {
         wgpu::Device device = CreateDevice();
diff --git a/src/dawn/tests/end2end/PixelLocalStorageTests.cpp b/src/dawn/tests/end2end/PixelLocalStorageTests.cpp
index b205986..d56c652 100644
--- a/src/dawn/tests/end2end/PixelLocalStorageTests.cpp
+++ b/src/dawn/tests/end2end/PixelLocalStorageTests.cpp
@@ -36,12 +36,21 @@
 
 class PixelLocalStorageTests : public DawnTest {
   protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        wgpu::RequiredLimits required = {};
+        required.limits.maxStorageBuffersInFragmentStage =
+            supported.limits.maxStorageBuffersInFragmentStage;
+        return required;
+    }
+
     void SetUp() override {
         DawnTest::SetUp();
         DAWN_TEST_UNSUPPORTED_IF(
             !device.HasFeature(wgpu::FeatureName::PixelLocalStorageCoherent) &&
             !device.HasFeature(wgpu::FeatureName::PixelLocalStorageNonCoherent));
 
+        DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+
         supportsCoherent = device.HasFeature(wgpu::FeatureName::PixelLocalStorageCoherent);
     }
 
diff --git a/src/dawn/tests/end2end/ShaderTests.cpp b/src/dawn/tests/end2end/ShaderTests.cpp
index a5309c0..60bfae4 100644
--- a/src/dawn/tests/end2end/ShaderTests.cpp
+++ b/src/dawn/tests/end2end/ShaderTests.cpp
@@ -37,6 +37,18 @@
 namespace {
 
 class ShaderTests : public DawnTest {
+  protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        // maxStorageTexturesInFragmentStage
+        // maxStorageBuffersInVertexStage
+        // maxStorageTexturesInVertexStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+
   public:
     wgpu::Buffer CreateBuffer(const std::vector<uint32_t>& data,
                               wgpu::BufferUsage usage = wgpu::BufferUsage::Storage |
@@ -1832,6 +1844,8 @@
 TEST_P(ShaderTests, StorageAcrossStages) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 4);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 3);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         @group(2) @binding(2) var<storage> u0_2: f32;
@@ -1872,6 +1886,8 @@
 TEST_P(ShaderTests, StorageAcrossStagesStruct) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 2);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         struct block {
@@ -1907,6 +1923,8 @@
 TEST_P(ShaderTests, StorageAcrossStagesSeparateModules) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 4);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 3);
 
     wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
         @group(2) @binding(2) var<storage> u0_2: f32;
@@ -1946,6 +1964,8 @@
 TEST_P(ShaderTests, StorageAcrossStagesSeparateModuleMismatch) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 2);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         @group(0) @binding(0) var<storage> tint_symbol_ubo_0: f32;
@@ -1974,6 +1994,8 @@
 TEST_P(ShaderTests, StorageAcrossStagesSameBindingPointCollide) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         struct X { x : vec4f }
@@ -2005,6 +2027,8 @@
 TEST_P(ShaderTests, StorageAcrossStagesSameBindingPointCollideMixedStructDef) {
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         struct X { x : vec4f }
diff --git a/src/dawn/tests/end2end/StorageTextureTests.cpp b/src/dawn/tests/end2end/StorageTextureTests.cpp
index cd68786..bebb2d2 100644
--- a/src/dawn/tests/end2end/StorageTextureTests.cpp
+++ b/src/dawn/tests/end2end/StorageTextureTests.cpp
@@ -41,6 +41,18 @@
 namespace {
 
 class StorageTextureTests : public DawnTest {
+  protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        // maxStorageTexturesInFragmentStage
+        // maxStorageBuffersInVertexStage
+        // maxStorageTexturesInVertexStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+
   public:
     static void FillExpectedData(void* pixelValuePtr,
                                  wgpu::TextureFormat format,
@@ -725,6 +737,8 @@
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());
 
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+
     for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
         if (!utils::TextureFormatSupportsStorageTexture(format, device, IsCompatibilityMode())) {
             continue;
@@ -1063,6 +1077,8 @@
 // Verify that the texture is correctly cleared to 0 before its first usage as a write-only storage
 // storage texture in a render pass.
 TEST_P(StorageTextureZeroInitTests, WriteonlyStorageTextureClearsToZeroInRenderPass) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+
     // Prepare the write-only storage texture.
     wgpu::Texture writeonlyStorageTexture = CreateTexture(
         wgpu::TextureFormat::R32Uint,
@@ -1146,6 +1162,8 @@
 
 // Verify read-write storage texture can work correctly in fragment shaders.
 TEST_P(ReadWriteStorageTextureTests, ReadWriteStorageTextureInFragmentShader) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+
     std::array<uint32_t, kWidth * kHeight> inputData;
     std::array<uint32_t, kWidth * kHeight> expectedData;
     for (size_t i = 0; i < inputData.size(); ++i) {
@@ -1267,6 +1285,8 @@
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
 
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageTexturesInVertexStage < 1);
+
     constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Uint;
     const std::vector<uint8_t> kInitialTextureData = GetExpectedData(kStorageTextureFormat);
     wgpu::Texture readonlyStorageTexture = CreateTextureWithTestData(
@@ -1313,6 +1333,8 @@
 
 // Verify read-only storage texture can work correctly in fragment shaders.
 TEST_P(ReadWriteStorageTextureTests, ReadOnlyStorageTextureInFragmentShader) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+
     constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Uint;
     const std::vector<uint8_t> kInitialTextureData = GetExpectedData(kStorageTextureFormat);
     wgpu::Texture readonlyStorageTexture = CreateTextureWithTestData(
diff --git a/src/dawn/tests/end2end/SurfaceTests.cpp b/src/dawn/tests/end2end/SurfaceTests.cpp
index db61806..9451ce6 100644
--- a/src/dawn/tests/end2end/SurfaceTests.cpp
+++ b/src/dawn/tests/end2end/SurfaceTests.cpp
@@ -46,6 +46,15 @@
 };
 
 class SurfaceTests : public DawnTest {
+  protected:
+    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+        // Just copy all the limits, though all we really care about is
+        // maxStorageBuffersInFragmentStage
+        wgpu::RequiredLimits required = {};
+        required.limits = supported.limits;
+        return required;
+    }
+
   public:
     void SetUp() override {
         DawnTest::SetUp();
@@ -616,6 +625,7 @@
 
 // Test using the surface as a storage texture when supported.
 TEST_P(SurfaceTests, Storage) {
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
     wgpu::Surface surface = CreateTestSurface();
     wgpu::SurfaceCapabilities caps;
     surface.GetCapabilities(adapter, &caps);
diff --git a/src/dawn/tests/unittests/native/LimitsTests.cpp b/src/dawn/tests/unittests/native/LimitsTests.cpp
index 24d720c..8856125 100644
--- a/src/dawn/tests/unittests/native/LimitsTests.cpp
+++ b/src/dawn/tests/unittests/native/LimitsTests.cpp
@@ -64,6 +64,10 @@
     Limits reified = ReifyDefaultLimits(limits, wgpu::FeatureLevel::Core);
     EXPECT_EQ(reified.maxComputeWorkgroupStorageSize, 16384u);
     EXPECT_EQ(reified.maxStorageBufferBindingSize, 134217728ul);
+    EXPECT_EQ(reified.maxStorageBuffersInFragmentStage, 8u);
+    EXPECT_EQ(reified.maxStorageTexturesInFragmentStage, 4u);
+    EXPECT_EQ(reified.maxStorageBuffersInVertexStage, 8u);
+    EXPECT_EQ(reified.maxStorageTexturesInVertexStage, 4u);
 }
 
 // Test |ReifyDefaultLimits| populates the default for wgpu::FeatureLevel::Compatibility
@@ -76,6 +80,10 @@
     Limits reified = ReifyDefaultLimits(limits, wgpu::FeatureLevel::Compatibility);
     EXPECT_EQ(reified.maxTextureDimension1D, 4096u);
     EXPECT_EQ(reified.maxStorageBufferBindingSize, 134217728ul);
+    EXPECT_EQ(reified.maxStorageBuffersInFragmentStage, 0u);
+    EXPECT_EQ(reified.maxStorageTexturesInFragmentStage, 0u);
+    EXPECT_EQ(reified.maxStorageBuffersInVertexStage, 0u);
+    EXPECT_EQ(reified.maxStorageTexturesInVertexStage, 0u);
 }
 
 // Test |ReifyDefaultLimits| clamps to the default if
diff --git a/webgpu-cts/compat-expectations.txt b/webgpu-cts/compat-expectations.txt
index 46b7358..96849bc 100644
--- a/webgpu-cts/compat-expectations.txt
+++ b/webgpu-cts/compat-expectations.txt
@@ -8621,6 +8621,370 @@
 crbug.com/42251283 [ android arm ] webgpu:shader,execution,expression,call,builtin,dpdyCoarse:f32:vectorize=3;non_uniform_discard=true [ Failure ]
 crbug.com/42251283 [ android arm ] webgpu:shader,execution,expression,call,builtin,dpdyCoarse:f32:vectorize=4;non_uniform_discard=true [ Failure ]
 
+# temp suppressions for 0 storage buffers / storage textures in vertex and fragment shaders
+crbug.com/381214210 webgpu:api,operation,memory_sync,* [ Skip ]
+crbug.com/381214210 webgpu:api,operation,rendering,draw:* [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_before_pipeline:encoderType="render%20bundle" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_before_pipeline:encoderType="render%20pass" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_indices:encoderType="render%20bundle" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_indices:encoderType="render%20pass" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_multiple_sets:encoderType="render%20bundle" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_multiple_sets:encoderType="render%20pass" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_order:encoderType="render%20bundle" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:bind_group_order:encoderType="render%20pass" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:compatible_pipelines:encoderType="render%20bundle" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:compatible_pipelines:encoderType="render%20pass" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:one_bind_group_multiple_slots:encoderType="render%20bundle" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,command_buffer,programmable,state_tracking:one_bind_group_multiple_slots:encoderType="render%20pass" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,memory_sync,buffer,multiple_buffers:multiple_pairs_of_draws_in_one_render_bundle: [ Skip ]
+crbug.com/381214210 webgpu:api,operation,memory_sync,buffer,multiple_buffers:multiple_pairs_of_draws_in_one_render_pass: [ Skip ]
+crbug.com/381214210 webgpu:api,operation,storage_texture,* [ Skip ]
+crbug.com/381214210 webgpu:api,operation,texture_view,write:format* [ Skip ]
+crbug.com/381214210 webgpu:api,operation,vertex_state,correctness* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,capability_checks,limits,maxStorageBuffersPerShaderStage:createPipeline* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,layout_shader_compat:pipeline_layout_shader_exact_match* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,render_pipeline,resource_compatibility:resource_compatibility:stage="fragment";* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,render_pipeline,resource_compatibility:resource_compatibility:stage="vertex";* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,resource_usages,buffer,in_pass_encoder:subresources,buffer_usage_in_one_render_pass_with_one_draw* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,resource_usages,buffer,in_pass_encoder:subresources,buffer_usage_in_one_render_pass_with_two_draws* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,resource_usages,buffer,in_pass_misc:subresources,reset_buffer_usage_before_draw* [ Skip ]
+crbug.com/381214210 webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,dpdx* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,dpdy* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,dpdxFine* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,dpdyFine* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,dpdxCoarse* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,dpdyCoarse* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,fwidth* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,fwidthFine* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,fwidthCoarse* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureDimensions:storage* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:multisampled* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureDimensions:storage:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="c";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="f";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_2d_coords:stage="v";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="c";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="f";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_3d_coords:stage="v";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="c";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="f";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGather:sampled_array_2d_coords:stage="v";format="stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureGatherCompare:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:arrayed:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="r32float";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="r32sint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="r32uint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba16float";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba16sint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba16uint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba32float";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba32sint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba32uint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba8sint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba8snorm";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba8uint";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureNumLayers:storage:format="rgba8unorm";view_type="full" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_2d_coords:format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_2d_coords:format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_2d_coords:format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_2d_coords:format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_3d_coords:format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_3d_coords:format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_3d_coords:format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_3d_coords:format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_array_2d_coords:format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_array_2d_coords:format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_array_2d_coords:format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSample:sampled_array_2d_coords:format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:arrayed_2d_coords:format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:arrayed_2d_coords:format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:arrayed_2d_coords:format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:arrayed_2d_coords:format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_2d_coords:format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_2d_coords:format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_2d_coords:format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_2d_coords:format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_3d_coords:format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_3d_coords:format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_3d_coords:format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_3d_coords:format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleCompare:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleCompareLevel:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_2d_coords:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="c";format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="c";format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="c";format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="c";format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="f";format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="f";format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="f";format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="f";format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="v";format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="v";format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="v";format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_3d_coords:stage="v";format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleGrad:sampled_array_2d_coords:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_2d_coords:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="c";format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="c";format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="c";format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="c";format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="f";format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="f";format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="f";format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="f";format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="v";format="depth16unorm";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="v";format="depth24plus";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="v";format="depth24plus-stencil8";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_3d_coords:stage="v";format="depth32float";dim="cube";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="c";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="c";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="c";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="c";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="f";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="f";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="f";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="f";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="v";format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="v";format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="v";format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureSampleLevel:sampled_array_2d_coords:stage="v";format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="1d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="2d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="2d-array";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="3d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32float";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="1d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="2d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="2d-array";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="3d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32sint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="1d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="2d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="2d-array";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="3d";stage="fragment";access="read_write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="r32uint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16float";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16float";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16float";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16float";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16sint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16sint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16sint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16sint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16uint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16uint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16uint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba16uint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32float";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32float";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32float";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32float";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32sint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32sint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32sint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32sint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32uint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32uint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32uint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba32uint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8sint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8sint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8sint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8sint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8snorm";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8snorm";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8snorm";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8snorm";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8uint";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8uint";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8uint";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8uint";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8unorm";viewDimension="1d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8unorm";viewDimension="2d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8unorm";viewDimension="2d-array";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureStore:texel_formats:format="rgba8unorm";viewDimension="3d";stage="fragment";access="write" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth16unorm";viewDimension="2d" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth16unorm";viewDimension="2d-array" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth16unorm";viewDimension="cube" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth24plus";viewDimension="2d" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth24plus";viewDimension="2d-array" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth24plus";viewDimension="cube" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth24plus-stencil8";viewDimension="2d" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth24plus-stencil8";viewDimension="2d-array" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth24plus-stencil8";viewDimension="cube" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth32float";viewDimension="2d" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth32float";viewDimension="2d-array" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="depth32float";viewDimension="cube" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="stencil8";viewDimension="2d" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="stencil8";viewDimension="2d-array" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:createTextureWithRandomDataAndGetTexels_with_generator:format="stencil8";viewDimension="cube" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="r32float";viewDimension="2d";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="r32float";viewDimension="2d";sampleCount=4 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="r32float";viewDimension="2d-array";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="r32float";viewDimension="cube";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="rgba32float";viewDimension="2d";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="rgba32float";viewDimension="2d";sampleCount=4 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="rgba32float";viewDimension="2d-array";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus";texelViewFormat="rgba32float";viewDimension="cube";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus-stencil8";texelViewFormat="r32float";viewDimension="2d";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus-stencil8";texelViewFormat="r32float";viewDimension="2d";sampleCount=4 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus-stencil8";texelViewFormat="r32float";viewDimension="2d-array";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="depth24plus-stencil8";texelViewFormat="r32float";viewDimension="cube";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="r8sint";texelViewFormat="rgba32sint";viewDimension="2d";sampleCount=4 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="r8uint";texelViewFormat="rgba32uint";viewDimension="2d";sampleCount=4 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="r8unorm";texelViewFormat="rgba32float";viewDimension="2d";sampleCount=4 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="stencil8";texelViewFormat="rgba32sint";viewDimension="2d";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="stencil8";texelViewFormat="rgba32sint";viewDimension="2d";sampleCount=4 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="stencil8";texelViewFormat="rgba32sint";viewDimension="2d-array";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,texture_utils:readTextureToTexelViews:srcFormat="stencil8";texelViewFormat="rgba32sint";viewDimension="cube";sampleCount=1 [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,statement,discard:all:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,statement,discard:continuing:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,statement,discard:derivatives:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,statement,discard:function_call:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,statement,discard:loop:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,statement,discard:three_quarters:* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,statement,discard:uniform_read_loop:* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,resource_usages,texture,in_pass_encoder:scope,basic,render:* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,resource_usages,texture,in_pass_encoder:scope,pass_boundary,render:* [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="draw";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="draw";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="drawIndexed";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="drawIndexed";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="drawIndexedIndirect";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="drawIndexedIndirect";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="drawIndirect";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20bundle";call="drawIndirect";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="draw";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="draw";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="drawIndexed";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="drawIndexed";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="drawIndexedIndirect";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="drawIndexedIndirect";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="drawIndirect";callWithZero=false [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bgl_resource_type_mismatch:encoderType="render%20pass";call="drawIndirect";callWithZero=true [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:buffer_binding,render_pipeline:type="read-only-storage" [ Skip ]
+crbug.com/381214210 webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:buffer_binding,render_pipeline:type="storage" [ Skip ]
+crbug.com/381214210 webgpu:api,operation,rendering,depth_clip_clamp:depth_clamp_and_clip:format="depth16unorm";* [ Skip ]
+crbug.com/381214210 webgpu:api,operation,rendering,depth_clip_clamp:depth_clamp_and_clip:format="depth24plus";* [ Skip ]
+crbug.com/381214210 webgpu:api,operation,rendering,depth_clip_clamp:depth_clamp_and_clip:format="depth24plus-stencil8";* [ Skip ]
+crbug.com/381214210 webgpu:api,operation,rendering,depth_clip_clamp:depth_clamp_and_clip:format="depth32float";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="c";format="depth16unorm" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="c";format="depth24plus" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="c";format="depth24plus-stencil8" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="c";format="depth32float" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="c";format="stencil8" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="f";format="depth16unorm" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="f";format="depth24plus" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="f";format="depth24plus-stencil8" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="f";format="depth32float" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="f";format="stencil8" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="v";format="depth16unorm" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="v";format="depth24plus" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="v";format="depth24plus-stencil8" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="v";format="depth32float" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_2d:stage="v";format="stencil8" [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_1d:stage="f";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_1d:stage="v";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_2d:stage="f";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_2d:stage="v";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_2d_array:stage="f";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_2d_array:stage="v";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_3d:stage="f";* [ Skip ]
+crbug.com/381214210 webgpu:shader,execution,expression,call,builtin,textureLoad:storage_textures_3d:stage="v";* [ Skip ]
+
 ################################################################################
 # Assorted failures that are missing bug associations (NEEDS TRIAGE)
 ################################################################################