Allow BlendOperation::Min/Max with BlendFactor::Undefined

Bug: dawn:2475
Change-Id: Ia17bd48202af5c7a3543fb5513ba27f28da05619
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/183280
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index 44e29c9..2236fa6 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -393,10 +393,15 @@
 
     if (blendComponent.operation == wgpu::BlendOperation::Min ||
         blendComponent.operation == wgpu::BlendOperation::Max) {
-        DAWN_INVALID_IF(blendComponent.srcFactor != wgpu::BlendFactor::One ||
-                            blendComponent.dstFactor != wgpu::BlendFactor::One,
-                        "Blend factor is not %s when blend operation is %s.",
-                        wgpu::BlendFactor::One, blendComponent.operation);
+        DAWN_INVALID_IF((blendComponent.srcFactor != wgpu::BlendFactor::One) &&
+                            (blendComponent.srcFactor != wgpu::BlendFactor::Undefined),
+                        "Source blend factor (%s) is defined not %s when blend operation is %s.",
+                        blendComponent.srcFactor, wgpu::BlendFactor::One, blendComponent.operation);
+        DAWN_INVALID_IF(
+            (blendComponent.dstFactor != wgpu::BlendFactor::One) &&
+                (blendComponent.dstFactor != wgpu::BlendFactor::Undefined),
+            "Destination blend factor (%s) is defined not %s when blend operation is %s.",
+            blendComponent.dstFactor, wgpu::BlendFactor::One, blendComponent.operation);
     }
 
     return {};
diff --git a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
index fb77ea8..4d67aac 100644
--- a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
@@ -568,7 +568,8 @@
 // Tests that when blendOperationMinOrMax is "min" or "max", both srcBlendFactor and dstBlendFactor
 // must be "one".
 TEST_F(RenderPipelineValidationTest, BlendOperationAndBlendFactors) {
-    constexpr std::array<wgpu::BlendFactor, 8> kBlendFactors = {wgpu::BlendFactor::Zero,
+    constexpr std::array<wgpu::BlendFactor, 9> kBlendFactors = {wgpu::BlendFactor::Undefined,
+                                                                wgpu::BlendFactor::Zero,
                                                                 wgpu::BlendFactor::One,
                                                                 wgpu::BlendFactor::SrcAlpha,
                                                                 wgpu::BlendFactor::OneMinusSrcAlpha,
@@ -595,7 +596,13 @@
 
                 descriptor.cBlends[0].color.operation = blendOperationMinOrMax;
                 descriptor.cBlends[0].alpha.operation = wgpu::BlendOperation::Add;
-                if (srcFactor == wgpu::BlendFactor::One && dstFactor == wgpu::BlendFactor::One) {
+
+                bool srcIsOne = srcFactor == wgpu::BlendFactor::One ||
+                                srcFactor == wgpu::BlendFactor::Undefined;
+                bool dstIsOne = dstFactor == wgpu::BlendFactor::One ||
+                                dstFactor == wgpu::BlendFactor::Undefined;
+
+                if (srcIsOne && dstIsOne) {
                     device.CreateRenderPipeline(&descriptor);
                 } else {
                     ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
@@ -603,7 +610,7 @@
 
                 descriptor.cBlends[0].color.operation = wgpu::BlendOperation::Add;
                 descriptor.cBlends[0].alpha.operation = blendOperationMinOrMax;
-                if (srcFactor == wgpu::BlendFactor::One && dstFactor == wgpu::BlendFactor::One) {
+                if (srcIsOne && dstIsOne) {
                     device.CreateRenderPipeline(&descriptor);
                 } else {
                     ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));