[dawn][headers] Flattens wgpu::*Limit structures.

- Flattens wgpu::SupportedLimits and wgpu::RequiredLimits into
  wgpu::Limits, adding extension support on wgpu::Limits in
  the process.
- Note that because the C++ code-gen differentiates between
  in/out structs right now, we are using 'out' for structs that
  can be used for both in and out to ensure the const-ness
  restrictions don't get hit.
- Also updates wgpu::InstanceCapabilities to use 'out' type for
  the reason specified above.
- Updates all dependencies in Dawn for the change and adds a
  #define for downstream users to use to update before landing
  this change.

Bug: 374263404
Change-Id: Ib1a81fd3351dad2b1e2365bdc657619676599e5d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/225294
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/generator/templates/api.h b/generator/templates/api.h
index 46cabc3..3a1cc8b 100644
--- a/generator/templates/api.h
+++ b/generator/templates/api.h
@@ -42,6 +42,7 @@
 #define WGPU_BREAKING_CHANGE_STRING_VIEW_CALLBACKS
 #define WGPU_BREAKING_CHANGE_FUTURE_CALLBACK_TYPES
 #define WGPU_BREAKING_CHANGE_LOGGING_CALLBACK_TYPE
+#define WGPU_BREAKING_CHANGE_FLATTEN_LIMITS
 
 {% set API = metadata.c_prefix %}
 #if defined({{API}}_SHARED_LIBRARY)
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 5261d58..057d90f 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -118,7 +118,7 @@
                 "name": "get limits",
                 "returns": "status",
                 "args": [
-                    {"name": "limits", "type": "supported limits", "annotation": "*"}
+                    {"name": "limits", "type": "limits", "annotation": "*"}
                 ]
             },
             {
@@ -203,7 +203,7 @@
             {"name": "label", "type": "string view", "optional": true},
             {"name": "required feature count", "type": "size_t", "default": 0},
             {"name": "required features", "type": "feature name", "annotation": "const*", "length": "required feature count", "default": "nullptr"},
-            {"name": "required limits", "type": "required limits", "annotation": "const*", "optional": true},
+            {"name": "required limits", "type": "limits", "annotation": "const*", "optional": true},
             {"name": "default queue", "type": "queue descriptor"},
             {"name": "device lost callback info", "type": "device lost callback info"},
             {"name": "uncaptured error callback info", "type": "uncaptured error callback info"}
@@ -1357,7 +1357,7 @@
                 "name": "get limits",
                 "returns": "status",
                 "args": [
-                    {"name": "limits", "type": "supported limits", "annotation": "*"}
+                    {"name": "limits", "type": "limits", "annotation": "*"}
                 ]
             },
             {
@@ -1523,6 +1523,8 @@
     },
     "limits": {
         "category": "structure",
+        "extensible": "out",
+        "_comment": "TODO(crbug.com/374263404): Using 'out' for extensible even though this can be in/out until C++ gen is updated.",
         "members": [
             {"name": "max texture dimension 1D", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max texture dimension 2D", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
@@ -1574,7 +1576,7 @@
     "dawn experimental subgroup limits": {
         "category": "structure",
         "chained": "out",
-        "chain roots": ["supported limits"],
+        "chain roots": ["limits"],
         "tags": ["dawn"],
         "members": [
             {"name": "min subgroup size", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
@@ -1584,7 +1586,7 @@
     "dawn experimental immediate data limits": {
         "category": "structure",
         "chained": "out",
-        "chain roots": ["supported limits"],
+        "chain roots": ["limits"],
         "tags": ["dawn"],
         "members": [
             {"name": "max immediate data range byte size", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"}
@@ -1593,26 +1595,12 @@
     "dawn texel copy buffer row alignment limits": {
         "category": "structure",
         "chained": "out",
-        "chain roots": ["supported limits"],
+        "chain roots": ["limits"],
         "tags": ["dawn"],
         "members": [
             {"name": "min texel copy buffer row alignment", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"}
         ]
     },
-    "required limits": {
-        "category": "structure",
-        "extensible": "in",
-        "members": [
-            {"name": "limits", "type": "limits"}
-        ]
-    },
-    "supported limits": {
-        "category": "structure",
-        "extensible": "out",
-        "members": [
-            {"name": "limits", "type": "limits"}
-        ]
-    },
     "supported features": {
         "category": "structure",
         "out": true,
@@ -2476,7 +2464,8 @@
     },
     "instance capabilities": {
         "category": "structure",
-        "extensible": "in",
+        "extensible": "out",
+        "_comment": "TODO(crbug.com/374263404): Using 'out' for extensible even though this can be in/out until C++ gen is updated.",
         "members": [
             {"name": "timed wait any enable", "type": "bool", "default": "false"},
             {"name": "timed wait any max count", "type": "size_t", "default": "0"}
diff --git a/src/dawn/dawn_wire.json b/src/dawn/dawn_wire.json
index bbe9b73..01d17e2 100644
--- a/src/dawn/dawn_wire.json
+++ b/src/dawn/dawn_wire.json
@@ -203,7 +203,7 @@
             { "name": "status", "type": "request adapter status" },
             { "name": "message", "type": "string view" },
             { "name": "info", "type": "adapter info", "annotation": "const*", "optional": "true" },
-            { "name": "limits", "type": "supported limits", "annotation": "const*", "optional": "true" },
+            { "name": "limits", "type": "limits", "annotation": "const*", "optional": "true" },
             { "name": "features count", "type": "uint32_t"},
             { "name": "features", "type": "feature name", "annotation": "const*", "length": "features count"}
         ],
@@ -212,7 +212,7 @@
             { "name": "future", "type": "future" },
             { "name": "status", "type": "request device status" },
             { "name": "message", "type": "string view" },
-            { "name": "limits", "type": "supported limits", "annotation": "const*", "optional": "true" },
+            { "name": "limits", "type": "limits", "annotation": "const*", "optional": "true" },
             { "name": "features count", "type": "uint32_t"},
             { "name": "features", "type": "feature name", "annotation": "const*", "length": "features count"}
         ]
diff --git a/src/dawn/native/Adapter.cpp b/src/dawn/native/Adapter.cpp
index cc68321..95f047b 100644
--- a/src/dawn/native/Adapter.cpp
+++ b/src/dawn/native/Adapter.cpp
@@ -89,17 +89,22 @@
     return instance;
 }
 
-wgpu::Status AdapterBase::APIGetLimits(SupportedLimits* limits) const {
+wgpu::Status AdapterBase::APIGetLimits(Limits* limits) const {
     DAWN_ASSERT(limits != nullptr);
-    UnpackedPtr<SupportedLimits> unpacked;
+    UnpackedPtr<Limits> unpacked;
     if (mInstance->ConsumedError(ValidateAndUnpack(limits), &unpacked)) {
         return wgpu::Status::Error;
     }
 
-    if (mUseTieredLimits) {
-        limits->limits = ApplyLimitTiers(mPhysicalDevice->GetLimits().v1);
-    } else {
-        limits->limits = mPhysicalDevice->GetLimits().v1;
+    {
+        wgpu::ChainedStructOut* originalChain = unpacked->nextInChain;
+        if (mUseTieredLimits) {
+            **unpacked = ApplyLimitTiers(mPhysicalDevice->GetLimits().v1);
+        } else {
+            **unpacked = mPhysicalDevice->GetLimits().v1;
+        }
+        // Recover origin chain.
+        unpacked->nextInChain = originalChain;
     }
 
     // TODO(crbug.com/382520104): Remove DawnExperimentalSubgroupLimits.
@@ -361,13 +366,13 @@
         DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
                         "can not chain after requiredLimits.");
 
-        SupportedLimits supportedLimits;
+        Limits supportedLimits;
         wgpu::Status status = APIGetLimits(&supportedLimits);
         DAWN_ASSERT(status == wgpu::Status::Success);
 
-        DAWN_TRY_CONTEXT(ValidateLimits(GetFeatureLevel(), supportedLimits.limits,
-                                        descriptor->requiredLimits->limits),
-                         "validating required limits");
+        DAWN_TRY_CONTEXT(
+            ValidateLimits(GetFeatureLevel(), supportedLimits, *descriptor->requiredLimits),
+            "validating required limits");
     }
 
     return mPhysicalDevice->CreateDevice(this, descriptor, deviceToggles, std::move(lostEvent));
diff --git a/src/dawn/native/Adapter.h b/src/dawn/native/Adapter.h
index 19f4aea..0b6df1b 100644
--- a/src/dawn/native/Adapter.h
+++ b/src/dawn/native/Adapter.h
@@ -60,7 +60,7 @@
 
     // WebGPU API
     InstanceBase* APIGetInstance() const;
-    wgpu::Status APIGetLimits(SupportedLimits* limits) const;
+    wgpu::Status APIGetLimits(Limits* limits) const;
     wgpu::Status APIGetInfo(AdapterInfo* info) const;
     bool APIHasFeature(wgpu::FeatureName feature) const;
     void APIGetFeatures(SupportedFeatures* features) const;
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index 7560926..4d9783a 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -359,8 +359,7 @@
     mBlobCache = std::make_unique<BlobCache>(cacheDesc);
 
     if (descriptor->requiredLimits != nullptr) {
-        mLimits.v1 =
-            ReifyDefaultLimits(descriptor->requiredLimits->limits, adapter->GetFeatureLevel());
+        mLimits.v1 = ReifyDefaultLimits(*descriptor->requiredLimits, adapter->GetFeatureLevel());
     } else {
         GetDefaultLimits(&mLimits.v1, adapter->GetFeatureLevel());
     }
@@ -1774,16 +1773,20 @@
     return wgpu::Status::Success;
 }
 
-wgpu::Status DeviceBase::APIGetLimits(SupportedLimits* limits) const {
+wgpu::Status DeviceBase::APIGetLimits(Limits* limits) const {
     DAWN_ASSERT(limits != nullptr);
     InstanceBase* instance = GetAdapter()->GetInstance();
 
-    UnpackedPtr<SupportedLimits> unpacked;
+    UnpackedPtr<Limits> unpacked;
     if (instance->ConsumedError(ValidateAndUnpack(limits), &unpacked)) {
         return wgpu::Status::Error;
     }
 
-    limits->limits = mLimits.v1;
+    {
+        wgpu::ChainedStructOut* originalChain = unpacked->nextInChain;
+        **unpacked = mLimits.v1;
+        unpacked->nextInChain = originalChain;
+    }
 
     // TODO(354751907): Move this to AdapterInfo
     if (auto* subgroupLimits = unpacked.Get<DawnExperimentalSubgroupLimits>()) {
diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h
index c6b15c4..bac9c5b 100644
--- a/src/dawn/native/Device.h
+++ b/src/dawn/native/Device.h
@@ -269,7 +269,7 @@
 
     wgpu::Status APIGetAHardwareBufferProperties(void* handle,
                                                  AHardwareBufferProperties* properties);
-    wgpu::Status APIGetLimits(SupportedLimits* limits) const;
+    wgpu::Status APIGetLimits(Limits* limits) const;
     bool APIHasFeature(wgpu::FeatureName feature) const;
     void APIGetFeatures(wgpu::SupportedFeatures* features) const;
     void APIGetFeatures(SupportedFeatures* features) const;
diff --git a/src/dawn/native/Error.h b/src/dawn/native/Error.h
index 0e1ca3a..c5dd0fd 100644
--- a/src/dawn/native/Error.h
+++ b/src/dawn/native/Error.h
@@ -159,16 +159,15 @@
         limitName, adapterLimitValue);
 }
 
-#define DAWN_INCREASE_LIMIT_MESSAGE(adapter, limitName, limitValue)                      \
-    [&]() -> std::string {                                                               \
-        ::dawn::native::SupportedLimits adapterLimits;                                   \
-        wgpu::Status status = adapter->APIGetLimits(&adapterLimits);                     \
-        DAWN_ASSERT(status == wgpu::Status::Success);                                    \
-        if (limitValue > adapterLimits.limits.limitName) {                               \
-            return "";                                                                   \
-        }                                                                                \
-        return ::dawn::native::MakeIncreaseLimitMessage(#limitName,                      \
-                                                        adapterLimits.limits.limitName); \
+#define DAWN_INCREASE_LIMIT_MESSAGE(adapter, limitName, limitValue)                           \
+    [&]() -> std::string {                                                                    \
+        ::dawn::native::Limits adapterLimits;                                                 \
+        wgpu::Status status = adapter->APIGetLimits(&adapterLimits);                          \
+        DAWN_ASSERT(status == wgpu::Status::Success);                                         \
+        if (limitValue > adapterLimits.limitName) {                                           \
+            return "";                                                                        \
+        }                                                                                     \
+        return ::dawn::native::MakeIncreaseLimitMessage(#limitName, adapterLimits.limitName); \
     }()
 
 #define DAWN_CONCAT1(x, y) x##y
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 9ed810d..620c772 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -1148,16 +1148,13 @@
 
     if (DAWN_UNLIKELY(x > limits.maxComputeWorkgroupSizeX || y > limits.maxComputeWorkgroupSizeY ||
                       z > limits.maxComputeWorkgroupSizeZ)) {
-        SupportedLimits adapterLimits;
+        Limits adapterLimits;
         wgpu::Status status = adapter->APIGetLimits(&adapterLimits);
         DAWN_ASSERT(status == wgpu::Status::Success);
 
-        uint32_t maxComputeWorkgroupSizeXAdapterLimit =
-            adapterLimits.limits.maxComputeWorkgroupSizeX;
-        uint32_t maxComputeWorkgroupSizeYAdapterLimit =
-            adapterLimits.limits.maxComputeWorkgroupSizeY;
-        uint32_t maxComputeWorkgroupSizeZAdapterLimit =
-            adapterLimits.limits.maxComputeWorkgroupSizeZ;
+        uint32_t maxComputeWorkgroupSizeXAdapterLimit = adapterLimits.maxComputeWorkgroupSizeX;
+        uint32_t maxComputeWorkgroupSizeYAdapterLimit = adapterLimits.maxComputeWorkgroupSizeY;
+        uint32_t maxComputeWorkgroupSizeZAdapterLimit = adapterLimits.maxComputeWorkgroupSizeZ;
         std::string increaseLimitAdvice =
             (x <= maxComputeWorkgroupSizeXAdapterLimit &&
              y <= maxComputeWorkgroupSizeYAdapterLimit && z <= maxComputeWorkgroupSizeZAdapterLimit)
diff --git a/src/dawn/native/Texture.cpp b/src/dawn/native/Texture.cpp
index 1365d9d..90c6ed0 100644
--- a/src/dawn/native/Texture.cpp
+++ b/src/dawn/native/Texture.cpp
@@ -304,7 +304,7 @@
     if (DAWN_UNLIKELY(descriptor->size.width > maxExtent.width ||
                       descriptor->size.height > maxExtent.height ||
                       descriptor->size.depthOrArrayLayers > maxExtent.depthOrArrayLayers)) {
-        SupportedLimits adapterLimits;
+        Limits adapterLimits;
         wgpu::Status status = device->GetAdapter()->APIGetLimits(&adapterLimits);
         DAWN_ASSERT(status == wgpu::Status::Success);
 
@@ -315,29 +315,29 @@
             case wgpu::TextureDimension::Undefined:
                 DAWN_UNREACHABLE();
             case wgpu::TextureDimension::e1D:
-                maxExtentAdapter = {adapterLimits.limits.maxTextureDimension1D, 1, 1};
+                maxExtentAdapter = {adapterLimits.maxTextureDimension1D, 1, 1};
                 limitName = "maxTextureDimension1D";
-                limitValue = adapterLimits.limits.maxTextureDimension1D;
+                limitValue = adapterLimits.maxTextureDimension1D;
                 break;
             case wgpu::TextureDimension::e2D:
-                maxExtentAdapter = {adapterLimits.limits.maxTextureDimension2D,
-                                    adapterLimits.limits.maxTextureDimension2D,
-                                    adapterLimits.limits.maxTextureArrayLayers};
+                maxExtentAdapter = {adapterLimits.maxTextureDimension2D,
+                                    adapterLimits.maxTextureDimension2D,
+                                    adapterLimits.maxTextureArrayLayers};
                 if (descriptor->size.width > maxExtent.width ||
                     descriptor->size.height > maxExtent.height) {
                     limitName = "maxTextureDimension2D";
-                    limitValue = adapterLimits.limits.maxTextureDimension2D;
+                    limitValue = adapterLimits.maxTextureDimension2D;
                 } else {
                     limitName = "maxTextureArrayLayers";
-                    limitValue = adapterLimits.limits.maxTextureArrayLayers;
+                    limitValue = adapterLimits.maxTextureArrayLayers;
                 }
                 break;
             case wgpu::TextureDimension::e3D:
-                maxExtentAdapter = {adapterLimits.limits.maxTextureDimension3D,
-                                    adapterLimits.limits.maxTextureDimension3D,
-                                    adapterLimits.limits.maxTextureDimension3D};
+                maxExtentAdapter = {adapterLimits.maxTextureDimension3D,
+                                    adapterLimits.maxTextureDimension3D,
+                                    adapterLimits.maxTextureDimension3D};
                 limitName = "maxTextureDimension3D";
-                limitValue = adapterLimits.limits.maxTextureDimension3D;
+                limitValue = adapterLimits.maxTextureDimension3D;
                 break;
         }
 
diff --git a/src/dawn/node/binding/GPUAdapter.cpp b/src/dawn/node/binding/GPUAdapter.cpp
index 3a9585e..8281412 100644
--- a/src/dawn/node/binding/GPUAdapter.cpp
+++ b/src/dawn/node/binding/GPUAdapter.cpp
@@ -98,7 +98,7 @@
 }
 
 interop::Interface<interop::GPUSupportedLimits> GPUAdapter::getLimits(Napi::Env env) {
-    wgpu::SupportedLimits limits{};
+    wgpu::Limits limits{};
     wgpu::DawnExperimentalImmediateDataLimits immediateDataLimits{};
 
     auto InsertInChain = [&](wgpu::ChainedStructOut* node) {
@@ -218,13 +218,13 @@
         env, PROMISE_INFO, async_);
     auto promise = ctx->promise;
 
-    wgpu::RequiredLimits limits;
+    wgpu::Limits limits;
 #define COPY_LIMIT(LIMIT)                                                                        \
     if (descriptor.requiredLimits.count(#LIMIT)) {                                               \
         auto jsLimitVariant = descriptor.requiredLimits[#LIMIT];                                 \
         if (!std::holds_alternative<interop::UndefinedType>(jsLimitVariant)) {                   \
             using DawnLimitType = decltype(WGPULimits::LIMIT);                                   \
-            DawnLimitType* dawnLimit = &limits.limits.LIMIT;                                     \
+            DawnLimitType* dawnLimit = &limits.LIMIT;                                            \
             uint64_t jsLimit = std::get<interop::GPUSize64>(jsLimitVariant);                     \
             if (jsLimit > std::numeric_limits<DawnLimitType>::max() - 1) {                       \
                 promise.Reject(                                                                  \
diff --git a/src/dawn/node/binding/GPUDevice.cpp b/src/dawn/node/binding/GPUDevice.cpp
index 7b17025..1514d31 100644
--- a/src/dawn/node/binding/GPUDevice.cpp
+++ b/src/dawn/node/binding/GPUDevice.cpp
@@ -181,7 +181,7 @@
 }
 
 interop::Interface<interop::GPUSupportedLimits> GPUDevice::getLimits(Napi::Env env) {
-    wgpu::SupportedLimits limits{};
+    wgpu::Limits limits{};
     wgpu::DawnExperimentalImmediateDataLimits immediateDataLimits{};
 
     auto InsertInChain = [&](wgpu::ChainedStructOut* node) {
diff --git a/src/dawn/node/binding/GPUSupportedLimits.cpp b/src/dawn/node/binding/GPUSupportedLimits.cpp
index 586928f..3ca271f 100644
--- a/src/dawn/node/binding/GPUSupportedLimits.cpp
+++ b/src/dawn/node/binding/GPUSupportedLimits.cpp
@@ -35,157 +35,154 @@
 // wgpu::bindings::GPUSupportedLimits
 ////////////////////////////////////////////////////////////////////////////////
 
-GPUSupportedLimits::GPUSupportedLimits(wgpu::SupportedLimits limits) : limits_(std::move(limits)) {
+GPUSupportedLimits::GPUSupportedLimits(wgpu::Limits limits) : limits_(std::move(limits)) {
     // Clear to prevent using invalid pointer.
     limits_.nextInChain = nullptr;
 }
 
 uint32_t GPUSupportedLimits::getMaxTextureDimension1D(Napi::Env) {
-    return limits_.limits.maxTextureDimension1D;
+    return limits_.maxTextureDimension1D;
 }
 
 uint32_t GPUSupportedLimits::getMaxTextureDimension2D(Napi::Env) {
-    return limits_.limits.maxTextureDimension2D;
+    return limits_.maxTextureDimension2D;
 }
 
 uint32_t GPUSupportedLimits::getMaxTextureDimension3D(Napi::Env) {
-    return limits_.limits.maxTextureDimension3D;
+    return limits_.maxTextureDimension3D;
 }
 
 uint32_t GPUSupportedLimits::getMaxTextureArrayLayers(Napi::Env) {
-    return limits_.limits.maxTextureArrayLayers;
+    return limits_.maxTextureArrayLayers;
 }
 
 uint32_t GPUSupportedLimits::getMaxBindGroups(Napi::Env) {
-    return limits_.limits.maxBindGroups;
+    return limits_.maxBindGroups;
 }
 
 uint32_t GPUSupportedLimits::getMaxBindGroupsPlusVertexBuffers(Napi::Env) {
-    return limits_.limits.maxBindGroupsPlusVertexBuffers;
+    return limits_.maxBindGroupsPlusVertexBuffers;
 }
 
 uint32_t GPUSupportedLimits::getMaxBindingsPerBindGroup(Napi::Env) {
-    return limits_.limits.maxBindingsPerBindGroup;
+    return limits_.maxBindingsPerBindGroup;
 }
 
 uint32_t GPUSupportedLimits::getMaxDynamicUniformBuffersPerPipelineLayout(Napi::Env) {
-    return limits_.limits.maxDynamicUniformBuffersPerPipelineLayout;
+    return limits_.maxDynamicUniformBuffersPerPipelineLayout;
 }
 
 uint32_t GPUSupportedLimits::getMaxDynamicStorageBuffersPerPipelineLayout(Napi::Env) {
-    return limits_.limits.maxDynamicStorageBuffersPerPipelineLayout;
+    return limits_.maxDynamicStorageBuffersPerPipelineLayout;
 }
 
 uint32_t GPUSupportedLimits::getMaxSampledTexturesPerShaderStage(Napi::Env) {
-    return limits_.limits.maxSampledTexturesPerShaderStage;
+    return limits_.maxSampledTexturesPerShaderStage;
 }
 
 uint32_t GPUSupportedLimits::getMaxSamplersPerShaderStage(Napi::Env) {
-    return limits_.limits.maxSamplersPerShaderStage;
+    return limits_.maxSamplersPerShaderStage;
 }
 
 uint32_t GPUSupportedLimits::getMaxStorageBuffersPerShaderStage(Napi::Env) {
-    return limits_.limits.maxStorageBuffersPerShaderStage;
+    return limits_.maxStorageBuffersPerShaderStage;
 }
 
 uint32_t GPUSupportedLimits::getMaxStorageTexturesPerShaderStage(Napi::Env) {
-    return limits_.limits.maxStorageTexturesPerShaderStage;
+    return limits_.maxStorageTexturesPerShaderStage;
 }
 
 uint32_t GPUSupportedLimits::getMaxUniformBuffersPerShaderStage(Napi::Env) {
-    return limits_.limits.maxUniformBuffersPerShaderStage;
+    return limits_.maxUniformBuffersPerShaderStage;
 }
 
 uint64_t GPUSupportedLimits::getMaxUniformBufferBindingSize(Napi::Env) {
-    return limits_.limits.maxUniformBufferBindingSize;
+    return limits_.maxUniformBufferBindingSize;
 }
 
 uint64_t GPUSupportedLimits::getMaxStorageBufferBindingSize(Napi::Env) {
-    return limits_.limits.maxStorageBufferBindingSize;
+    return limits_.maxStorageBufferBindingSize;
 }
 
 uint32_t GPUSupportedLimits::getMinUniformBufferOffsetAlignment(Napi::Env) {
-    return limits_.limits.minUniformBufferOffsetAlignment;
+    return limits_.minUniformBufferOffsetAlignment;
 }
 
 uint32_t GPUSupportedLimits::getMinStorageBufferOffsetAlignment(Napi::Env) {
-    return limits_.limits.minStorageBufferOffsetAlignment;
+    return limits_.minStorageBufferOffsetAlignment;
 }
 
 uint32_t GPUSupportedLimits::getMaxVertexBuffers(Napi::Env) {
-    return limits_.limits.maxVertexBuffers;
+    return limits_.maxVertexBuffers;
 }
 
 uint64_t GPUSupportedLimits::getMaxBufferSize(Napi::Env) {
-    return limits_.limits.maxBufferSize;
+    return limits_.maxBufferSize;
 }
 
 uint32_t GPUSupportedLimits::getMaxVertexAttributes(Napi::Env) {
-    return limits_.limits.maxVertexAttributes;
+    return limits_.maxVertexAttributes;
 }
 
 uint32_t GPUSupportedLimits::getMaxVertexBufferArrayStride(Napi::Env) {
-    return limits_.limits.maxVertexBufferArrayStride;
+    return limits_.maxVertexBufferArrayStride;
 }
 
 uint32_t GPUSupportedLimits::getMaxInterStageShaderVariables(Napi::Env) {
-    return limits_.limits.maxInterStageShaderVariables;
+    return limits_.maxInterStageShaderVariables;
 }
 
 uint32_t GPUSupportedLimits::getMaxColorAttachments(Napi::Env) {
-    return limits_.limits.maxColorAttachments;
+    return limits_.maxColorAttachments;
 }
 
 uint32_t GPUSupportedLimits::getMaxColorAttachmentBytesPerSample(Napi::Env) {
-    return limits_.limits.maxColorAttachmentBytesPerSample;
+    return limits_.maxColorAttachmentBytesPerSample;
 }
 
 uint32_t GPUSupportedLimits::getMaxComputeWorkgroupStorageSize(Napi::Env) {
-    return limits_.limits.maxComputeWorkgroupStorageSize;
+    return limits_.maxComputeWorkgroupStorageSize;
 }
 
 uint32_t GPUSupportedLimits::getMaxComputeInvocationsPerWorkgroup(Napi::Env) {
-    return limits_.limits.maxComputeInvocationsPerWorkgroup;
+    return limits_.maxComputeInvocationsPerWorkgroup;
 }
 
 uint32_t GPUSupportedLimits::getMaxComputeWorkgroupSizeX(Napi::Env) {
-    return limits_.limits.maxComputeWorkgroupSizeX;
+    return limits_.maxComputeWorkgroupSizeX;
 }
 
 uint32_t GPUSupportedLimits::getMaxComputeWorkgroupSizeY(Napi::Env) {
-    return limits_.limits.maxComputeWorkgroupSizeY;
+    return limits_.maxComputeWorkgroupSizeY;
 }
 
 uint32_t GPUSupportedLimits::getMaxComputeWorkgroupSizeZ(Napi::Env) {
-    return limits_.limits.maxComputeWorkgroupSizeZ;
+    return limits_.maxComputeWorkgroupSizeZ;
 }
 
 uint32_t GPUSupportedLimits::getMaxComputeWorkgroupsPerDimension(Napi::Env) {
-    return limits_.limits.maxComputeWorkgroupsPerDimension;
+    return limits_.maxComputeWorkgroupsPerDimension;
 }
 
 std::variant<uint32_t, interop::UndefinedType>
 GPUSupportedLimits::getMaxStorageBuffersInFragmentStage(Napi::Env) {
-    return std::variant<uint32_t, interop::UndefinedType>(
-        limits_.limits.maxStorageBuffersInFragmentStage);
+    return std::variant<uint32_t, interop::UndefinedType>(limits_.maxStorageBuffersInFragmentStage);
 }
 
 std::variant<uint32_t, interop::UndefinedType>
 GPUSupportedLimits::getMaxStorageTexturesInFragmentStage(Napi::Env) {
     return std::variant<uint32_t, interop::UndefinedType>(
-        limits_.limits.maxStorageTexturesInFragmentStage);
+        limits_.maxStorageTexturesInFragmentStage);
 }
 
 std::variant<uint32_t, interop::UndefinedType>
 GPUSupportedLimits::getMaxStorageBuffersInVertexStage(Napi::Env) {
-    return std::variant<uint32_t, interop::UndefinedType>(
-        limits_.limits.maxStorageBuffersInVertexStage);
+    return std::variant<uint32_t, interop::UndefinedType>(limits_.maxStorageBuffersInVertexStage);
 }
 
 std::variant<uint32_t, interop::UndefinedType>
 GPUSupportedLimits::getMaxStorageTexturesInVertexStage(Napi::Env) {
-    return std::variant<uint32_t, interop::UndefinedType>(
-        limits_.limits.maxStorageTexturesInVertexStage);
+    return std::variant<uint32_t, interop::UndefinedType>(limits_.maxStorageTexturesInVertexStage);
 }
 
 }  // namespace wgpu::binding
diff --git a/src/dawn/node/binding/GPUSupportedLimits.h b/src/dawn/node/binding/GPUSupportedLimits.h
index 8d9f22e..66d85cc 100644
--- a/src/dawn/node/binding/GPUSupportedLimits.h
+++ b/src/dawn/node/binding/GPUSupportedLimits.h
@@ -39,7 +39,7 @@
 // GPUSupportedLimits is an implementation of interop::GPUSupportedLimits.
 class GPUSupportedLimits final : public interop::GPUSupportedLimits {
   public:
-    explicit GPUSupportedLimits(wgpu::SupportedLimits limits);
+    explicit GPUSupportedLimits(wgpu::Limits limits);
 
     // interop::GPUSupportedLimits interface compliance
     uint32_t getMaxTextureDimension1D(Napi::Env) override;
@@ -83,7 +83,7 @@
         Napi::Env) override;
 
   private:
-    wgpu::SupportedLimits limits_;
+    wgpu::Limits limits_;
 };
 
 }  // namespace wgpu::binding
diff --git a/src/dawn/samples/DawnInfo.cpp b/src/dawn/samples/DawnInfo.cpp
index 0383161..54a0710 100644
--- a/src/dawn/samples/DawnInfo.cpp
+++ b/src/dawn/samples/DawnInfo.cpp
@@ -254,12 +254,12 @@
 }
 
 void DumpAdapterLimits(const wgpu::Adapter& adapter) {
-    wgpu::SupportedLimits adapterLimits;
+    wgpu::Limits adapterLimits;
     if (adapter.GetLimits(&adapterLimits)) {
         std::cout << "\n";
         std::cout << "  Adapter Limits\n";
         std::cout << "  ==============\n";
-        std::cout << LimitsToString(adapterLimits.limits, "    ") << "\n";
+        std::cout << LimitsToString(adapterLimits, "    ") << "\n";
     }
 }
 
diff --git a/src/dawn/tests/DawnTest.cpp b/src/dawn/tests/DawnTest.cpp
index dc38882..582f0f6 100644
--- a/src/dawn/tests/DawnTest.cpp
+++ b/src/dawn/tests/DawnTest.cpp
@@ -1080,7 +1080,7 @@
     return {};
 }
 
-wgpu::RequiredLimits DawnTestBase::GetRequiredLimits(const wgpu::SupportedLimits&) {
+wgpu::Limits DawnTestBase::GetRequiredLimits(const wgpu::Limits&) {
     return {};
 }
 
@@ -1088,14 +1088,14 @@
     return mParam.adapterProperties;
 }
 
-wgpu::SupportedLimits DawnTestBase::GetAdapterLimits() {
-    wgpu::SupportedLimits supportedLimits = {};
+wgpu::Limits DawnTestBase::GetAdapterLimits() {
+    wgpu::Limits supportedLimits = {};
     adapter.GetLimits(&supportedLimits);
     return supportedLimits;
 }
 
-wgpu::SupportedLimits DawnTestBase::GetSupportedLimits() {
-    wgpu::SupportedLimits supportedLimits = {};
+wgpu::Limits DawnTestBase::GetSupportedLimits() {
+    wgpu::Limits supportedLimits = {};
     device.GetLimits(&supportedLimits);
     return supportedLimits;
 }
@@ -1148,10 +1148,10 @@
         requiredFeatures.push_back(wgpu::FeatureName::ImplicitDeviceSynchronization);
     }
 
-    wgpu::SupportedLimits supportedLimits;
+    wgpu::Limits supportedLimits;
     native::GetProcs().adapterGetLimits(mBackendAdapter.Get(),
-                                        reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits));
-    wgpu::RequiredLimits requiredLimits = GetRequiredLimits(supportedLimits);
+                                        reinterpret_cast<WGPULimits*>(&supportedLimits));
+    wgpu::Limits requiredLimits = GetRequiredLimits(supportedLimits);
 
     wgpu::DeviceDescriptor deviceDescriptor =
         *reinterpret_cast<const wgpu::DeviceDescriptor*>(descriptor);
diff --git a/src/dawn/tests/DawnTest.h b/src/dawn/tests/DawnTest.h
index b1b69f1..0f53976 100644
--- a/src/dawn/tests/DawnTest.h
+++ b/src/dawn/tests/DawnTest.h
@@ -616,12 +616,12 @@
     // code path to handle the situation when not all features are supported.
     virtual std::vector<wgpu::FeatureName> GetRequiredFeatures();
 
-    virtual wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits&);
+    virtual wgpu::Limits GetRequiredLimits(const wgpu::Limits&);
 
     const TestAdapterProperties& GetAdapterProperties() const;
 
-    wgpu::SupportedLimits GetAdapterLimits();
-    wgpu::SupportedLimits GetSupportedLimits();
+    wgpu::Limits GetAdapterLimits();
+    wgpu::Limits GetSupportedLimits();
 
     uint64_t GetDeprecationWarningCountForTesting() const;
 
diff --git a/src/dawn/tests/end2end/BasicTests.cpp b/src/dawn/tests/end2end/BasicTests.cpp
index b757d5b..f82bc4f 100644
--- a/src/dawn/tests/end2end/BasicTests.cpp
+++ b/src/dawn/tests/end2end/BasicTests.cpp
@@ -82,7 +82,7 @@
     EXPECT_EQ(instanceCapabilities.timedWaitAnyMaxCount, kTimedWaitAnyMaxCountDefault);
     EXPECT_EQ(instanceCapabilities.nextInChain, nullptr);
 
-    wgpu::ChainedStruct chained{};
+    wgpu::ChainedStructOut chained{};
     instanceCapabilities.nextInChain = &chained;
     status = wgpu::GetInstanceCapabilities(&instanceCapabilities);
     EXPECT_EQ(status, wgpu::Status::Error);
diff --git a/src/dawn/tests/end2end/BindGroupTests.cpp b/src/dawn/tests/end2end/BindGroupTests.cpp
index e1a0cf3..1bce07a 100644
--- a/src/dawn/tests/end2end/BindGroupTests.cpp
+++ b/src/dawn/tests/end2end/BindGroupTests.cpp
@@ -42,26 +42,20 @@
 
 class BindGroupTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& 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;
-        required.limits.maxStorageBuffersPerShaderStage =
-            supported.limits.maxStorageBuffersPerShaderStage;
-        required.limits.maxStorageTexturesInFragmentStage =
-            supported.limits.maxStorageTexturesInFragmentStage;
-        required.limits.maxStorageTexturesPerShaderStage =
-            supported.limits.maxStorageTexturesPerShaderStage;
+        wgpu::Limits required = {};
+        required.maxStorageBuffersInVertexStage = supported.maxStorageBuffersInVertexStage;
+        required.maxStorageBuffersInFragmentStage = supported.maxStorageBuffersInFragmentStage;
+        required.maxStorageBuffersPerShaderStage = supported.maxStorageBuffersPerShaderStage;
+        required.maxStorageTexturesInFragmentStage = supported.maxStorageTexturesInFragmentStage;
+        required.maxStorageTexturesPerShaderStage = supported.maxStorageTexturesPerShaderStage;
         return required;
     }
 
     void SetUp() override {
         DawnTest::SetUp();
-        mMinUniformBufferOffsetAlignment =
-            GetSupportedLimits().limits.minUniformBufferOffsetAlignment;
+        mMinUniformBufferOffsetAlignment = GetSupportedLimits().minUniformBufferOffsetAlignment;
     }
     wgpu::CommandBuffer CreateSimpleComputeCommandBuffer(const wgpu::ComputePipeline& pipeline,
                                                          const wgpu::BindGroup& bindGroup) {
@@ -811,7 +805,7 @@
 
 // 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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
@@ -893,7 +887,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
@@ -1488,7 +1482,7 @@
 // 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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     utils::ComboRenderPipelineDescriptor pipelineDescriptor;
 
@@ -1559,7 +1553,7 @@
 
     // Test various usages and binding types since they take different backend code paths.
     doBufferTest(wgpu::BufferBindingType::Uniform, wgpu::BufferUsage::Uniform);
-    if (GetSupportedLimits().limits.maxStorageBuffersInFragmentStage > 0) {
+    if (GetSupportedLimits().maxStorageBuffersInFragmentStage > 0) {
         doBufferTest(wgpu::BufferBindingType::Storage, wgpu::BufferUsage::Storage);
         doBufferTest(wgpu::BufferBindingType::ReadOnlyStorage, wgpu::BufferUsage::Storage);
     }
diff --git a/src/dawn/tests/end2end/BufferTests.cpp b/src/dawn/tests/end2end/BufferTests.cpp
index e7a0975..70fa5e2 100644
--- a/src/dawn/tests/end2end/BufferTests.cpp
+++ b/src/dawn/tests/end2end/BufferTests.cpp
@@ -1220,12 +1220,10 @@
 
 class BufferMapExtendedUsagesTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
-        wgpu::RequiredLimits required = {};
-        required.limits.maxStorageBuffersInVertexStage =
-            supported.limits.maxStorageBuffersInVertexStage;
-        required.limits.maxStorageBuffersPerShaderStage =
-            supported.limits.maxStorageBuffersPerShaderStage;
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
+        wgpu::Limits required = {};
+        required.maxStorageBuffersInVertexStage = supported.maxStorageBuffersInVertexStage;
+        required.maxStorageBuffersPerShaderStage = supported.maxStorageBuffersPerShaderStage;
         return required;
     }
 
@@ -1636,7 +1634,7 @@
     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);
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 1);
 
     // Create buffer with initial red color data.
     wgpu::Buffer storageBuffer = CreateBufferFromData(
@@ -1845,7 +1843,7 @@
 }
 
 TEST_P(BufferMapExtendedUsagesTests, MixMapWriteAndGPUWriteStorageBufferThenDraw) {
-    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 1);
     MixMapWriteAndGPUWriteBufferThenDraw(ColorSrc::StorageBuffer);
 }
 
@@ -1856,7 +1854,7 @@
 // - draw using the storage buffer.
 TEST_P(BufferMapExtendedUsagesTests,
        MapWriteThenGPUWriteStorageBufferThenCopyFromAnotherBufferThenDraw) {
-    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 1);
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 1);
 
     const float kRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
     const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f};
diff --git a/src/dawn/tests/end2end/ComputeDispatchTests.cpp b/src/dawn/tests/end2end/ComputeDispatchTests.cpp
index 84772e7..4819e85 100644
--- a/src/dawn/tests/end2end/ComputeDispatchTests.cpp
+++ b/src/dawn/tests/end2end/ComputeDispatchTests.cpp
@@ -176,7 +176,7 @@
         std::vector<uint32_t> expected;
 
         uint32_t maxComputeWorkgroupsPerDimension =
-            GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+            GetSupportedLimits().maxComputeWorkgroupsPerDimension;
         if (indirectBufferData[indirectStart] == 0 || indirectBufferData[indirectStart + 1] == 0 ||
             indirectBufferData[indirectStart + 2] == 0 ||
             indirectBufferData[indirectStart] > maxComputeWorkgroupsPerDimension ||
@@ -269,7 +269,7 @@
     // TODO(crbug.com/dawn/1196): Fails on Chromium's Quadro P400 bots
     DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsNvidia());
 #endif
-    uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
 
     // Test that the maximum works in each dimension.
     // Note: Testing (max, max, max) is very slow.
@@ -282,7 +282,7 @@
 TEST_P(ComputeDispatchTests, ExceedsMaxWorkgroupsNoop) {
     DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));
 
-    uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
 
     // All dimensions are above the max
     IndirectTest({max + 1, max + 1, max + 1}, 0);
@@ -304,7 +304,7 @@
 TEST_P(ComputeDispatchTests, ExceedsMaxWorkgroupsWithOffsetNoop) {
     DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));
 
-    uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
 
     IndirectTest({1, 2, 3, max + 1, 4, 5}, 1 * sizeof(uint32_t));
     IndirectTest({1, 2, 3, max + 1, 4, 5}, 2 * sizeof(uint32_t));
@@ -482,7 +482,7 @@
         queue.Submit(1, &commands);
 
         uint32_t maxComputeWorkgroupsPerDimension =
-            GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+            GetSupportedLimits().maxComputeWorkgroupsPerDimension;
 
         std::vector<uint32_t> expected(4 * indirectOffsets.size(), 0);
         for (size_t i = 0; i < indirectOffsets.size(); i++) {
@@ -558,7 +558,7 @@
     DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsNvidia());
 #endif
 
-    uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
 
     // Two dispatches: first is no-op
     IndirectTest({max + 1, 1, 1, 2, 3, 4}, {0, 3 * sizeof(uint32_t)});
diff --git a/src/dawn/tests/end2end/CopyTests.cpp b/src/dawn/tests/end2end/CopyTests.cpp
index f8e27f2..87823d1 100644
--- a/src/dawn/tests/end2end/CopyTests.cpp
+++ b/src/dawn/tests/end2end/CopyTests.cpp
@@ -310,7 +310,7 @@
         if (!device.HasFeature(wgpu::FeatureName::DawnTexelCopyBufferRowAlignment)) {
             return kTextureBytesPerRowAlignment;
         }
-        wgpu::SupportedLimits limits{};
+        wgpu::Limits limits{};
         wgpu::DawnTexelCopyBufferRowAlignmentLimits alignmentLimits{};
         limits.nextInChain = &alignmentLimits;
         device.GetLimits(&limits);
diff --git a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
index 5057a55..46ce595 100644
--- a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
@@ -58,12 +58,10 @@
 
 class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingTestParams> {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // Just copy all the limits, though all we really care about is
         // maxStorageBuffersInFragmentStage
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
+        return supported;
     }
 
     enum class TestAspectAndSamplerType {
@@ -790,7 +788,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     wgpu::TextureFormat format = GetParam().mTextureFormat;
 
@@ -1002,7 +1000,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     wgpu::TextureFormat format = GetParam().mTextureFormat;
 
diff --git a/src/dawn/tests/end2end/DeviceLostTests.cpp b/src/dawn/tests/end2end/DeviceLostTests.cpp
index 9af19c6..8f84699 100644
--- a/src/dawn/tests/end2end/DeviceLostTests.cpp
+++ b/src/dawn/tests/end2end/DeviceLostTests.cpp
@@ -49,13 +49,11 @@
 
 class DeviceLostTest : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // TODO(crbug.com/383593270): Enable all the limits.
-        wgpu::RequiredLimits required = {};
-        required.limits.maxStorageBuffersInFragmentStage =
-            supported.limits.maxStorageBuffersInFragmentStage;
-        required.limits.maxStorageBuffersPerShaderStage =
-            supported.limits.maxStorageBuffersPerShaderStage;
+        wgpu::Limits required = {};
+        required.maxStorageBuffersInFragmentStage = supported.maxStorageBuffersInFragmentStage;
+        required.maxStorageBuffersPerShaderStage = supported.maxStorageBuffersPerShaderStage;
         return required;
     }
 
@@ -490,7 +488,7 @@
 // references to bind group layouts such that the cache was non-empty at the end
 // of shut down.
 TEST_P(DeviceLostTest, FreeBindGroupAfterDeviceLossWithPendingCommands) {
-    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
         device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
diff --git a/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp b/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp
index 079bd88..5d0baf3 100644
--- a/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp
+++ b/src/dawn/tests/end2end/DrawIndexedIndirectTests.cpp
@@ -39,12 +39,10 @@
 
 class DrawIndexedIndirectTest : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // Force larger limits, that might reach into the upper 32 bits of the 64bit limit values,
         // to help detect integer arithmetic bugs like overflows and truncations.
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
+        return supported;
     }
 
     void SetUp() override {
diff --git a/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp b/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp
index 8ba2e10..a9532c0 100644
--- a/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp
+++ b/src/dawn/tests/end2end/DynamicBufferOffsetTests.cpp
@@ -43,23 +43,20 @@
 
 class DynamicBufferOffsetTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // TODO(crbug.com/383593270): Enable all the limits.
-        wgpu::RequiredLimits required = {};
-        required.limits.maxStorageBuffersInFragmentStage =
-            supported.limits.maxStorageBuffersInFragmentStage;
-        required.limits.maxStorageBuffersPerShaderStage =
-            supported.limits.maxStorageBuffersPerShaderStage;
+        wgpu::Limits required = {};
+        required.maxStorageBuffersInFragmentStage = supported.maxStorageBuffersInFragmentStage;
+        required.maxStorageBuffersPerShaderStage = supported.maxStorageBuffersPerShaderStage;
         return required;
     }
 
     void SetUp() override {
         DawnTest::SetUp();
 
-        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
-        mMinUniformBufferOffsetAlignment =
-            GetSupportedLimits().limits.minUniformBufferOffsetAlignment;
+        mMinUniformBufferOffsetAlignment = GetSupportedLimits().minUniformBufferOffsetAlignment;
 
         // Mix up dynamic and non dynamic resources in one bind group and using not continuous
         // binding number to cover more cases.
@@ -616,10 +613,8 @@
         pipeline = device.CreateComputePipeline(&pipelineDesc);
     }
 
-    uint32_t minUniformBufferOffsetAlignment =
-        GetSupportedLimits().limits.minUniformBufferOffsetAlignment;
-    uint32_t minStorageBufferOffsetAlignment =
-        GetSupportedLimits().limits.minStorageBufferOffsetAlignment;
+    uint32_t minUniformBufferOffsetAlignment = GetSupportedLimits().minUniformBufferOffsetAlignment;
+    uint32_t minStorageBufferOffsetAlignment = GetSupportedLimits().minStorageBufferOffsetAlignment;
 
     uint32_t arrayByteLength = kArrayLength * 4 * sizeof(uint32_t);
 
diff --git a/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp b/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp
index e2345d7..fa4682d 100644
--- a/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp
+++ b/src/dawn/tests/end2end/GpuMemorySynchronizationTests.cpp
@@ -40,17 +40,15 @@
 
 class GpuMemorySyncTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // Just copy all the limits, though all we really care about is
         // maxStorageBuffersInFragmentStage
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
+        return supported;
     }
 
     void SetUp() override {
         DawnTest::SetUp();
-        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
     }
 
     wgpu::Buffer CreateBuffer() {
@@ -123,7 +121,7 @@
 // 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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     // Create pipeline, bind group, and buffer for compute pass.
     wgpu::Buffer buffer = CreateBuffer();
@@ -433,17 +431,15 @@
 
 class MultipleWriteThenMultipleReadTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // Just copy all the limits, though all we really care about is
         // maxStorageBuffersInFragmentStage
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
+        return supported;
     }
 
     void SetUp() override {
         DawnTest::SetUp();
-        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+        DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
     }
 
   protected:
diff --git a/src/dawn/tests/end2end/MaxLimitTests.cpp b/src/dawn/tests/end2end/MaxLimitTests.cpp
index 56355aa..a34cd8c 100644
--- a/src/dawn/tests/end2end/MaxLimitTests.cpp
+++ b/src/dawn/tests/end2end/MaxLimitTests.cpp
@@ -41,17 +41,12 @@
 
 class MaxLimitTests : public DawnTest {
   public:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
-    }
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override { return supported; }
 };
 
 // Test using the maximum amount of workgroup memory works
 TEST_P(MaxLimitTests, MaxComputeWorkgroupStorageSize) {
-    uint32_t maxComputeWorkgroupStorageSize =
-        GetSupportedLimits().limits.maxComputeWorkgroupStorageSize;
+    uint32_t maxComputeWorkgroupStorageSize = GetSupportedLimits().maxComputeWorkgroupStorageSize;
 
     std::string shader = R"(
         struct Dst {
@@ -141,7 +136,7 @@
         std::string shader;
         switch (usage) {
             case wgpu::BufferUsage::Storage:
-                maxBufferBindingSize = GetSupportedLimits().limits.maxStorageBufferBindingSize;
+                maxBufferBindingSize = GetSupportedLimits().maxStorageBufferBindingSize;
                 // TODO(crbug.com/dawn/1160): Usually can't actually allocate a buffer this large
                 // because allocating the buffer for zero-initialization fails.
                 maxBufferBindingSize =
@@ -178,7 +173,7 @@
               )";
                 break;
             case wgpu::BufferUsage::Uniform:
-                maxBufferBindingSize = GetSupportedLimits().limits.maxUniformBufferBindingSize;
+                maxBufferBindingSize = GetSupportedLimits().maxUniformBufferBindingSize;
 
                 // Clamp to not exceed the maximum i32 value for the WGSL @size(x) annotation.
                 maxBufferBindingSize = std::min(maxBufferBindingSize,
@@ -275,7 +270,7 @@
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
 
-    wgpu::Limits limits = GetSupportedLimits().limits;
+    wgpu::Limits limits = GetSupportedLimits();
 
     std::vector<wgpu::BindGroupLayoutEntry> bglEntries;
     std::vector<wgpu::BindGroupEntry> bgEntries;
@@ -430,7 +425,7 @@
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
 
-    wgpu::Limits limits = GetSupportedLimits().limits;
+    wgpu::Limits limits = GetSupportedLimits();
 
     std::vector<wgpu::BindGroupLayoutEntry> bglEntries;
     std::vector<wgpu::BindGroupEntry> bgEntries;
@@ -555,7 +550,7 @@
     // TODO(crbug.com/dawn/590): Failing on Pixel4
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());
 
-    wgpu::Limits limits = GetSupportedLimits().limits;
+    wgpu::Limits limits = GetSupportedLimits();
 
     std::ostringstream interface;
     std::ostringstream body;
@@ -711,7 +706,7 @@
     // there is at least one color attachment, and as many of the buffer/textures as possible,
     // splitting a shared remaining count between the two resources if they are not separately
     // defined, or exceed the combined limit.
-    wgpu::Limits limits = GetSupportedLimits().limits;
+    wgpu::Limits limits = GetSupportedLimits();
     uint32_t attachmentCount = limits.maxColorAttachments;
     uint32_t storageBuffers = limits.maxStorageBuffersPerShaderStage;
     uint32_t storageTextures = limits.maxStorageTexturesPerShaderStage;
@@ -844,13 +839,13 @@
 // Verifies that supported buffer limits do not exceed maxBufferSize.
 TEST_P(MaxLimitTests, MaxBufferSizes) {
     // Base limits without tiering.
-    wgpu::Limits baseLimits = GetAdapterLimits().limits;
+    wgpu::Limits baseLimits = GetAdapterLimits();
     EXPECT_LE(baseLimits.maxStorageBufferBindingSize, baseLimits.maxBufferSize);
     EXPECT_LE(baseLimits.maxUniformBufferBindingSize, baseLimits.maxBufferSize);
 
     // Base limits with tiering.
     GetAdapter().SetUseTieredLimits(true);
-    wgpu::Limits tieredLimits = GetAdapterLimits().limits;
+    wgpu::Limits tieredLimits = GetAdapterLimits();
     EXPECT_LE(tieredLimits.maxStorageBufferBindingSize, tieredLimits.maxBufferSize);
     EXPECT_LE(tieredLimits.maxUniformBufferBindingSize, tieredLimits.maxBufferSize);
 
@@ -901,7 +896,7 @@
     // Allocate the inter-stage shader variables that consume as many inter-stage shader variables
     // as possible.
     uint32_t GetInterStageVariableCount(const MaxInterStageLimitTestsSpec& spec) {
-        wgpu::Limits baseLimits = GetAdapterLimits().limits;
+        wgpu::Limits baseLimits = GetAdapterLimits();
 
         uint32_t builtinVariableCount = 0;
         if (spec.renderPointLists) {
@@ -1138,7 +1133,7 @@
 TEST_P(MaxInterStageShaderVariablesLimitTests, MaxLocation_ClipDistances) {
     DAWN_TEST_UNSUPPORTED_IF(!mSupportsClipDistances);
 
-    wgpu::Limits baseLimits = GetAdapterLimits().limits;
+    wgpu::Limits baseLimits = GetAdapterLimits();
 
     constexpr std::array<wgpu::PrimitiveTopology, 2> kPrimitives = {
         {wgpu::PrimitiveTopology::TriangleList, wgpu::PrimitiveTopology::PointList}};
@@ -1206,7 +1201,7 @@
 
   private:
     wgpu::RenderPipeline CreateRenderPipeline(const TestSpec& spec) {
-        wgpu::Limits baseLimits = GetAdapterLimits().limits;
+        wgpu::Limits baseLimits = GetAdapterLimits();
         uint32_t maxVertexAttributes = baseLimits.maxVertexAttributes;
 
         // In compatibility mode @builtin(vertex_index) and @builtin(instance_index) each use an
diff --git a/src/dawn/tests/end2end/MultiDrawIndexedIndirectTests.cpp b/src/dawn/tests/end2end/MultiDrawIndexedIndirectTests.cpp
index 840a30e..e451a77 100644
--- a/src/dawn/tests/end2end/MultiDrawIndexedIndirectTests.cpp
+++ b/src/dawn/tests/end2end/MultiDrawIndexedIndirectTests.cpp
@@ -39,12 +39,10 @@
 
 class MultiDrawIndexedIndirectTest : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // Force larger limits, that might reach into the upper 32 bits of the 64bit limit values,
         // to help detect integer arithmetic bugs like overflows and truncations.
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
+        return supported;
     }
 
     std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
diff --git a/src/dawn/tests/end2end/OpArrayLengthTests.cpp b/src/dawn/tests/end2end/OpArrayLengthTests.cpp
index 125f6c3..16902aa 100644
--- a/src/dawn/tests/end2end/OpArrayLengthTests.cpp
+++ b/src/dawn/tests/end2end/OpArrayLengthTests.cpp
@@ -37,13 +37,11 @@
 
 class OpArrayLengthTest : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& 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;
+        return supported;
     }
 
     void SetUp() override {
@@ -181,7 +179,7 @@
     // Nvidia OpenGL.
     DAWN_SUPPRESS_TEST_IF(IsNvidia() && (IsOpenGL() || IsOpenGLES()));
 
-    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 3);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 3);
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
 
@@ -242,7 +240,7 @@
     // TODO(crbug.com/dawn/2295): Also failing on Pixel 6 OpenGLES (ARM).
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
 
-    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInVertexStage < 3);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 3);
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);
 
diff --git a/src/dawn/tests/end2end/PipelineCachingTests.cpp b/src/dawn/tests/end2end/PipelineCachingTests.cpp
index 5c793bb..4750133 100644
--- a/src/dawn/tests/end2end/PipelineCachingTests.cpp
+++ b/src/dawn/tests/end2end/PipelineCachingTests.cpp
@@ -130,12 +130,10 @@
 
 class SinglePipelineCachingTests : public PipelineCachingTests {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // Just copy all the limits, though all we really care about is
         // maxStorageBuffersInFragmentStage
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
+        return supported;
     }
 };
 
@@ -544,7 +542,7 @@
 // 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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     // First time should create and write out to the cache.
     {
diff --git a/src/dawn/tests/end2end/PipelineLayoutTests.cpp b/src/dawn/tests/end2end/PipelineLayoutTests.cpp
index f99f810..5e5fc24 100644
--- a/src/dawn/tests/end2end/PipelineLayoutTests.cpp
+++ b/src/dawn/tests/end2end/PipelineLayoutTests.cpp
@@ -36,13 +36,11 @@
 
 class PipelineLayoutTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // TODO(crbug.com/383593270): Enable all the limits.
-        wgpu::RequiredLimits required = {};
-        required.limits.maxStorageBuffersInFragmentStage =
-            supported.limits.maxStorageBuffersInFragmentStage;
-        required.limits.maxStorageBuffersPerShaderStage =
-            supported.limits.maxStorageBuffersPerShaderStage;
+        wgpu::Limits required = {};
+        required.maxStorageBuffersInFragmentStage = supported.maxStorageBuffersInFragmentStage;
+        required.maxStorageBuffersPerShaderStage = supported.maxStorageBuffersPerShaderStage;
         return required;
     }
 };
@@ -52,14 +50,14 @@
 // dynamic offset bindings were at max. Test is successful if the pipeline layout is created
 // without error.
 TEST_P(PipelineLayoutTests, DynamicBuffersOverflow) {
-    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
     // Create the first bind group layout which uses max number of dynamic buffers bindings.
     wgpu::BindGroupLayout bglA;
     {
         std::vector<wgpu::BindGroupLayoutEntry> entries;
-        for (uint32_t i = 0;
-             i < GetSupportedLimits().limits.maxDynamicStorageBuffersPerPipelineLayout; i++) {
+        for (uint32_t i = 0; i < GetSupportedLimits().maxDynamicStorageBuffersPerPipelineLayout;
+             i++) {
             wgpu::BindGroupLayoutEntry entry;
             entry.binding = i;
             entry.visibility = wgpu::ShaderStage::Compute;
diff --git a/src/dawn/tests/end2end/PixelLocalStorageTests.cpp b/src/dawn/tests/end2end/PixelLocalStorageTests.cpp
index 75482ff..daea321 100644
--- a/src/dawn/tests/end2end/PixelLocalStorageTests.cpp
+++ b/src/dawn/tests/end2end/PixelLocalStorageTests.cpp
@@ -36,12 +36,10 @@
 
 class PixelLocalStorageTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
-        wgpu::RequiredLimits required = {};
-        required.limits.maxStorageBuffersInFragmentStage =
-            supported.limits.maxStorageBuffersInFragmentStage;
-        required.limits.maxStorageBuffersPerShaderStage =
-            supported.limits.maxStorageBuffersPerShaderStage;
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
+        wgpu::Limits required = {};
+        required.maxStorageBuffersInFragmentStage = supported.maxStorageBuffersInFragmentStage;
+        required.maxStorageBuffersPerShaderStage = supported.maxStorageBuffersPerShaderStage;
         return required;
     }
 
@@ -51,7 +49,7 @@
             !device.HasFeature(wgpu::FeatureName::PixelLocalStorageCoherent) &&
             !device.HasFeature(wgpu::FeatureName::PixelLocalStorageNonCoherent));
 
-        DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+        DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
 
         supportsCoherent = device.HasFeature(wgpu::FeatureName::PixelLocalStorageCoherent);
     }
diff --git a/src/dawn/tests/end2end/QueueTests.cpp b/src/dawn/tests/end2end/QueueTests.cpp
index bef8a71..e0dddf8 100644
--- a/src/dawn/tests/end2end/QueueTests.cpp
+++ b/src/dawn/tests/end2end/QueueTests.cpp
@@ -190,7 +190,7 @@
 // Test using the max buffer size. Regression test for dawn:1985. We don't bother validating the
 // results for this case since that would take a lot longer, just that there are no errors.
 TEST_P(QueueWriteBufferTests, MaxBufferSizeWriteBuffer) {
-    uint32_t maxBufferSize = GetSupportedLimits().limits.maxBufferSize;
+    uint32_t maxBufferSize = GetSupportedLimits().maxBufferSize;
     wgpu::BufferDescriptor descriptor;
     descriptor.size = maxBufferSize;
     descriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
diff --git a/src/dawn/tests/end2end/RenderPassLoadOpTests.cpp b/src/dawn/tests/end2end/RenderPassLoadOpTests.cpp
index af7fb65..8a4d8dc 100644
--- a/src/dawn/tests/end2end/RenderPassLoadOpTests.cpp
+++ b/src/dawn/tests/end2end/RenderPassLoadOpTests.cpp
@@ -625,7 +625,7 @@
             expectedDataForRGBA32Float)}};
 
     for (const TestCase& testCase : kTestCases) {
-        if (testCase.size() > GetSupportedLimits().limits.maxColorAttachments) {
+        if (testCase.size() > GetSupportedLimits().maxColorAttachments) {
             continue;
         }
         std::vector<wgpu::Texture> textures;
diff --git a/src/dawn/tests/end2end/ShaderTests.cpp b/src/dawn/tests/end2end/ShaderTests.cpp
index d70a9e2..a81d52d 100644
--- a/src/dawn/tests/end2end/ShaderTests.cpp
+++ b/src/dawn/tests/end2end/ShaderTests.cpp
@@ -38,15 +38,13 @@
 
 class ShaderTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& 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;
+        return supported;
     }
 
   public:
@@ -1844,8 +1842,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 4);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 3);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         @group(2) @binding(2) var<storage> u0_2: f32;
@@ -1886,8 +1884,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 2);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 1);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         struct block {
@@ -1923,8 +1921,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 4);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 3);
 
     wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
         @group(2) @binding(2) var<storage> u0_2: f32;
@@ -1964,8 +1962,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 2);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         @group(0) @binding(0) var<storage> tint_symbol_ubo_0: f32;
@@ -1994,8 +1992,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 1);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         struct X { x : vec4f }
@@ -2027,8 +2025,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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInVertexStage < 1);
 
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
         struct X { x : vec4f }
@@ -2618,8 +2616,8 @@
 
 // Regression test for crbug.com/dawn/388870480.
 TEST_P(ShaderTests, CollisionHandle) {
-    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageTexturesInVertexStage < 2);
-    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageTexturesInVertexStage < 2);
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageTexturesInFragmentStage < 1);
 
     // TODO(crbug.com/394915257): ANGLE D3D11 bug
     DAWN_SUPPRESS_TEST_IF(IsANGLED3D11());
@@ -2652,8 +2650,8 @@
 // Regression test for crbug.com/dawn/388870480.
 // Trigger potential collision when disable_symbol_renaming is on
 TEST_P(ShaderTests, CollisionHandle_DifferentModules) {
-    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageTexturesInVertexStage < 2);
-    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageTexturesInVertexStage < 2);
+    DAWN_TEST_UNSUPPORTED_IF(GetSupportedLimits().maxStorageTexturesInFragmentStage < 1);
 
     // TODO(crbug.com/394915257): ANGLE D3D11 bug
     DAWN_SUPPRESS_TEST_IF(IsANGLED3D11());
diff --git a/src/dawn/tests/end2end/ShaderValidationTests.cpp b/src/dawn/tests/end2end/ShaderValidationTests.cpp
index 0fe683c..23a521d 100644
--- a/src/dawn/tests/end2end/ShaderValidationTests.cpp
+++ b/src/dawn/tests/end2end/ShaderValidationTests.cpp
@@ -108,8 +108,7 @@
 
     void TestInitializedWithOutOfLimitValue(const wgpu::ShaderModule& module) {
         std::vector<wgpu::ConstantEntry> constants{
-            {nullptr, "x",
-             static_cast<double>(GetSupportedLimits().limits.maxComputeWorkgroupSizeX + 1)},
+            {nullptr, "x", static_cast<double>(GetSupportedLimits().maxComputeWorkgroupSizeX + 1)},
             {nullptr, "y", 1},
             {nullptr, "z", 1}};
         TestCreatePipeline(module, constants);
@@ -145,7 +144,7 @@
         }
     };
 
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     CheckShaderWithWorkgroupSize(true, 1, 1, 1);
     CheckShaderWithWorkgroupSize(true, supportedLimits.maxComputeWorkgroupSizeX, 1, 1);
@@ -169,7 +168,7 @@
 
 // Test workgroup size validation with fixed values (storage size limits validation).
 TEST_P(WorkgroupSizeValidationTest, WithFixedValuesStorageSizeLimits) {
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     constexpr uint32_t kVec4Size = 16;
     const uint32_t maxVec4Count = supportedLimits.maxComputeWorkgroupStorageSize / kVec4Size;
@@ -302,8 +301,7 @@
     {
         // Error: invalid value (out of device limits)
         std::vector<wgpu::ConstantEntry> constants{
-            {nullptr, "x",
-             static_cast<double>(GetSupportedLimits().limits.maxComputeWorkgroupSizeX + 1)}};
+            {nullptr, "x", static_cast<double>(GetSupportedLimits().maxComputeWorkgroupSizeX + 1)}};
         ASSERT_DEVICE_ERROR(TestCreatePipeline(module, constants));
     }
     {
@@ -316,7 +314,7 @@
 // Test workgroup size validation after being overrided with invalid values.
 TEST_P(WorkgroupSizeValidationTest, ValidationAfterOverride) {
     wgpu::ShaderModule module = SetUpShaderWithUninitializedConstants();
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
     {
         // Error: exceed maxComputeWorkgroupSizeZ
         std::vector<wgpu::ConstantEntry> constants{
@@ -342,7 +340,7 @@
 // Test workgroup size validation after being overrided with invalid values (storage size limits
 // validation).
 TEST_P(WorkgroupSizeValidationTest, ValidationAfterOverrideStorageSize) {
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     constexpr uint32_t kVec4Size = 16;
     const uint32_t maxVec4Count = supportedLimits.maxComputeWorkgroupStorageSize / kVec4Size;
diff --git a/src/dawn/tests/end2end/StorageTextureTests.cpp b/src/dawn/tests/end2end/StorageTextureTests.cpp
index 5e54ed8..722adbc 100644
--- a/src/dawn/tests/end2end/StorageTextureTests.cpp
+++ b/src/dawn/tests/end2end/StorageTextureTests.cpp
@@ -42,15 +42,13 @@
 
 class StorageTextureTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& 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;
+        return supported;
     }
 
   public:
@@ -746,7 +744,7 @@
     // 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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageTexturesInFragmentStage < 1);
 
     for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
         if (!utils::TextureFormatSupportsStorageTexture(format, device, IsCompatibilityMode())) {
@@ -1087,7 +1085,7 @@
 // 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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageTexturesInFragmentStage < 1);
 
     // Prepare the write-only storage texture.
     wgpu::Texture writeonlyStorageTexture = CreateTexture(
@@ -1172,7 +1170,7 @@
 
 // Verify read-write storage texture can work correctly in fragment shaders.
 TEST_P(ReadWriteStorageTextureTests, ReadWriteStorageTextureInFragmentShader) {
-    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageTexturesInFragmentStage < 1);
 
     std::array<uint32_t, kWidth * kHeight> inputData;
     std::array<uint32_t, kWidth * kHeight> expectedData;
@@ -1295,7 +1293,7 @@
     // 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);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageTexturesInVertexStage < 1);
 
     constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Uint;
     const std::vector<uint8_t> kInitialTextureData = GetExpectedData(kStorageTextureFormat);
@@ -1343,7 +1341,7 @@
 
 // Verify read-only storage texture can work correctly in fragment shaders.
 TEST_P(ReadWriteStorageTextureTests, ReadOnlyStorageTextureInFragmentShader) {
-    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageTexturesInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageTexturesInFragmentStage < 1);
 
     constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Uint;
     const std::vector<uint8_t> kInitialTextureData = GetExpectedData(kStorageTextureFormat);
diff --git a/src/dawn/tests/end2end/SurfaceConfigurationValidationTests.cpp b/src/dawn/tests/end2end/SurfaceConfigurationValidationTests.cpp
index 17c634b..32b3076 100644
--- a/src/dawn/tests/end2end/SurfaceConfigurationValidationTests.cpp
+++ b/src/dawn/tests/end2end/SurfaceConfigurationValidationTests.cpp
@@ -267,22 +267,22 @@
 // A width that exceeds the maximum texture size fails
 TEST_P(SurfaceConfigurationValidationTests, ExcessiveWidth) {
     wgpu::Surface surface = CreateTestSurface();
-    wgpu::SupportedLimits supported;
+    wgpu::Limits supported;
     device.GetLimits(&supported);
 
     wgpu::SurfaceConfiguration config = GetPreferredConfiguration(surface);
-    config.width = supported.limits.maxTextureDimension1D + 1;
+    config.width = supported.maxTextureDimension1D + 1;
     ASSERT_DEVICE_ERROR(surface.Configure(&config));
 }
 
 // A height that exceeds the maximum texture size fails
 TEST_P(SurfaceConfigurationValidationTests, ExcessiveHeight) {
     wgpu::Surface surface = CreateTestSurface();
-    wgpu::SupportedLimits supported;
+    wgpu::Limits supported;
     device.GetLimits(&supported);
 
     wgpu::SurfaceConfiguration config = GetPreferredConfiguration(surface);
-    config.height = supported.limits.maxTextureDimension2D + 1;
+    config.height = supported.maxTextureDimension2D + 1;
     ASSERT_DEVICE_ERROR(surface.Configure(&config));
 }
 
diff --git a/src/dawn/tests/end2end/SurfaceTests.cpp b/src/dawn/tests/end2end/SurfaceTests.cpp
index 7e1f9ee..51e3a37 100644
--- a/src/dawn/tests/end2end/SurfaceTests.cpp
+++ b/src/dawn/tests/end2end/SurfaceTests.cpp
@@ -47,12 +47,10 @@
 
 class SurfaceTests : public DawnTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
         // Just copy all the limits, though all we really care about is
         // maxStorageBuffersInFragmentStage
-        wgpu::RequiredLimits required = {};
-        required.limits = supported.limits;
-        return required;
+        return supported;
     }
 
   public:
@@ -625,7 +623,7 @@
 
 // Test using the surface as a storage texture when supported.
 TEST_P(SurfaceTests, Storage) {
-    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().limits.maxStorageBuffersInFragmentStage < 1);
+    DAWN_SUPPRESS_TEST_IF(GetSupportedLimits().maxStorageBuffersInFragmentStage < 1);
     wgpu::Surface surface = CreateTestSurface();
     wgpu::SurfaceCapabilities caps;
     surface.GetCapabilities(adapter, &caps);
diff --git a/src/dawn/tests/perf_tests/DrawCallPerf.cpp b/src/dawn/tests/perf_tests/DrawCallPerf.cpp
index f5f0a3c..03627aa 100644
--- a/src/dawn/tests/perf_tests/DrawCallPerf.cpp
+++ b/src/dawn/tests/perf_tests/DrawCallPerf.cpp
@@ -269,8 +269,7 @@
     DawnPerfTestWithParams::SetUp();
 
     // Compute aligned uniform / vertex data sizes.
-    mAlignedUniformSize =
-        Align(kUniformSize, GetSupportedLimits().limits.minUniformBufferOffsetAlignment);
+    mAlignedUniformSize = Align(kUniformSize, GetSupportedLimits().minUniformBufferOffsetAlignment);
     mAlignedVertexDataSize = Align(sizeof(kVertexData), 4);
 
     // Initialize uniform buffer data.
diff --git a/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp b/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp
index 73ad85f..dfba797 100644
--- a/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp
+++ b/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp
@@ -125,9 +125,9 @@
         return requirements;
     }
 
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
-        wgpu::RequiredLimits required = {};
-        required.limits.maxStorageBufferBindingSize =
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
+        wgpu::Limits required = {};
+        required.maxStorageBufferBindingSize =
             BytesPerElement() * GetParam().mRows * GetParam().mCols;
         return required;
     }
diff --git a/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp b/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp
index 6db82b1..356f53f 100644
--- a/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp
@@ -1065,7 +1065,7 @@
 
 // Tests constraints to be sure the uniform buffer binding isn't too large
 TEST_F(BindGroupValidationTest, MaxUniformBufferBindingSize) {
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     wgpu::BufferDescriptor descriptor;
     descriptor.size = 2 * supportedLimits.maxUniformBufferBindingSize;
@@ -1108,7 +1108,7 @@
 
 // Tests constraints to be sure the storage buffer binding isn't too large
 TEST_F(BindGroupValidationTest, MaxStorageBufferBindingSize) {
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     wgpu::BufferDescriptor descriptor;
     descriptor.size = 2 * supportedLimits.maxStorageBufferBindingSize;
@@ -1373,7 +1373,7 @@
         wgpu::BindGroupLayoutEntry otherEntry;
     };
 
-    wgpu::Limits limits = GetSupportedLimits().limits;
+    wgpu::Limits limits = GetSupportedLimits();
 
     std::array<TestInfo, 7> kTestInfos = {
         TestInfo{limits.maxSampledTexturesPerShaderStage,
@@ -1475,7 +1475,7 @@
         wgpu::BindGroupLayoutEntry otherEntry;
     };
 
-    wgpu::Limits limits = GetSupportedLimits().limits;
+    wgpu::Limits limits = GetSupportedLimits();
 
     std::array<TestInfo, 3> kTestInfos = {
         TestInfo{limits.maxSampledTexturesPerShaderStage, kSampledTexturesPerExternalTexture,
@@ -1565,7 +1565,7 @@
     std::vector<wgpu::BindGroupLayoutEntry> maxStorageDB;
     std::vector<wgpu::BindGroupLayoutEntry> maxReadonlyStorageDB;
 
-    wgpu::Limits limits = GetSupportedLimits().limits;
+    wgpu::Limits limits = GetSupportedLimits();
 
     // In this test, we use all the same shader stage. Ensure that this does not exceed the
     // per-stage limit.
@@ -2011,8 +2011,7 @@
                       wgpu::BufferBindingType::Storage, true},
                      {3, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                       wgpu::BufferBindingType::ReadOnlyStorage, true}});
-        mMinUniformBufferOffsetAlignment =
-            GetSupportedLimits().limits.minUniformBufferOffsetAlignment;
+        mMinUniformBufferOffsetAlignment = GetSupportedLimits().minUniformBufferOffsetAlignment;
         mBufferSize = 3 * mMinUniformBufferOffsetAlignment + 8;
     }
 
@@ -2713,7 +2712,7 @@
                     return vec4f();
                 })");
 
-        mBufferSize = 3 * GetSupportedLimits().limits.minUniformBufferOffsetAlignment + 8;
+        mBufferSize = 3 * GetSupportedLimits().minUniformBufferOffsetAlignment + 8;
     }
 
     wgpu::Buffer CreateBuffer(uint64_t bufferSize, wgpu::BufferUsage usage) {
@@ -3118,7 +3117,7 @@
   public:
     void SetUp() override {
         BindGroupLayoutCompatibilityTest::SetUp();
-        mBufferSize = 3 * GetSupportedLimits().limits.minUniformBufferOffsetAlignment + 8;
+        mBufferSize = 3 * GetSupportedLimits().minUniformBufferOffsetAlignment + 8;
     }
 
     void TestRenderPassBindings(const wgpu::BindGroup* bg,
diff --git a/src/dawn/tests/unittests/validation/BufferValidationTests.cpp b/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
index 67cffaf..0aea96d 100644
--- a/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
@@ -96,7 +96,7 @@
     // Success when at limit
     {
         wgpu::BufferDescriptor descriptor;
-        descriptor.size = GetSupportedLimits().limits.maxBufferSize;
+        descriptor.size = GetSupportedLimits().maxBufferSize;
         descriptor.usage = wgpu::BufferUsage::Uniform;
 
         device.CreateBuffer(&descriptor);
@@ -105,9 +105,8 @@
     // max possible limit given the adapters.)
     {
         wgpu::BufferDescriptor descriptor;
-        ASSERT_TRUE(GetSupportedLimits().limits.maxBufferSize <
-                    std::numeric_limits<uint32_t>::max());
-        descriptor.size = GetSupportedLimits().limits.maxBufferSize + 1;
+        ASSERT_TRUE(GetSupportedLimits().maxBufferSize < std::numeric_limits<uint32_t>::max());
+        descriptor.size = GetSupportedLimits().maxBufferSize + 1;
         descriptor.usage = wgpu::BufferUsage::Uniform;
 
         ASSERT_DEVICE_ERROR(device.CreateBuffer(&descriptor));
diff --git a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
index 4b3c0e3..447374b 100644
--- a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
@@ -355,10 +355,10 @@
 }
 
 TEST_F(CompatValidationTest, CanNotUseTooManyTextureSamplerCombos) {
-    wgpu::SupportedLimits limits;
+    wgpu::Limits limits;
     device.GetLimits(&limits);
-    uint32_t maxCombos = std::min(limits.limits.maxSampledTexturesPerShaderStage,
-                                  limits.limits.maxSamplersPerShaderStage);
+    uint32_t maxCombos =
+        std::min(limits.maxSampledTexturesPerShaderStage, limits.maxSamplersPerShaderStage);
 
     struct Test {
         bool expectSuccess;
@@ -395,7 +395,7 @@
     // clang-format on
     for (const auto& test : comboTests) {
         uint32_t maxTexturesPerShaderStage =
-            limits.limits.maxSampledTexturesPerShaderStage - (test.numExternalTextures * 3);
+            limits.maxSampledTexturesPerShaderStage - (test.numExternalTextures * 3);
         auto numCombos = test.numCombos;
         std::vector<std::string> textureDeclarations[2];
         std::vector<std::string> samplerDeclarations[2];
@@ -406,8 +406,8 @@
                 textureDeclarations[stage].push_back(
                     absl::StrFormat("@group(%u) @binding(%u) var t%u_%u: texture_2d<f32>;",
                                     stage * 2, t, stage, t));
-                for (uint32_t s = 0;
-                     count < numCombos && t < limits.limits.maxSamplersPerShaderStage; ++s) {
+                for (uint32_t s = 0; count < numCombos && t < limits.maxSamplersPerShaderStage;
+                     ++s) {
                     if (t == 0) {
                         samplerDeclarations[stage].push_back(
                             absl::StrFormat("@group(%u) @binding(%u) var s%u_%u: sampler;",
@@ -1866,10 +1866,10 @@
 class CompatMaxVertexAttributesTest : public CompatValidationTest {
   protected:
     void TestMaxVertexAttributes(bool usesVertexIndex, bool usesInstanceIndex) {
-        wgpu::SupportedLimits limits;
+        wgpu::Limits limits;
         device.GetLimits(&limits);
 
-        uint32_t maxAttributes = limits.limits.maxVertexAttributes;
+        uint32_t maxAttributes = limits.maxVertexAttributes;
         uint32_t numAttributesUsedByBuiltins =
             (usesVertexIndex ? 1 : 0) + (usesInstanceIndex ? 1 : 0);
 
@@ -1964,20 +1964,15 @@
 
 class CompatLayoutLimitsTests : public CompatValidationTest {
   protected:
-    wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits& supported) override {
-        wgpu::RequiredLimits required = {};
-        required.limits.maxStorageBuffersInFragmentStage =
-            supported.limits.maxStorageBuffersInFragmentStage / 2;
-        required.limits.maxStorageBuffersInVertexStage =
-            supported.limits.maxStorageBuffersInVertexStage / 2;
-        required.limits.maxStorageTexturesInFragmentStage =
-            supported.limits.maxStorageTexturesInFragmentStage / 2;
-        required.limits.maxStorageTexturesInVertexStage =
-            supported.limits.maxStorageTexturesInVertexStage / 2;
-        required.limits.maxStorageBuffersPerShaderStage =
-            supported.limits.maxStorageBuffersPerShaderStage;
-        required.limits.maxStorageTexturesPerShaderStage =
-            supported.limits.maxStorageTexturesPerShaderStage;
+    wgpu::Limits GetRequiredLimits(const wgpu::Limits& supported) override {
+        wgpu::Limits required = {};
+        required.maxStorageBuffersInFragmentStage = supported.maxStorageBuffersInFragmentStage / 2;
+        required.maxStorageBuffersInVertexStage = supported.maxStorageBuffersInVertexStage / 2;
+        required.maxStorageTexturesInFragmentStage =
+            supported.maxStorageTexturesInFragmentStage / 2;
+        required.maxStorageTexturesInVertexStage = supported.maxStorageTexturesInVertexStage / 2;
+        required.maxStorageBuffersPerShaderStage = supported.maxStorageBuffersPerShaderStage;
+        required.maxStorageTexturesPerShaderStage = supported.maxStorageTexturesPerShaderStage;
         return required;
     }
 
@@ -2037,7 +2032,7 @@
 // Test that in compat we get an error if we use more than maxStorageBuffersInFragmentStage
 // when it's lower than maxStorageBuffersPerShaderStage in createBindGroupLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageBuffersInFragmentStageBindGroupLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Fragment;
     entry.buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
@@ -2049,7 +2044,7 @@
 // Test that in compat we get an error if we use more than maxStorageBuffersInVertexStage
 // when it's lower than maxStorageBuffersPerShaderStage in createBindGroupLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageBuffersInVertexStageBindGroupLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Vertex;
     entry.buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
@@ -2061,7 +2056,7 @@
 // Test that in compat we get an error if we use more than maxStorageTexturesInFragmentStage
 // when it's lower than maxStorageTexturesPerShaderStage in createBindGroupLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageTexturesInFragmentStageBindGroupLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Fragment;
     entry.storageTexture.format = wgpu::TextureFormat::R32Float;
@@ -2074,7 +2069,7 @@
 // Test that in compat we get an error if we use more than maxStorageTexturesInVertexStage
 // when it's lower than maxStorageTexturesPerShaderStage in createBindGroupLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageTexturesInVertexStageBindGroupLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Vertex;
     entry.storageTexture.format = wgpu::TextureFormat::R32Float;
@@ -2087,7 +2082,7 @@
 // Test that in compat we get an error if we use more than maxStorageBuffersInFragmentStage
 // when it's lower than maxStorageBuffersPerShaderStage in createPipelineLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageBuffersInFragmentStagePipelineLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Fragment;
     entry.buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
@@ -2099,7 +2094,7 @@
 // Test that in compat we get an error if we use more than maxStorageBuffersInVertexStage
 // when it's lower than maxStorageBuffersPerShaderStage in createPipelineLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageBuffersInVertexStagePipelineLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Vertex;
     entry.buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
@@ -2111,7 +2106,7 @@
 // Test that in compat we get an error if we use more than maxStorageTexturesInFragmentStage
 // when it's lower than maxStorageTexturesPerShaderStage in createPipelineLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageTexturesInFragmentStagePipelineLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Fragment;
     entry.storageTexture.format = wgpu::TextureFormat::R32Float;
@@ -2124,7 +2119,7 @@
 // Test that in compat we get an error if we use more than maxStorageTexturesInVertexStage
 // when it's lower than maxStorageTexturesPerShaderStage in createPipelineLayout
 TEST_F(CompatLayoutLimitsTests, CanNotPassLimitOfStorageTexturesInVertexStagePipelineLayout) {
-    const auto limits = GetSupportedLimits().limits;
+    const auto limits = GetSupportedLimits();
     wgpu::BindGroupLayoutEntry entry;
     entry.visibility = wgpu::ShaderStage::Vertex;
     entry.storageTexture.format = wgpu::TextureFormat::R32Float;
diff --git a/src/dawn/tests/unittests/validation/ComputeValidationTests.cpp b/src/dawn/tests/unittests/validation/ComputeValidationTests.cpp
index bc54e0c..c5fbf21 100644
--- a/src/dawn/tests/unittests/validation/ComputeValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/ComputeValidationTests.cpp
@@ -109,31 +109,31 @@
 
 // Check that the largest allowed dispatch is OK.
 TEST_F(ComputeDispatchValidationTest, PerDimensionDispatchSizeLimits_LargestValid) {
-    const uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    const uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
     TestDispatch(max, max, max);
 }
 
 // Check that exceeding the maximum on the X dimension results in validation failure.
 TEST_F(ComputeDispatchValidationTest, PerDimensionDispatchSizeLimits_InvalidX) {
-    const uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    const uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
     ASSERT_DEVICE_ERROR(TestDispatch(max + 1, 1, 1));
 }
 
 // Check that exceeding the maximum on the Y dimension results in validation failure.
 TEST_F(ComputeDispatchValidationTest, PerDimensionDispatchSizeLimits_InvalidY) {
-    const uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    const uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
     ASSERT_DEVICE_ERROR(TestDispatch(1, max + 1, 1));
 }
 
 // Check that exceeding the maximum on the Z dimension results in validation failure.
 TEST_F(ComputeDispatchValidationTest, PerDimensionDispatchSizeLimits_InvalidZ) {
-    const uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    const uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
     ASSERT_DEVICE_ERROR(TestDispatch(1, 1, max + 1));
 }
 
 // Check that exceeding the maximum on all dimensions results in validation failure.
 TEST_F(ComputeDispatchValidationTest, PerDimensionDispatchSizeLimits_InvalidAll) {
-    const uint32_t max = GetSupportedLimits().limits.maxComputeWorkgroupsPerDimension;
+    const uint32_t max = GetSupportedLimits().maxComputeWorkgroupsPerDimension;
     ASSERT_DEVICE_ERROR(TestDispatch(max + 1, max + 1, max + 1));
 }
 
diff --git a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp
index 5f165f9..30d9943 100644
--- a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp
@@ -63,9 +63,9 @@
                 Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
         .WillOnce(WithArgs<1>([](wgpu::Device device) {
             // Check one of the default limits.
-            wgpu::SupportedLimits limits;
+            wgpu::Limits limits;
             device.GetLimits(&limits);
-            EXPECT_EQ(limits.limits.maxBindGroups, 4u);
+            EXPECT_EQ(limits.maxBindGroups, 4u);
         }));
     adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                           mRequestDeviceCallback.Callback());
@@ -73,7 +73,7 @@
 
 // Test that requesting a device with the default limits is valid.
 TEST_F(RequestDeviceValidationTest, DefaultLimits) {
-    wgpu::RequiredLimits limits = {};
+    wgpu::Limits limits = {};
     wgpu::DeviceDescriptor descriptor;
     descriptor.requiredLimits = &limits;
 
@@ -81,9 +81,9 @@
                 Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
         .WillOnce(WithArgs<1>([](wgpu::Device device) {
             // Check one of the default limits.
-            wgpu::SupportedLimits limits;
+            wgpu::Limits limits;
             device.GetLimits(&limits);
-            EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
+            EXPECT_EQ(limits.maxTextureArrayLayers, 256u);
         }));
     adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                           mRequestDeviceCallback.Callback());
@@ -91,49 +91,49 @@
 
 // Test that requesting a device where a required limit is above the maximum value.
 TEST_F(RequestDeviceValidationTest, HigherIsBetter) {
-    wgpu::RequiredLimits limits = {};
+    wgpu::Limits limits = {};
     wgpu::DeviceDescriptor descriptor;
     descriptor.requiredLimits = &limits;
 
-    wgpu::SupportedLimits supportedLimits;
+    wgpu::Limits supportedLimits;
     EXPECT_EQ(adapter.GetLimits(&supportedLimits), wgpu::Status::Success);
 
     // If we can support better than the default, test below the max.
-    if (supportedLimits.limits.maxBindGroups > 4u) {
-        limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups - 1;
+    if (supportedLimits.maxBindGroups > 4u) {
+        limits.maxBindGroups = supportedLimits.maxBindGroups - 1;
         EXPECT_CALL(mRequestDeviceCallback,
                     Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
             .WillOnce(WithArgs<1>([&](wgpu::Device device) {
-                wgpu::SupportedLimits limits;
+                wgpu::Limits limits;
                 device.GetLimits(&limits);
 
                 // Check we got exactly the request.
-                EXPECT_EQ(limits.limits.maxBindGroups, supportedLimits.limits.maxBindGroups - 1);
+                EXPECT_EQ(limits.maxBindGroups, supportedLimits.maxBindGroups - 1);
                 // Check another default limit.
-                EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
+                EXPECT_EQ(limits.maxTextureArrayLayers, 256u);
             }));
         adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                               mRequestDeviceCallback.Callback());
     }
 
     // Test the max.
-    limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups;
+    limits.maxBindGroups = supportedLimits.maxBindGroups;
     EXPECT_CALL(mRequestDeviceCallback,
                 Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
         .WillOnce(WithArgs<1>([&](wgpu::Device device) {
-            wgpu::SupportedLimits limits;
+            wgpu::Limits limits;
             device.GetLimits(&limits);
 
             // Check we got exactly the request.
-            EXPECT_EQ(limits.limits.maxBindGroups, supportedLimits.limits.maxBindGroups);
+            EXPECT_EQ(limits.maxBindGroups, supportedLimits.maxBindGroups);
             // Check another default limit.
-            EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
+            EXPECT_EQ(limits.maxTextureArrayLayers, 256u);
         }));
     adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                           mRequestDeviceCallback.Callback());
 
     // Test above the max.
-    limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups + 1;
+    limits.maxBindGroups = supportedLimits.maxBindGroups + 1;
     EXPECT_CALL(mRequestDeviceCallback,
                 Call(wgpu::RequestDeviceStatus::Error, IsNull(), NonEmptySizedString()))
         .Times(1);
@@ -141,15 +141,15 @@
                           mRequestDeviceCallback.Callback());
 
     // Test worse than the default
-    limits.limits.maxBindGroups = 3u;
+    limits.maxBindGroups = 3u;
     EXPECT_CALL(mRequestDeviceCallback,
                 Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
         .WillOnce(WithArgs<1>([&](wgpu::Device device) {
-            wgpu::SupportedLimits limits;
+            wgpu::Limits limits;
             device.GetLimits(&limits);
 
             // Check we got the default.
-            EXPECT_EQ(limits.limits.maxBindGroups, 4u);
+            EXPECT_EQ(limits.maxBindGroups, 4u);
         }));
     adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                           mRequestDeviceCallback.Callback());
@@ -157,16 +157,15 @@
 
 // Test that requesting a device where a required limit is below the minimum value.
 TEST_F(RequestDeviceValidationTest, LowerIsBetter) {
-    wgpu::RequiredLimits limits = {};
+    wgpu::Limits limits = {};
     wgpu::DeviceDescriptor descriptor;
     descriptor.requiredLimits = &limits;
 
-    wgpu::SupportedLimits supportedLimits;
+    wgpu::Limits supportedLimits;
     EXPECT_EQ(adapter.GetLimits(&supportedLimits), wgpu::Status::Success);
 
     // Test below the min.
-    limits.limits.minUniformBufferOffsetAlignment =
-        supportedLimits.limits.minUniformBufferOffsetAlignment / 2;
+    limits.minUniformBufferOffsetAlignment = supportedLimits.minUniformBufferOffsetAlignment / 2;
     EXPECT_CALL(mRequestDeviceCallback,
                 Call(wgpu::RequestDeviceStatus::Error, IsNull(), NonEmptySizedString()))
         .Times(1);
@@ -174,53 +173,52 @@
                           mRequestDeviceCallback.Callback());
 
     // Test the min.
-    limits.limits.minUniformBufferOffsetAlignment =
-        supportedLimits.limits.minUniformBufferOffsetAlignment;
+    limits.minUniformBufferOffsetAlignment = supportedLimits.minUniformBufferOffsetAlignment;
     EXPECT_CALL(mRequestDeviceCallback,
                 Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
         .WillOnce(WithArgs<1>([&](wgpu::Device device) {
-            wgpu::SupportedLimits limits;
+            wgpu::Limits limits;
             device.GetLimits(&limits);
 
             // Check we got exactly the request.
-            EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment,
-                      supportedLimits.limits.minUniformBufferOffsetAlignment);
+            EXPECT_EQ(limits.minUniformBufferOffsetAlignment,
+                      supportedLimits.minUniformBufferOffsetAlignment);
             // Check another default limit.
-            EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
+            EXPECT_EQ(limits.maxTextureArrayLayers, 256u);
         }));
     adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                           mRequestDeviceCallback.Callback());
 
     // IF we can support better than the default, test above the min.
-    if (supportedLimits.limits.minUniformBufferOffsetAlignment > 256u) {
-        limits.limits.minUniformBufferOffsetAlignment =
-            supportedLimits.limits.minUniformBufferOffsetAlignment * 2;
+    if (supportedLimits.minUniformBufferOffsetAlignment > 256u) {
+        limits.minUniformBufferOffsetAlignment =
+            supportedLimits.minUniformBufferOffsetAlignment * 2;
         EXPECT_CALL(mRequestDeviceCallback,
                     Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
             .WillOnce(WithArgs<1>([&](wgpu::Device device) {
-                wgpu::SupportedLimits limits;
+                wgpu::Limits limits;
                 device.GetLimits(&limits);
 
                 // Check we got exactly the request.
-                EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment,
-                          supportedLimits.limits.minUniformBufferOffsetAlignment * 2);
+                EXPECT_EQ(limits.minUniformBufferOffsetAlignment,
+                          supportedLimits.minUniformBufferOffsetAlignment * 2);
                 // Check another default limit.
-                EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
+                EXPECT_EQ(limits.maxTextureArrayLayers, 256u);
             }));
         adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                               mRequestDeviceCallback.Callback());
     }
 
     // Test worse than the default
-    limits.limits.minUniformBufferOffsetAlignment = 2u * 256u;
+    limits.minUniformBufferOffsetAlignment = 2u * 256u;
     EXPECT_CALL(mRequestDeviceCallback,
                 Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
         .WillOnce(WithArgs<1>([&](wgpu::Device device) {
-            wgpu::SupportedLimits limits;
+            wgpu::Limits limits;
             device.GetLimits(&limits);
 
             // Check we got the default.
-            EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment, 256u);
+            EXPECT_EQ(limits.minUniformBufferOffsetAlignment, 256u);
         }));
     adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
                           mRequestDeviceCallback.Callback());
@@ -228,9 +226,9 @@
 
 // Test that it is an error to request limits with an invalid chained struct
 TEST_F(RequestDeviceValidationTest, InvalidChainedStruct) {
-    wgpu::RenderPassMaxDrawCount maxDrawCount = {};
-    wgpu::RequiredLimits limits = {};
-    limits.nextInChain = &maxDrawCount;
+    wgpu::ChainedStructOut chain = {};
+    wgpu::Limits limits = {};
+    limits.nextInChain = &chain;
 
     wgpu::DeviceDescriptor descriptor;
     descriptor.requiredLimits = &limits;
diff --git a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
index db26d87..203a756 100644
--- a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
+++ b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
@@ -719,7 +719,7 @@
 
 // Test create external texture with too large apparent size results in error.
 TEST_F(ExternalTextureTest, CreateExternalTextureWithApparentSizeTooLarge) {
-    wgpu::SupportedLimits limits;
+    wgpu::Limits limits;
     device.GetLimits(&limits);
 
     // Control case should succeed.
@@ -731,8 +731,7 @@
         externalDesc.plane0 = texture.CreateView();
         externalDesc.cropOrigin = {0, 0};
         externalDesc.cropSize = {texture.GetWidth(), texture.GetHeight()};
-        externalDesc.apparentSize = {limits.limits.maxTextureDimension2D,
-                                     limits.limits.maxTextureDimension2D};
+        externalDesc.apparentSize = {limits.maxTextureDimension2D, limits.maxTextureDimension2D};
         device.CreateExternalTexture(&externalDesc);
     }
 
@@ -745,8 +744,8 @@
         externalDesc.plane0 = texture.CreateView();
         externalDesc.cropOrigin = {0, 0};
         externalDesc.cropSize = {texture.GetWidth(), texture.GetHeight()};
-        externalDesc.apparentSize = {limits.limits.maxTextureDimension2D + 1,
-                                     limits.limits.maxTextureDimension2D};
+        externalDesc.apparentSize = {limits.maxTextureDimension2D + 1,
+                                     limits.maxTextureDimension2D};
         ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
     }
 
@@ -759,8 +758,8 @@
         externalDesc.plane0 = texture.CreateView();
         externalDesc.cropOrigin = {0, 0};
         externalDesc.cropSize = {texture.GetWidth(), texture.GetHeight()};
-        externalDesc.apparentSize = {limits.limits.maxTextureDimension2D,
-                                     limits.limits.maxTextureDimension2D + 1};
+        externalDesc.apparentSize = {limits.maxTextureDimension2D,
+                                     limits.maxTextureDimension2D + 1};
         ASSERT_DEVICE_ERROR(device.CreateExternalTexture(&externalDesc));
     }
 }
diff --git a/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp b/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp
index f9bdefb..f710c67 100644
--- a/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp
+++ b/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp
@@ -61,7 +61,7 @@
         if (maxImmediateDataByteSize != std::numeric_limits<uint32_t>::max()) {
             return maxImmediateDataByteSize;
         }
-        wgpu::SupportedLimits supportedLimits = {};
+        wgpu::Limits supportedLimits = {};
         wgpu::DawnExperimentalImmediateDataLimits immediateDataLimits = {};
         supportedLimits.nextInChain = &immediateDataLimits;
         device.GetLimits(&supportedLimits);
diff --git a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
index 3cda8ca..de0462e 100644
--- a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
@@ -3009,10 +3009,10 @@
 // Test that rendering to multiple render targets while using dual source blending results in an
 // error.
 TEST_F(DualSourceBlendingFeatureTest, MultipleRenderTargetsNotAllowed) {
-    wgpu::SupportedLimits limits;
+    wgpu::Limits limits;
     device.GetLimits(&limits);
 
-    for (uint32_t location = 1; location < limits.limits.maxColorAttachments; location++) {
+    for (uint32_t location = 1; location < limits.maxColorAttachments; location++) {
         std::ostringstream sstream;
         sstream << R"(
                 enable dual_source_blending;
diff --git a/src/dawn/tests/unittests/validation/TextureValidationTests.cpp b/src/dawn/tests/unittests/validation/TextureValidationTests.cpp
index 265ae3c..0c8e400 100644
--- a/src/dawn/tests/unittests/validation/TextureValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/TextureValidationTests.cpp
@@ -319,7 +319,7 @@
 
     // Mip level equal to the maximum for a 2D texture is allowed
     {
-        uint32_t maxTextureDimension2D = GetSupportedLimits().limits.maxTextureDimension2D;
+        uint32_t maxTextureDimension2D = GetSupportedLimits().maxTextureDimension2D;
         wgpu::TextureDescriptor descriptor = defaultDescriptor;
         descriptor.size.width = maxTextureDimension2D;
         descriptor.size.height = maxTextureDimension2D;
@@ -330,7 +330,7 @@
 
     // Mip level exceeding the maximum for a 2D texture not allowed
     {
-        uint32_t maxTextureDimension2D = GetSupportedLimits().limits.maxTextureDimension2D;
+        uint32_t maxTextureDimension2D = GetSupportedLimits().maxTextureDimension2D;
         wgpu::TextureDescriptor descriptor = defaultDescriptor;
         descriptor.size.width = maxTextureDimension2D;
         descriptor.size.height = maxTextureDimension2D;
@@ -359,7 +359,7 @@
 // Test the validation of array layer count
 TEST_F(TextureValidationTest, ArrayLayerCount) {
     wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     // Array layer count exceeding maxTextureArrayLayers is not allowed for 2D texture
     {
@@ -386,7 +386,7 @@
 
 // Test the validation of 1D texture size
 TEST_F(TextureValidationTest, 1DTextureSize) {
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     wgpu::TextureDescriptor defaultDescriptor;
     defaultDescriptor.size = {4, 1, 1};
@@ -432,7 +432,7 @@
 // Test the validation of 2D texture size
 TEST_F(TextureValidationTest, 2DTextureSize) {
     wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     // Out-of-bound texture dimension is not allowed
     {
@@ -482,7 +482,7 @@
     wgpu::TextureDescriptor defaultDescriptor = CreateDefaultTextureDescriptor();
     defaultDescriptor.dimension = wgpu::TextureDimension::e3D;
     defaultDescriptor.usage = wgpu::TextureUsage::TextureBinding;
-    wgpu::Limits supportedLimits = GetSupportedLimits().limits;
+    wgpu::Limits supportedLimits = GetSupportedLimits();
 
     // Out-of-bound texture dimension is not allowed
     {
diff --git a/src/dawn/tests/unittests/validation/ValidationTest.cpp b/src/dawn/tests/unittests/validation/ValidationTest.cpp
index c6ff2fe..cde54bf 100644
--- a/src/dawn/tests/unittests/validation/ValidationTest.cpp
+++ b/src/dawn/tests/unittests/validation/ValidationTest.cpp
@@ -281,8 +281,8 @@
            }) != toggles.end();
 }
 
-wgpu::SupportedLimits ValidationTest::GetSupportedLimits() const {
-    wgpu::SupportedLimits supportedLimits = {};
+wgpu::Limits ValidationTest::GetSupportedLimits() const {
+    wgpu::Limits supportedLimits = {};
     device.GetLimits(&supportedLimits);
     return supportedLimits;
 }
@@ -295,7 +295,7 @@
     return {};
 }
 
-wgpu::RequiredLimits ValidationTest::GetRequiredLimits(const wgpu::SupportedLimits&) {
+wgpu::Limits ValidationTest::GetRequiredLimits(const wgpu::Limits&) {
     return {};
 }
 
@@ -416,10 +416,10 @@
     deviceDescriptor.requiredFeatures = requiredFeatures.data();
     deviceDescriptor.requiredFeatureCount = requiredFeatures.size();
 
-    wgpu::SupportedLimits supportedLimits;
-    dawn::native::GetProcs().adapterGetLimits(
-        mBackendAdapter.Get(), reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits));
-    wgpu::RequiredLimits requiredLimits = GetRequiredLimits(supportedLimits);
+    wgpu::Limits supportedLimits;
+    dawn::native::GetProcs().adapterGetLimits(mBackendAdapter.Get(),
+                                              reinterpret_cast<WGPULimits*>(&supportedLimits));
+    wgpu::Limits requiredLimits = GetRequiredLimits(supportedLimits);
     deviceDescriptor.requiredLimits = &requiredLimits;
 
     device = RequestDeviceSync(deviceDescriptor);
diff --git a/src/dawn/tests/unittests/validation/ValidationTest.h b/src/dawn/tests/unittests/validation/ValidationTest.h
index d90f5f7..c15e1fa 100644
--- a/src/dawn/tests/unittests/validation/ValidationTest.h
+++ b/src/dawn/tests/unittests/validation/ValidationTest.h
@@ -163,7 +163,7 @@
 
     const dawn::native::ToggleInfo* GetToggleInfo(const char* name) const;
     bool HasToggleEnabled(const char* toggle) const;
-    wgpu::SupportedLimits GetSupportedLimits() const;
+    wgpu::Limits GetSupportedLimits() const;
     dawn::utils::WireHelper* GetWireHelper() const;
 
   protected:
@@ -173,7 +173,7 @@
     // Override these appropriately for different tests.
     virtual bool AllowUnsafeAPIs();
     virtual std::vector<wgpu::FeatureName> GetRequiredFeatures();
-    virtual wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits&);
+    virtual wgpu::Limits GetRequiredLimits(const wgpu::Limits&);
     virtual std::vector<const char*> GetEnabledToggles();
     virtual std::vector<const char*> GetDisabledToggles();
 
diff --git a/src/dawn/tests/unittests/validation/VertexStateValidationTests.cpp b/src/dawn/tests/unittests/validation/VertexStateValidationTests.cpp
index 4a71bff..e25aee8 100644
--- a/src/dawn/tests/unittests/validation/VertexStateValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/VertexStateValidationTests.cpp
@@ -203,9 +203,9 @@
 
 // Check out of bounds condition on total number of vertex attributes
 TEST_F(VertexStateTest, SetVertexAttributesNumLimit) {
-    wgpu::SupportedLimits limits;
+    wgpu::Limits limits;
     device.GetLimits(&limits);
-    uint32_t maxVertexAttributes = limits.limits.maxVertexAttributes;
+    uint32_t maxVertexAttributes = limits.maxVertexAttributes;
 
     // Control case, setting max vertex attribute number
     utils::ComboVertexState state;
@@ -293,9 +293,9 @@
 
 // Check out of bounds condition on attribute shader location
 TEST_F(VertexStateTest, SetAttributeLocationOutOfBounds) {
-    wgpu::SupportedLimits limits;
+    wgpu::Limits limits;
     device.GetLimits(&limits);
-    uint32_t maxVertexAttributes = limits.limits.maxVertexAttributes;
+    uint32_t maxVertexAttributes = limits.maxVertexAttributes;
 
     // Control case, setting last attribute shader location
     utils::ComboVertexState state;
diff --git a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
index c15d309..b7d64da 100644
--- a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
@@ -149,9 +149,9 @@
 
 // Test that RequestDevice forwards the device information to the client.
 TEST_P(WireAdapterTests, RequestDeviceSuccess) {
-    wgpu::SupportedLimits fakeLimits = {};
-    fakeLimits.limits.maxTextureDimension1D = 433;
-    fakeLimits.limits.maxVertexAttributes = 1243;
+    wgpu::Limits fakeLimits = {};
+    fakeLimits.maxTextureDimension1D = 433;
+    fakeLimits.maxVertexAttributes = 1243;
 
     std::initializer_list<WGPUFeatureName> fakeFeaturesList = {
         WGPUFeatureName_Depth32FloatStencil8,
@@ -173,8 +173,8 @@
             EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, _)).Times(1);
 
             EXPECT_CALL(api, DeviceGetLimits(apiDevice, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
-                    *reinterpret_cast<wgpu::SupportedLimits*>(limits) = fakeLimits;
+                .WillOnce(WithArg<1>(Invoke([&](WGPULimits* limits) {
+                    *reinterpret_cast<wgpu::Limits*>(limits) = fakeLimits;
                     return WGPUStatus_Success;
                 })));
 
@@ -208,11 +208,10 @@
                 EXPECT_EQ(adapterInfo.device, kEmptyOutputStringView);
                 EXPECT_EQ(adapterInfo.description, kEmptyOutputStringView);
 
-                wgpu::SupportedLimits limits;
+                wgpu::Limits limits;
                 EXPECT_EQ(device.GetLimits(&limits), wgpu::Status::Success);
-                EXPECT_EQ(limits.limits.maxTextureDimension1D,
-                          fakeLimits.limits.maxTextureDimension1D);
-                EXPECT_EQ(limits.limits.maxVertexAttributes, fakeLimits.limits.maxVertexAttributes);
+                EXPECT_EQ(limits.maxTextureDimension1D, fakeLimits.maxTextureDimension1D);
+                EXPECT_EQ(limits.maxVertexAttributes, fakeLimits.maxVertexAttributes);
 
                 WGPUSupportedFeatures features = {};
                 device.GetFeatures(reinterpret_cast<wgpu::SupportedFeatures*>(&features));
diff --git a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
index e2dadea4..21c67d9 100644
--- a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
@@ -130,9 +130,9 @@
     fakeInfo.subgroupMinSize = 4;
     fakeInfo.subgroupMaxSize = 128;
 
-    wgpu::SupportedLimits fakeLimits = {};
-    fakeLimits.limits.maxTextureDimension1D = 433;
-    fakeLimits.limits.maxVertexAttributes = 1243;
+    wgpu::Limits fakeLimits = {};
+    fakeLimits.maxTextureDimension1D = 433;
+    fakeLimits.maxVertexAttributes = 1243;
 
     std::initializer_list<WGPUFeatureName> fakeFeaturesList = {
         WGPUFeatureName_Depth32FloatStencil8,
@@ -153,8 +153,8 @@
                 })));
 
             EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
-                    *reinterpret_cast<wgpu::SupportedLimits*>(limits) = fakeLimits;
+                .WillOnce(WithArg<1>(Invoke([&](WGPULimits* limits) {
+                    *reinterpret_cast<wgpu::Limits*>(limits) = fakeLimits;
                     return WGPUStatus_Success;
                 })));
 
@@ -191,11 +191,10 @@
                 EXPECT_EQ(info.subgroupMinSize, fakeInfo.subgroupMinSize);
                 EXPECT_EQ(info.subgroupMaxSize, fakeInfo.subgroupMaxSize);
 
-                wgpu::SupportedLimits limits = {};
+                wgpu::Limits limits = {};
                 EXPECT_EQ(adapter.GetLimits(&limits), wgpu::Status::Success);
-                EXPECT_EQ(limits.limits.maxTextureDimension1D,
-                          fakeLimits.limits.maxTextureDimension1D);
-                EXPECT_EQ(limits.limits.maxVertexAttributes, fakeLimits.limits.maxVertexAttributes);
+                EXPECT_EQ(limits.maxTextureDimension1D, fakeLimits.maxTextureDimension1D);
+                EXPECT_EQ(limits.maxVertexAttributes, fakeLimits.maxVertexAttributes);
 
                 WGPUSupportedFeatures features = {};
                 adapter.GetFeatures(reinterpret_cast<wgpu::SupportedFeatures*>(&features));
diff --git a/src/dawn/tests/unittests/wire/WireTest.cpp b/src/dawn/tests/unittests/wire/WireTest.cpp
index 5e75213..46782d8 100644
--- a/src/dawn/tests/unittests/wire/WireTest.cpp
+++ b/src/dawn/tests/unittests/wire/WireTest.cpp
@@ -113,7 +113,7 @@
             })));
 
         EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull()))
-            .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
+            .WillOnce(WithArg<1>(Invoke([&](WGPULimits* limits) {
                 *limits = {};
                 return WGPUStatus_Success;
             })));
@@ -160,7 +160,7 @@
             object->mUncapturedErrorUserdata2 = desc->uncapturedErrorCallbackInfo.userdata2;
 
             EXPECT_CALL(api, DeviceGetLimits(apiDevice, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
+                .WillOnce(WithArg<1>(Invoke([&](WGPULimits* limits) {
                     *limits = {};
                     return WGPUStatus_Success;
                 })));
diff --git a/src/dawn/wire/client/Adapter.cpp b/src/dawn/wire/client/Adapter.cpp
index dfd0125..afac972 100644
--- a/src/dawn/wire/client/Adapter.cpp
+++ b/src/dawn/wire/client/Adapter.cpp
@@ -57,7 +57,7 @@
     WireResult ReadyHook(FutureID futureID,
                          WGPURequestDeviceStatus status,
                          WGPUStringView message,
-                         const WGPUSupportedLimits* limits,
+                         const WGPULimits* limits,
                          uint32_t featuresCount,
                          const WGPUFeatureName* features) {
         DAWN_ASSERT(mDevice != nullptr);
@@ -124,7 +124,7 @@
     return ObjectType::Adapter;
 }
 
-WGPUStatus Adapter::GetLimits(WGPUSupportedLimits* limits) const {
+WGPUStatus Adapter::GetLimits(WGPULimits* limits) const {
     return mLimitsAndFeatures.GetLimits(limits);
 }
 
@@ -136,7 +136,7 @@
     mLimitsAndFeatures.ToSupportedFeatures(features);
 }
 
-void Adapter::SetLimits(const WGPUSupportedLimits* limits) {
+void Adapter::SetLimits(const WGPULimits* limits) {
     return mLimitsAndFeatures.SetLimits(limits);
 }
 
@@ -321,7 +321,7 @@
                                                   WGPUFuture future,
                                                   WGPURequestDeviceStatus status,
                                                   WGPUStringView message,
-                                                  const WGPUSupportedLimits* limits,
+                                                  const WGPULimits* limits,
                                                   uint32_t featuresCount,
                                                   const WGPUFeatureName* features) {
     return GetEventManager(eventManager)
diff --git a/src/dawn/wire/client/Adapter.h b/src/dawn/wire/client/Adapter.h
index c6e8d25..66bfa85 100644
--- a/src/dawn/wire/client/Adapter.h
+++ b/src/dawn/wire/client/Adapter.h
@@ -45,9 +45,9 @@
 
     ObjectType GetObjectType() const override;
 
-    WGPUStatus GetLimits(WGPUSupportedLimits* limits) const;
+    WGPUStatus GetLimits(WGPULimits* limits) const;
     bool HasFeature(WGPUFeatureName feature) const;
-    void SetLimits(const WGPUSupportedLimits* limits);
+    void SetLimits(const WGPULimits* limits);
     void SetFeatures(const WGPUFeatureName* features, uint32_t featuresCount);
     void SetInfo(const WGPUAdapterInfo* info);
     WGPUStatus GetInfo(WGPUAdapterInfo* info) const;
diff --git a/src/dawn/wire/client/Device.cpp b/src/dawn/wire/client/Device.cpp
index d832503..09e344d 100644
--- a/src/dawn/wire/client/Device.cpp
+++ b/src/dawn/wire/client/Device.cpp
@@ -285,7 +285,7 @@
     Unregister();
 }
 
-WGPUStatus Device::GetLimits(WGPUSupportedLimits* limits) const {
+WGPUStatus Device::GetLimits(WGPULimits* limits) const {
     return mLimitsAndFeatures.GetLimits(limits);
 }
 
@@ -301,7 +301,7 @@
     return mAdapter->GetInfo(adapterInfo);
 }
 
-void Device::SetLimits(const WGPUSupportedLimits* limits) {
+void Device::SetLimits(const WGPULimits* limits) {
     return mLimitsAndFeatures.SetLimits(limits);
 }
 
diff --git a/src/dawn/wire/client/Device.h b/src/dawn/wire/client/Device.h
index 53aafeb..dd68014 100644
--- a/src/dawn/wire/client/Device.h
+++ b/src/dawn/wire/client/Device.h
@@ -54,7 +54,7 @@
 
     ObjectType GetObjectType() const override;
 
-    void SetLimits(const WGPUSupportedLimits* limits);
+    void SetLimits(const WGPULimits* limits);
     void SetFeatures(const WGPUFeatureName* features, uint32_t featuresCount);
 
     bool IsAlive() const;
@@ -78,7 +78,7 @@
         WGPURenderPipelineDescriptor const* descriptor,
         const WGPUCreateRenderPipelineAsyncCallbackInfo& callbackInfo);
 
-    WGPUStatus GetLimits(WGPUSupportedLimits* limits) const;
+    WGPUStatus GetLimits(WGPULimits* limits) const;
     WGPUFuture GetLostFuture();
     bool HasFeature(WGPUFeatureName feature) const;
     void GetFeatures(WGPUSupportedFeatures* features) const;
diff --git a/src/dawn/wire/client/Instance.cpp b/src/dawn/wire/client/Instance.cpp
index e4218fb..c3d80f8 100644
--- a/src/dawn/wire/client/Instance.cpp
+++ b/src/dawn/wire/client/Instance.cpp
@@ -62,7 +62,7 @@
                          WGPURequestAdapterStatus status,
                          WGPUStringView message,
                          const WGPUAdapterInfo* info,
-                         const WGPUSupportedLimits* limits,
+                         const WGPULimits* limits,
                          uint32_t featuresCount,
                          const WGPUFeatureName* features) {
         DAWN_ASSERT(mAdapter != nullptr);
@@ -203,7 +203,7 @@
                                                     WGPURequestAdapterStatus status,
                                                     WGPUStringView message,
                                                     const WGPUAdapterInfo* info,
-                                                    const WGPUSupportedLimits* limits,
+                                                    const WGPULimits* limits,
                                                     uint32_t featuresCount,
                                                     const WGPUFeatureName* features) {
     return GetEventManager(eventManager)
diff --git a/src/dawn/wire/client/LimitsAndFeatures.cpp b/src/dawn/wire/client/LimitsAndFeatures.cpp
index 7cfb19d..eb30dad 100644
--- a/src/dawn/wire/client/LimitsAndFeatures.cpp
+++ b/src/dawn/wire/client/LimitsAndFeatures.cpp
@@ -36,7 +36,7 @@
 
 LimitsAndFeatures::~LimitsAndFeatures() = default;
 
-WGPUStatus LimitsAndFeatures::GetLimits(WGPUSupportedLimits* limits) const {
+WGPUStatus LimitsAndFeatures::GetLimits(WGPULimits* limits) const {
     DAWN_ASSERT(limits != nullptr);
     auto* originalNextInChain = limits->nextInChain;
     *limits = mLimits;
@@ -104,7 +104,7 @@
     supportedFeatures->features = features;
 }
 
-void LimitsAndFeatures::SetLimits(const WGPUSupportedLimits* limits) {
+void LimitsAndFeatures::SetLimits(const WGPULimits* limits) {
     DAWN_ASSERT(limits != nullptr);
     mLimits = *limits;
     mLimits.nextInChain = nullptr;
diff --git a/src/dawn/wire/client/LimitsAndFeatures.h b/src/dawn/wire/client/LimitsAndFeatures.h
index 69ee5e8..e454a41 100644
--- a/src/dawn/wire/client/LimitsAndFeatures.h
+++ b/src/dawn/wire/client/LimitsAndFeatures.h
@@ -39,15 +39,15 @@
     LimitsAndFeatures();
     ~LimitsAndFeatures();
 
-    WGPUStatus GetLimits(WGPUSupportedLimits* limits) const;
+    WGPUStatus GetLimits(WGPULimits* limits) const;
     bool HasFeature(WGPUFeatureName feature) const;
     void ToSupportedFeatures(WGPUSupportedFeatures* supportedFeatures) const;
 
-    void SetLimits(const WGPUSupportedLimits* limits);
+    void SetLimits(const WGPULimits* limits);
     void SetFeatures(const WGPUFeatureName* features, uint32_t featuresCount);
 
   private:
-    WGPUSupportedLimits mLimits;
+    WGPULimits mLimits;
     WGPUDawnExperimentalSubgroupLimits mExperimentalSubgroupLimits;
     WGPUDawnExperimentalImmediateDataLimits mExperimentalImmediateDataLimits;
     WGPUDawnTexelCopyBufferRowAlignmentLimits mTexelCopyBufferRowAlignmentLimits;
diff --git a/src/dawn/wire/server/ServerAdapter.cpp b/src/dawn/wire/server/ServerAdapter.cpp
index a49c29a..a4d8c36 100644
--- a/src/dawn/wire/server/ServerAdapter.cpp
+++ b/src/dawn/wire/server/ServerAdapter.cpp
@@ -117,7 +117,7 @@
     // Query and report the adapter limits, including DawnExperimentalSubgroupLimits,
     // DawnExperimentalImmediateDataLimits and DawnTexelCopyBufferRowAlignmentLimits.
     // Reporting to client.
-    WGPUSupportedLimits limits = {};
+    WGPULimits limits = {};
 
     // Chained DawnExperimentalSubgroupLimits.
     // TODO(crbug.com/354751907) Remove this, as it is now in AdapterInfo.
diff --git a/src/dawn/wire/server/ServerInstance.cpp b/src/dawn/wire/server/ServerInstance.cpp
index 225310c..60ad8ec 100644
--- a/src/dawn/wire/server/ServerInstance.cpp
+++ b/src/dawn/wire/server/ServerInstance.cpp
@@ -135,7 +135,7 @@
 
     // Query and report the adapter limits, including DawnExperimentalSubgroupLimits,
     // DawnExperimentalImmediateDataLimits, and DawnTexelCopyBufferRowAlignmentLimits.
-    WGPUSupportedLimits limits = {};
+    WGPULimits limits = {};
 
     // TODO(crbug.com/354751907) Remove this, as it is now in AdapterInfo.
     WGPUDawnExperimentalSubgroupLimits experimentalSubgroupLimits = {};
diff --git a/third_party/emdawnwebgpu/library_webgpu.js b/third_party/emdawnwebgpu/library_webgpu.js
index eed1924..f722193 100644
--- a/third_party/emdawnwebgpu/library_webgpu.js
+++ b/third_party/emdawnwebgpu/library_webgpu.js
@@ -515,8 +515,8 @@
       return desc;
     },
 
-    fillLimitStruct: (limits, supportedLimitsOutPtr) => {
-      var limitsOutPtr = supportedLimitsOutPtr + {{{ C_STRUCTS.WGPUSupportedLimits.limits }}};
+    fillLimitStruct: (limits, limitsOutPtr) => {
+      {{{ gpu.makeCheckDescriptor('limitsOutPtr') }}}
 
       function setLimitValueU32(name, limitOffset) {
         var limitValue = limits[name];
@@ -748,10 +748,9 @@
         desc["requiredFeatures"] = Array.from({{{ makeHEAPView('U32', 'requiredFeaturesPtr', `requiredFeaturesPtr + requiredFeatureCount * 4`) }}},
           (feature) => WebGPU.FeatureName[feature]);
       }
-      var requiredLimitsPtr = {{{ makeGetValue('descriptor', C_STRUCTS.WGPUDeviceDescriptor.requiredLimits, '*') }}};
-      if (requiredLimitsPtr) {
-        {{{ gpu.makeCheckDescriptor('requiredLimitsPtr') }}}
-        var limitsPtr = requiredLimitsPtr + {{{ C_STRUCTS.WGPURequiredLimits.limits }}};
+      var limitsPtr = {{{ makeGetValue('descriptor', C_STRUCTS.WGPUDeviceDescriptor.requiredLimits, '*') }}};
+      if (limitsPtr) {
+        {{{ gpu.makeCheckDescriptor('limitsPtr') }}}
         var requiredLimits = {};
         function setLimitU32IfDefined(name, limitOffset) {
           var ptr = limitsPtr + limitOffset;
diff --git a/tools/android/BUILD.gn b/tools/android/BUILD.gn
index d2efcba..4ac723a 100644
--- a/tools/android/BUILD.gn
+++ b/tools/android/BUILD.gn
@@ -161,7 +161,6 @@
     "java/android/dawn/RequestDeviceCallback.kt",
     "java/android/dawn/RequestDeviceCallbackInfo.kt",
     "java/android/dawn/RequestDeviceStatus.kt",
-    "java/android/dawn/RequiredLimits.kt",
     "java/android/dawn/SType.kt",
     "java/android/dawn/Sampler.kt",
     "java/android/dawn/SamplerBindingLayout.kt",
@@ -180,7 +179,6 @@
     "java/android/dawn/StoreOp.kt",
     "java/android/dawn/SubgroupMatrixComponentType.kt",
     "java/android/dawn/SupportedFeatures.kt",
-    "java/android/dawn/SupportedLimits.kt",
     "java/android/dawn/SupportedWGSLLanguageFeatures.kt",
     "java/android/dawn/Surface.kt",
     "java/android/dawn/SurfaceCapabilities.kt",