Print all builtins in the error message of inter-stage shader variables

This patch adds all the used built-in variables in the error message
of the violation of maximum inter-stage shader variables. With this
patch the error messages will be as below:

- Total vertex output variables count (17 = 17 (user-defined)) exceeds
  the maximum (16).
- Total vertex output variables count (17 = 15 (user-defined) + 2
  (clip_distances)) exceeds the maximum (16).
- Total fragment input variables count (17 = 17 (user-defined)) exceeds
  the maximum (16).
- Total fragment input variables count (17 = 16 (user-defined) + 1
  (front_facing) exceeds the maximum (16).
- Total fragment input variables count (17 = 16 (user-defined) + 1
  (front_facing|sample_mask) exceeds the maximum (16).
- Total fragment input variables count (17 = 16 (user-defined) + 1
  (front_facing|sample_mask|sample_index) exceeds the maximum (16).

Bug: 364338810
Test: dawn_unittests
Change-Id: I0a0ad7fe1bfb13b3a8ff11f4d707f45b167dcba8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/206034
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Gregg Tavares <gman@google.com>
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 144a79e..73aa23e 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -729,10 +729,22 @@
             metadata->totalInterStageShaderVariables +=
                 RoundUp(*entryPoint.clip_distances_size, 4) / 4;
         }
-        // TODO(chromium:364338810): Print out the usage of built-in variables in the error message
-        DelayedInvalidIf(metadata->totalInterStageShaderVariables > maxInterStageShaderVariables,
-                         "Total vertex output variables count (%u) exceeds the maximum (%u).",
-                         metadata->totalInterStageShaderVariables, maxInterStageShaderVariables);
+
+        if (metadata->totalInterStageShaderVariables > maxInterStageShaderVariables) {
+            size_t userDefinedOutputVariables = entryPoint.output_variables.size();
+
+            std::ostringstream builtinInfo;
+            if (entryPoint.clip_distances_size.has_value()) {
+                builtinInfo << " + " << RoundUp(*entryPoint.clip_distances_size, 4) / 4
+                            << " (clip_distances)";
+            }
+
+            metadata->infringedLimitErrors.push_back(absl::StrFormat(
+                "Total vertex output variables count (%u = %u (user-defined)%s) exceeds the "
+                "maximum (%u).",
+                metadata->totalInterStageShaderVariables, userDefinedOutputVariables,
+                builtinInfo.str(), maxInterStageShaderVariables));
+        }
 
         metadata->usesVertexIndex = entryPoint.vertex_index_used;
         metadata->usesInstanceIndex = entryPoint.instance_index_used;
@@ -784,10 +796,39 @@
         metadata->usesFragDepth = entryPoint.frag_depth_used;
 
         metadata->totalInterStageShaderVariables = totalInterStageShaderVariables;
-        // TODO(chromium:364338810): Print out the usage of built-in variables in the error message
-        DelayedInvalidIf(totalInterStageShaderVariables > maxInterStageShaderVariables,
-                         "Total fragment input variables count (%u) exceeds the maximum (%u).",
-                         totalInterStageShaderVariables, maxInterStageShaderVariables);
+        if (metadata->totalInterStageShaderVariables > maxInterStageShaderVariables) {
+            size_t userDefinedInputVariables = entryPoint.input_variables.size();
+
+            std::ostringstream builtinInfo;
+            if (metadata->totalInterStageShaderVariables > userDefinedInputVariables) {
+                builtinInfo << " + 1 (";
+                bool isFirst = true;
+                if (entryPoint.front_facing_used) {
+                    builtinInfo << "front_facing";
+                    isFirst = false;
+                }
+                if (entryPoint.input_sample_mask_used) {
+                    if (!isFirst) {
+                        builtinInfo << "|";
+                    }
+                    builtinInfo << "sample_mask";
+                    isFirst = false;
+                }
+                if (entryPoint.sample_index_used) {
+                    if (!isFirst) {
+                        builtinInfo << "|";
+                    }
+                    builtinInfo << "sample_index";
+                    isFirst = false;
+                }
+            }
+
+            metadata->infringedLimitErrors.push_back(absl::StrFormat(
+                "Total fragment input variables count (%u = %u (user-defined)%s) exceeds the "
+                "maximum (%u).",
+                metadata->totalInterStageShaderVariables, userDefinedInputVariables,
+                builtinInfo.str(), maxInterStageShaderVariables));
+        }
 
         // Fragment output reflection.
         uint32_t maxColorAttachments = limits.v1.maxColorAttachments;