Only allow CompareFunction::Undefined for samplerDesc.compare

The various backends hit UNREACHABLE() during pipeline creation if
depthStencil.depthCompare (or likewise for stencil) are set to
undefined.

Bug: chromium:1195694
Change-Id: Ibf4d8d47b4c98343dce3caccdf79ee90c0de899f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/46863
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/dawn.json b/dawn.json
index 9eecdf6..6bc4c37 100644
--- a/dawn.json
+++ b/dawn.json
@@ -490,7 +490,7 @@
     "compare function": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 0, "name": "undefined", "jsrepr": "undefined", "valid": false},
             {"value": 1, "name": "never"},
             {"value": 2, "name": "less"},
             {"value": 3, "name": "less equal"},
diff --git a/src/dawn_native/Sampler.cpp b/src/dawn_native/Sampler.cpp
index a2dcaab..51db080 100644
--- a/src/dawn_native/Sampler.cpp
+++ b/src/dawn_native/Sampler.cpp
@@ -58,7 +58,14 @@
         DAWN_TRY(ValidateAddressMode(descriptor->addressModeU));
         DAWN_TRY(ValidateAddressMode(descriptor->addressModeV));
         DAWN_TRY(ValidateAddressMode(descriptor->addressModeW));
-        DAWN_TRY(ValidateCompareFunction(descriptor->compare));
+
+        // CompareFunction::Undefined is tagged as invalid because it can't be used, except for the
+        // SamplerDescriptor where it is a special value that means the sampler is not a
+        // comparison-sampler.
+        if (descriptor->compare != wgpu::CompareFunction::Undefined) {
+            DAWN_TRY(ValidateCompareFunction(descriptor->compare));
+        }
+
         return {};
     }
 
diff --git a/src/tests/unittests/validation/RenderPipelineValidationTests.cpp b/src/tests/unittests/validation/RenderPipelineValidationTests.cpp
index 4dea0c7..8a8643d 100644
--- a/src/tests/unittests/validation/RenderPipelineValidationTests.cpp
+++ b/src/tests/unittests/validation/RenderPipelineValidationTests.cpp
@@ -572,6 +572,22 @@
     }
 }
 
+// Test that depthStencil.depthCompare must not be undefiend.
+TEST_F(RenderPipelineValidationTest, DepthCompareUndefinedIsError) {
+    utils::ComboRenderPipelineDescriptor2 descriptor;
+    descriptor.vertex.module = vsModule;
+    descriptor.cFragment.module = fsModule;
+    descriptor.EnableDepthStencil(wgpu::TextureFormat::Depth32Float);
+
+    // Control case: Always is valid.
+    descriptor.cDepthStencil.depthCompare = wgpu::CompareFunction::Always;
+    device.CreateRenderPipeline2(&descriptor);
+
+    // Error case: Undefined is invalid.
+    descriptor.cDepthStencil.depthCompare = wgpu::CompareFunction::Undefined;
+    ASSERT_DEVICE_ERROR(device.CreateRenderPipeline2(&descriptor));
+}
+
 // Test that the entryPoint names must be present for the correct stage in the shader module.
 TEST_F(RenderPipelineValidationTest, EntryPointNameValidation) {
     wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(