Add constant maxBindGroupsPlusVertexBuffers

Bug: dawn:1849, dawn:1675
Change-Id: Iaa8e612ecf6faa15a00a6756cf3a96aa36a63dbe
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/138480
Commit-Queue: Yunchao He <yunchao.he@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/dawn.json b/dawn.json
index 926dea5..617bd66 100644
--- a/dawn.json
+++ b/dawn.json
@@ -1282,6 +1282,7 @@
             {"name": "max texture dimension 3D", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max texture array layers", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max bind groups", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
+            {"name": "max bind groups plus vertex buffers", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max bindings per bind group", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max dynamic uniform buffers per pipeline layout", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
             {"name": "max dynamic storage buffers per pipeline layout", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
diff --git a/src/dawn/common/Constants.h b/src/dawn/common/Constants.h
index 1836ed3..4a46586 100644
--- a/src/dawn/common/Constants.h
+++ b/src/dawn/common/Constants.h
@@ -25,6 +25,7 @@
 static constexpr uint8_t kMaxVertexAttributes = 16u;
 static constexpr uint8_t kMaxVertexBuffers = 8u;
 static constexpr uint32_t kMaxVertexBufferArrayStride = 2048u;
+static constexpr uint32_t kMaxBindGroupsPlusVertexBuffers = 24u;
 static constexpr uint32_t kNumStages = 3;
 static constexpr uint8_t kMaxColorAttachments = 8u;
 static constexpr uint32_t kTextureBytesPerRowAlignment = 256u;
diff --git a/src/dawn/native/CommandBufferStateTracker.cpp b/src/dawn/native/CommandBufferStateTracker.cpp
index 099c0b8..eae1916 100644
--- a/src/dawn/native/CommandBufferStateTracker.cpp
+++ b/src/dawn/native/CommandBufferStateTracker.cpp
@@ -495,6 +495,9 @@
 
     DAWN_TRY(CheckMissingAspects(requiredAspects & ~mAspects));
 
+    // Validation for kMaxBindGroupsPlusVertexBuffers is skipped because it is not necessary so far.
+    static_assert(kMaxBindGroups + kMaxVertexBuffers <= kMaxBindGroupsPlusVertexBuffers);
+
     return {};
 }
 
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index b1f1496..7400af1 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -1734,6 +1734,10 @@
     DAWN_TRY(ValidateIsAlive());
     if (IsValidationEnabled()) {
         DAWN_TRY(ValidateRenderPipelineDescriptor(this, descriptor));
+
+        // Validation for kMaxBindGroupsPlusVertexBuffers is skipped because it is not necessary so
+        // far.
+        static_assert(kMaxBindGroups + kMaxVertexBuffers <= kMaxBindGroupsPlusVertexBuffers);
     }
 
     // Ref will keep the pipeline layout alive until the end of the function where
diff --git a/src/dawn/native/Limits.cpp b/src/dawn/native/Limits.cpp
index 6f73a68..fcf129e 100644
--- a/src/dawn/native/Limits.cpp
+++ b/src/dawn/native/Limits.cpp
@@ -66,6 +66,7 @@
     X(Maximum,                       maxTextureDimension3D,      2048,       2048) \
     X(Maximum,                       maxTextureArrayLayers,       256,        256) \
     X(Maximum,                               maxBindGroups,         4,          4) \
+    X(Maximum,              maxBindGroupsPlusVertexBuffers,        24,         24) \
     X(Maximum,                     maxBindingsPerBindGroup,      1000,       1000) \
     X(Maximum,                 maxUniformBufferBindingSize,     65536,      65536) \
     X(Alignment,           minUniformBufferOffsetAlignment,       256,        256) \
@@ -277,6 +278,8 @@
     limits->maxColorAttachments =
         std::min(limits->maxColorAttachments, uint32_t(kMaxColorAttachments));
     limits->maxBindGroups = std::min(limits->maxBindGroups, kMaxBindGroups);
+    limits->maxBindGroupsPlusVertexBuffers =
+        std::min(limits->maxBindGroupsPlusVertexBuffers, kMaxBindGroupsPlusVertexBuffers);
     limits->maxVertexAttributes =
         std::min(limits->maxVertexAttributes, uint32_t(kMaxVertexAttributes));
     limits->maxVertexBuffers = std::min(limits->maxVertexBuffers, uint32_t(kMaxVertexBuffers));
diff --git a/src/dawn/tests/unittests/LimitsTests.cpp b/src/dawn/tests/unittests/LimitsTests.cpp
index 4515a88..61c3804 100644
--- a/src/dawn/tests/unittests/LimitsTests.cpp
+++ b/src/dawn/tests/unittests/LimitsTests.cpp
@@ -312,6 +312,7 @@
         limits.maxVertexBufferArrayStride = kMaxVertexBufferArrayStride + 1;
         limits.maxColorAttachments = uint32_t(kMaxColorAttachments) + 1;
         limits.maxBindGroups = kMaxBindGroups + 1;
+        limits.maxBindGroupsPlusVertexBuffers = kMaxBindGroupsPlusVertexBuffers + 1;
         limits.maxVertexAttributes = uint32_t(kMaxVertexAttributes) + 1;
         limits.maxVertexBuffers = uint32_t(kMaxVertexBuffers) + 1;
         limits.maxInterStageShaderComponents = kMaxInterStageShaderComponents + 1;
@@ -326,6 +327,7 @@
         EXPECT_EQ(limits.maxVertexBufferArrayStride, kMaxVertexBufferArrayStride);
         EXPECT_EQ(limits.maxColorAttachments, uint32_t(kMaxColorAttachments));
         EXPECT_EQ(limits.maxBindGroups, kMaxBindGroups);
+        EXPECT_EQ(limits.maxBindGroupsPlusVertexBuffers, kMaxBindGroupsPlusVertexBuffers);
         EXPECT_EQ(limits.maxVertexAttributes, uint32_t(kMaxVertexAttributes));
         EXPECT_EQ(limits.maxVertexBuffers, uint32_t(kMaxVertexBuffers));
         EXPECT_EQ(limits.maxInterStageShaderComponents, kMaxInterStageShaderComponents);