webgpu.h: Re-number enums, with defaulting: RenderPipelineDescriptor

Part 3 implements the following sub-structures of
RenderPipelineDescriptor. Defaulting is done in the constructor, which
(in most cases) is called by a bounce through the backend.

- PrimitiveState.topology: PrimitiveTopology = TriangleList
- PrimitiveState.frontFace: FrontFace = CCW
- PrimitiveState.cullMode: CullMode = None
- StencilFaceState.compare: CompareFunction = Always
- StencilFaceState.{fail,depthFail,pass}Op: StencilOperation = Keep
- BlendComponent.operation: BlendOperation = Add
- BlendComponent.srcFactor: BlendFactor = One
- BlendComponent.dstFactor: BlendFactor = Zero
- VertexBufferLayout.stepMode: VertexStepMode = Vertex

Spot tests are added for all of these. They won't necessarily catch if
the defaulting is _wrong_, but should crash if it is _missing_.

Bug: dawn:2224
Change-Id: I0e3029af0646ffcd58f8b8c99f7050206916ca36
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/166822
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 05b4503..7b6cabe 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -455,34 +455,37 @@
     },
     "blend factor": {
         "category": "enum",
+        "_comment": "TODO(github.com/gpuweb/gpuweb/issues/4283): make sure the dual source blending names match the spec when it lands, and remove the tags.",
         "values": [
-            {"value": 0, "name": "zero"},
-            {"value": 1, "name": "one"},
-            {"value": 2, "name": "src"},
-            {"value": 3, "name": "one minus src"},
-            {"value": 4, "name": "src alpha"},
-            {"value": 5, "name": "one minus src alpha"},
-            {"value": 6, "name": "dst"},
-            {"value": 7, "name": "one minus dst"},
-            {"value": 8, "name": "dst alpha"},
-            {"value": 9, "name": "one minus dst alpha"},
-            {"value": 10, "name": "src alpha saturated"},
-            {"value": 11, "name": "constant"},
-            {"value": 12, "name": "one minus constant"},
-            {"value": 13, "name": "src1", "tags": ["dawn"]},
-            {"value": 14, "name": "one minus src1", "tags": ["dawn"]},
-            {"value": 15, "name": "src1 alpha", "tags": ["dawn"]},
-            {"value": 16, "name": "one minus src1 alpha", "tags": ["dawn"]}
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 1, "name": "zero"},
+            {"value": 2, "name": "one"},
+            {"value": 3, "name": "src"},
+            {"value": 4, "name": "one minus src"},
+            {"value": 5, "name": "src alpha"},
+            {"value": 6, "name": "one minus src alpha"},
+            {"value": 7, "name": "dst"},
+            {"value": 8, "name": "one minus dst"},
+            {"value": 9, "name": "dst alpha"},
+            {"value": 10, "name": "one minus dst alpha"},
+            {"value": 11, "name": "src alpha saturated"},
+            {"value": 12, "name": "constant"},
+            {"value": 13, "name": "one minus constant"},
+            {"value": 14, "name": "src1", "tags": ["dawn"]},
+            {"value": 15, "name": "one minus src1", "tags": ["dawn"]},
+            {"value": 16, "name": "src1 alpha", "tags": ["dawn"]},
+            {"value": 17, "name": "one minus src1 alpha", "tags": ["dawn"]}
         ]
     },
     "blend operation": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "add"},
-            {"value": 1, "name": "subtract"},
-            {"value": 2, "name": "reverse subtract"},
-            {"value": 3, "name": "min"},
-            {"value": 4, "name": "max"}
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 1, "name": "add"},
+            {"value": 2, "name": "subtract"},
+            {"value": 3, "name": "reverse subtract"},
+            {"value": 4, "name": "min"},
+            {"value": 5, "name": "max"}
         ]
     },
     "bool": {
@@ -825,7 +828,7 @@
     "compare function": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "undefined", "jsrepr": "undefined", "valid": false},
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
             {"value": 1, "name": "never"},
             {"value": 2, "name": "less"},
             {"value": 3, "name": "equal"},
@@ -1079,9 +1082,10 @@
     "cull mode": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "none"},
-            {"value": 1, "name": "front"},
-            {"value": 2, "name": "back"}
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 1, "name": "none"},
+            {"value": 2, "name": "front"},
+            {"value": 3, "name": "back"}
         ]
     },
     "device": {
@@ -1988,8 +1992,9 @@
     "front face": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "CCW"},
-            {"value": 1, "name": "CW"}
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 1, "name": "CCW"},
+            {"value": 2, "name": "CW"}
         ]
     },
     "image copy buffer": {
@@ -2177,9 +2182,10 @@
     "vertex step mode": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "vertex"},
-            {"value": 1, "name": "instance"},
-            {"value": 2, "name": "vertex buffer not used", "jsrepr": "undefined", "valid": true}
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 1, "name": "vertex buffer not used"},
+            {"value": 2, "name": "vertex"},
+            {"value": 3, "name": "instance"}
         ]
     },
     "load op": {
@@ -2303,11 +2309,12 @@
     "primitive topology": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "point list"},
-            {"value": 1, "name": "line list"},
-            {"value": 2, "name": "line strip"},
-            {"value": 3, "name": "triangle list"},
-            {"value": 4, "name": "triangle strip"}
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 1, "name": "point list"},
+            {"value": 2, "name": "line list"},
+            {"value": 3, "name": "line strip"},
+            {"value": 4, "name": "triangle list"},
+            {"value": 5, "name": "triangle strip"}
         ]
     },
     "query set": {
@@ -3122,14 +3129,15 @@
     "stencil operation": {
         "category": "enum",
         "values": [
-            {"value": 0, "name": "keep"},
-            {"value": 1, "name": "zero"},
-            {"value": 2, "name": "replace"},
-            {"value": 3, "name": "invert"},
-            {"value": 4, "name": "increment clamp"},
-            {"value": 5, "name": "decrement clamp"},
-            {"value": 6, "name": "increment wrap"},
-            {"value": 7, "name": "decrement wrap"}
+            {"value": 0, "name": "undefined", "jsrepr": "undefined"},
+            {"value": 1, "name": "keep"},
+            {"value": 2, "name": "zero"},
+            {"value": 3, "name": "replace"},
+            {"value": 4, "name": "invert"},
+            {"value": 5, "name": "increment clamp"},
+            {"value": 6, "name": "decrement clamp"},
+            {"value": 7, "name": "increment wrap"},
+            {"value": 8, "name": "decrement wrap"}
         ]
     },
     "stencil face state": {
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index 87690ec..b264226 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -274,10 +274,8 @@
 
 MaybeError ValidateDepthStencilState(const DeviceBase* device,
                                      const DepthStencilState* descriptor) {
-    if (descriptor->depthCompare != wgpu::CompareFunction::Undefined) {
-        DAWN_TRY_CONTEXT(ValidateCompareFunction(descriptor->depthCompare),
-                         "validating depth compare function");
-    }
+    DAWN_TRY_CONTEXT(ValidateCompareFunction(descriptor->depthCompare),
+                     "validating depth compare function");
     DAWN_TRY_CONTEXT(ValidateCompareFunction(descriptor->stencilFront.compare),
                      "validating stencil front compare function");
     DAWN_TRY_CONTEXT(ValidateStencilOperation(descriptor->stencilFront.failOp),
@@ -849,12 +847,17 @@
 
     auto buffers =
         ityp::SpanFromUntyped<VertexBufferSlot>(descriptor->vertex.buffers, mVertexBufferCount);
-    for (auto [slot, buffer] : Enumerate(buffers)) {
+    for (auto [slot, bufferOrig] : Enumerate(buffers)) {
         // Skip unused slots
-        if (buffer.stepMode == wgpu::VertexStepMode::VertexBufferNotUsed) {
+        if (bufferOrig.stepMode == wgpu::VertexStepMode::VertexBufferNotUsed) {
             continue;
         }
 
+        // Make a local copy with defaulting applied, before copying the
+        // now-defaulted values into mVertexBufferInfos.
+        VertexBufferLayout buffer = bufferOrig;
+        buffer.ApplyTrivialFrontendDefaults();
+
         mVertexBuffersUsed.set(slot);
         mVertexBufferInfos[slot].arrayStride = buffer.arrayStride;
         mVertexBufferInfos[slot].stepMode = buffer.stepMode;
@@ -867,7 +870,8 @@
             case wgpu::VertexStepMode::Instance:
                 mVertexBuffersUsedAsInstanceBuffer.set(slot);
                 break;
-            default:
+            case wgpu::VertexStepMode::VertexBufferNotUsed:
+            case wgpu::VertexStepMode::Undefined:
                 DAWN_UNREACHABLE();
         }
 
@@ -898,6 +902,7 @@
     }
 
     mPrimitive = descriptor->primitive;
+    mPrimitive.ApplyTrivialFrontendDefaults();
     UnpackedPtr<PrimitiveState> unpackedPrimitive = Unpack(&mPrimitive);
     if (auto* depthClipControl = unpackedPrimitive.Get<PrimitiveDepthClipControl>()) {
         mUnclippedDepth = depthClipControl->unclippedDepth;
@@ -907,6 +912,9 @@
 
     if (mAttachmentState->HasDepthStencilAttachment()) {
         mDepthStencil = *descriptor->depthStencil;
+        mDepthStencil.stencilFront.ApplyTrivialFrontendDefaults();
+        mDepthStencil.stencilBack.ApplyTrivialFrontendDefaults();
+
         // Reify depth option for stencil-only formats
         const Format& format = device->GetValidInternalFormat(mDepthStencil.format);
         if (!format.HasDepth()) {
@@ -937,22 +945,10 @@
         // The values indicate that depth and stencil test are disabled when backends
         // set their own depth stencil states/descriptors according to the values in
         // mDepthStencil.
-        mDepthStencil.format = wgpu::TextureFormat::Undefined;
-        mDepthStencil.depthWriteEnabled = false;
+        // - Most defaults come from the dawn::native::DepthStencilState definition.
+        mDepthStencil = {};
+        // - depthCompare is nullable for validation purposes but should default to Always.
         mDepthStencil.depthCompare = wgpu::CompareFunction::Always;
-        mDepthStencil.stencilBack.compare = wgpu::CompareFunction::Always;
-        mDepthStencil.stencilBack.failOp = wgpu::StencilOperation::Keep;
-        mDepthStencil.stencilBack.depthFailOp = wgpu::StencilOperation::Keep;
-        mDepthStencil.stencilBack.passOp = wgpu::StencilOperation::Keep;
-        mDepthStencil.stencilFront.compare = wgpu::CompareFunction::Always;
-        mDepthStencil.stencilFront.failOp = wgpu::StencilOperation::Keep;
-        mDepthStencil.stencilFront.depthFailOp = wgpu::StencilOperation::Keep;
-        mDepthStencil.stencilFront.passOp = wgpu::StencilOperation::Keep;
-        mDepthStencil.stencilReadMask = 0xff;
-        mDepthStencil.stencilWriteMask = 0xff;
-        mDepthStencil.depthBias = 0;
-        mDepthStencil.depthBiasSlopeScale = 0.0f;
-        mDepthStencil.depthBiasClamp = 0.0f;
     }
 
     for (auto i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
@@ -964,6 +960,8 @@
 
         if (target->blend != nullptr) {
             mTargetBlend[i] = *target->blend;
+            mTargetBlend[i].alpha.ApplyTrivialFrontendDefaults();
+            mTargetBlend[i].color.ApplyTrivialFrontendDefaults();
             mTargets[i].blend = &mTargetBlend[i];
         }
     }
diff --git a/src/dawn/native/Sampler.cpp b/src/dawn/native/Sampler.cpp
index 550c898..d27ca6a 100644
--- a/src/dawn/native/Sampler.cpp
+++ b/src/dawn/native/Sampler.cpp
@@ -69,13 +69,7 @@
     DAWN_TRY(ValidateAddressMode(descriptor->addressModeU));
     DAWN_TRY(ValidateAddressMode(descriptor->addressModeV));
     DAWN_TRY(ValidateAddressMode(descriptor->addressModeW));
-
-    // 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));
-    }
+    DAWN_TRY(ValidateCompareFunction(descriptor->compare));
 
     return {};
 }
diff --git a/src/dawn/native/TintUtils.cpp b/src/dawn/native/TintUtils.cpp
index 534e82f..815b366 100644
--- a/src/dawn/native/TintUtils.cpp
+++ b/src/dawn/native/TintUtils.cpp
@@ -133,6 +133,7 @@
         case wgpu::VertexStepMode::Instance:
             return tint::ast::transform::VertexStepMode::kInstance;
         case wgpu::VertexStepMode::VertexBufferNotUsed:
+        case wgpu::VertexStepMode::Undefined:
             break;
     }
     DAWN_UNREACHABLE();
diff --git a/src/dawn/native/d3d11/RenderPipelineD3D11.cpp b/src/dawn/native/d3d11/RenderPipelineD3D11.cpp
index 12062f4..77bcc7f 100644
--- a/src/dawn/native/d3d11/RenderPipelineD3D11.cpp
+++ b/src/dawn/native/d3d11/RenderPipelineD3D11.cpp
@@ -54,8 +54,10 @@
         case wgpu::VertexStepMode::Instance:
             return D3D11_INPUT_PER_INSTANCE_DATA;
         case wgpu::VertexStepMode::VertexBufferNotUsed:
-            DAWN_UNREACHABLE();
+        case wgpu::VertexStepMode::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D_PRIMITIVE_TOPOLOGY D3DPrimitiveTopology(wgpu::PrimitiveTopology topology) {
@@ -70,9 +72,10 @@
             return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
         case wgpu::PrimitiveTopology::TriangleStrip:
             return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
-        default:
-            DAWN_UNREACHABLE();
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D11_CULL_MODE D3DCullMode(wgpu::CullMode cullMode) {
@@ -83,9 +86,10 @@
             return D3D11_CULL_FRONT;
         case wgpu::CullMode::Back:
             return D3D11_CULL_BACK;
-        default:
-            DAWN_UNREACHABLE();
+        case wgpu::CullMode::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D11_BLEND D3DBlendFactor(wgpu::BlendFactor blendFactor) {
@@ -124,9 +128,10 @@
             return D3D11_BLEND_SRC1_ALPHA;
         case wgpu::BlendFactor::OneMinusSrc1Alpha:
             return D3D11_BLEND_INV_SRC1_ALPHA;
-        default:
-            DAWN_UNREACHABLE();
+        case wgpu::BlendFactor::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 // When a blend factor is defined for the alpha channel, any of the factors that don't
@@ -165,9 +170,10 @@
             return D3D11_BLEND_OP_MIN;
         case wgpu::BlendOperation::Max:
             return D3D11_BLEND_OP_MAX;
-        default:
-            DAWN_UNREACHABLE();
+        case wgpu::BlendOperation::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 UINT D3DColorWriteMask(wgpu::ColorWriteMask colorWriteMask) {
@@ -197,7 +203,10 @@
             return D3D11_STENCIL_OP_INCR;
         case wgpu::StencilOperation::DecrementWrap:
             return D3D11_STENCIL_OP_DECR;
+        case wgpu::StencilOperation::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D11_DEPTH_STENCILOP_DESC StencilOpDesc(const StencilFaceState& descriptor) {
diff --git a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
index 9115613..483a75d 100644
--- a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
+++ b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
@@ -55,8 +55,10 @@
         case wgpu::VertexStepMode::Instance:
             return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
         case wgpu::VertexStepMode::VertexBufferNotUsed:
-            DAWN_UNREACHABLE();
+        case wgpu::VertexStepMode::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D12_PRIMITIVE_TOPOLOGY D3D12PrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
@@ -71,7 +73,10 @@
             return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
         case wgpu::PrimitiveTopology::TriangleStrip:
             return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D12_PRIMITIVE_TOPOLOGY_TYPE D3D12PrimitiveTopologyType(
@@ -85,7 +90,10 @@
         case wgpu::PrimitiveTopology::TriangleList:
         case wgpu::PrimitiveTopology::TriangleStrip:
             return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D12_CULL_MODE D3D12CullMode(wgpu::CullMode mode) {
@@ -96,7 +104,10 @@
             return D3D12_CULL_MODE_FRONT;
         case wgpu::CullMode::Back:
             return D3D12_CULL_MODE_BACK;
+        case wgpu::CullMode::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D12_BLEND D3D12Blend(wgpu::BlendFactor factor) {
@@ -135,7 +146,10 @@
             return D3D12_BLEND_SRC1_ALPHA;
         case wgpu::BlendFactor::OneMinusSrc1Alpha:
             return D3D12_BLEND_INV_SRC1_ALPHA;
+        case wgpu::BlendFactor::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 // When a blend factor is defined for the alpha channel, any of the factors that don't
@@ -174,7 +188,10 @@
             return D3D12_BLEND_OP_MIN;
         case wgpu::BlendOperation::Max:
             return D3D12_BLEND_OP_MAX;
+        case wgpu::BlendOperation::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 uint8_t D3D12RenderTargetWriteMask(wgpu::ColorWriteMask writeMask) {
@@ -253,7 +270,10 @@
             return D3D12_STENCIL_OP_INCR;
         case wgpu::StencilOperation::DecrementWrap:
             return D3D12_STENCIL_OP_DECR;
+        case wgpu::StencilOperation::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 D3D12_DEPTH_STENCILOP_DESC StencilOpDesc(const StencilFaceState& descriptor) {
diff --git a/src/dawn/native/metal/RenderPipelineMTL.mm b/src/dawn/native/metal/RenderPipelineMTL.mm
index 94d14e71..2d4ca1c 100644
--- a/src/dawn/native/metal/RenderPipelineMTL.mm
+++ b/src/dawn/native/metal/RenderPipelineMTL.mm
@@ -117,8 +117,10 @@
         case wgpu::VertexStepMode::Instance:
             return MTLVertexStepFunctionPerInstance;
         case wgpu::VertexStepMode::VertexBufferNotUsed:
-            DAWN_UNREACHABLE();
+        case wgpu::VertexStepMode::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 MTLPrimitiveType MTLPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
@@ -133,7 +135,10 @@
             return MTLPrimitiveTypeTriangle;
         case wgpu::PrimitiveTopology::TriangleStrip:
             return MTLPrimitiveTypeTriangleStrip;
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 MTLPrimitiveTopologyClass MTLInputPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
@@ -146,7 +151,10 @@
         case wgpu::PrimitiveTopology::TriangleList:
         case wgpu::PrimitiveTopology::TriangleStrip:
             return MTLPrimitiveTopologyClassTriangle;
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 MTLBlendFactor MetalBlendFactor(wgpu::BlendFactor factor, bool alpha) {
@@ -185,7 +193,10 @@
             return MTLBlendFactorSource1Alpha;
         case wgpu::BlendFactor::OneMinusSrc1Alpha:
             return MTLBlendFactorOneMinusSource1Alpha;
+        case wgpu::BlendFactor::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 MTLBlendOperation MetalBlendOperation(wgpu::BlendOperation operation) {
@@ -200,7 +211,10 @@
             return MTLBlendOperationMin;
         case wgpu::BlendOperation::Max:
             return MTLBlendOperationMax;
+        case wgpu::BlendOperation::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 MTLColorWriteMask MetalColorWriteMask(wgpu::ColorWriteMask writeMask,
@@ -262,7 +276,10 @@
             return MTLStencilOperationIncrementWrap;
         case wgpu::StencilOperation::DecrementWrap:
             return MTLStencilOperationDecrementWrap;
+        case wgpu::StencilOperation::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 NSRef<MTLDepthStencilDescriptor> MakeDepthStencilDesc(const DepthStencilState* descriptor) {
@@ -315,7 +332,10 @@
             return MTLWindingClockwise;
         case wgpu::FrontFace::CCW:
             return MTLWindingCounterClockwise;
+        case wgpu::FrontFace::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 MTLCullMode ToMTLCullMode(wgpu::CullMode mode) {
@@ -326,7 +346,10 @@
             return MTLCullModeFront;
         case wgpu::CullMode::Back:
             return MTLCullModeBack;
+        case wgpu::CullMode::Undefined:
+            break;
     }
+    DAWN_UNREACHABLE();
 }
 
 }  // anonymous namespace
diff --git a/src/dawn/native/opengl/RenderPipelineGL.cpp b/src/dawn/native/opengl/RenderPipelineGL.cpp
index a545026..e461ee6 100644
--- a/src/dawn/native/opengl/RenderPipelineGL.cpp
+++ b/src/dawn/native/opengl/RenderPipelineGL.cpp
@@ -48,6 +48,8 @@
             return GL_TRIANGLES;
         case wgpu::PrimitiveTopology::TriangleStrip:
             return GL_TRIANGLE_STRIP;
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -106,7 +108,8 @@
             return GL_SRC1_ALPHA;
         case wgpu::BlendFactor::OneMinusSrc1Alpha:
             return GL_ONE_MINUS_SRC1_ALPHA;
-            DAWN_UNREACHABLE();
+        case wgpu::BlendFactor::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -123,6 +126,8 @@
             return GL_MIN;
         case wgpu::BlendOperation::Max:
             return GL_MAX;
+        case wgpu::BlendOperation::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -189,6 +194,8 @@
             return GL_INCR_WRAP;
         case wgpu::StencilOperation::DecrementWrap:
             return GL_DECR_WRAP;
+        case wgpu::StencilOperation::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -300,6 +307,7 @@
                     gl.VertexAttribDivisor(glAttrib, 1);
                     break;
                 case wgpu::VertexStepMode::VertexBufferNotUsed:
+                case wgpu::VertexStepMode::Undefined:
                     DAWN_UNREACHABLE();
             }
         }
diff --git a/src/dawn/native/vulkan/RenderPipelineVk.cpp b/src/dawn/native/vulkan/RenderPipelineVk.cpp
index 084a250..1c269d3 100644
--- a/src/dawn/native/vulkan/RenderPipelineVk.cpp
+++ b/src/dawn/native/vulkan/RenderPipelineVk.cpp
@@ -54,6 +54,7 @@
         case wgpu::VertexStepMode::Instance:
             return VK_VERTEX_INPUT_RATE_INSTANCE;
         case wgpu::VertexStepMode::VertexBufferNotUsed:
+        case wgpu::VertexStepMode::Undefined:
             break;
     }
     DAWN_UNREACHABLE();
@@ -140,6 +141,8 @@
             return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
         case wgpu::PrimitiveTopology::TriangleStrip:
             return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -155,6 +158,8 @@
         case wgpu::PrimitiveTopology::LineStrip:
         case wgpu::PrimitiveTopology::TriangleStrip:
             return true;
+        case wgpu::PrimitiveTopology::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -165,6 +170,8 @@
             return VK_FRONT_FACE_COUNTER_CLOCKWISE;
         case wgpu::FrontFace::CW:
             return VK_FRONT_FACE_CLOCKWISE;
+        case wgpu::FrontFace::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -177,6 +184,8 @@
             return VK_CULL_MODE_FRONT_BIT;
         case wgpu::CullMode::Back:
             return VK_CULL_MODE_BACK_BIT;
+        case wgpu::CullMode::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -217,6 +226,8 @@
             return VK_BLEND_FACTOR_SRC1_ALPHA;
         case wgpu::BlendFactor::OneMinusSrc1Alpha:
             return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
+        case wgpu::BlendFactor::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -233,6 +244,8 @@
             return VK_BLEND_OP_MIN;
         case wgpu::BlendOperation::Max:
             return VK_BLEND_OP_MAX;
+        case wgpu::BlendOperation::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
@@ -300,6 +313,8 @@
             return VK_STENCIL_OP_INCREMENT_AND_WRAP;
         case wgpu::StencilOperation::DecrementWrap:
             return VK_STENCIL_OP_DECREMENT_AND_WRAP;
+        case wgpu::StencilOperation::Undefined:
+            break;
     }
     DAWN_UNREACHABLE();
 }
diff --git a/src/dawn/tests/end2end/ColorStateTests.cpp b/src/dawn/tests/end2end/ColorStateTests.cpp
index 7fe8f63..f9204f5 100644
--- a/src/dawn/tests/end2end/ColorStateTests.cpp
+++ b/src/dawn/tests/end2end/ColorStateTests.cpp
@@ -321,9 +321,10 @@
 // Test compilation and usage of the fixture
 TEST_P(ColorStateTest, Basic) {
     wgpu::BlendComponent blendComponent;
-    blendComponent.operation = wgpu::BlendOperation::Add;
-    blendComponent.srcFactor = wgpu::BlendFactor::One;
-    blendComponent.dstFactor = wgpu::BlendFactor::Zero;
+    // Spot-test for defaulting of these three fields.
+    blendComponent.operation = wgpu::BlendOperation::Undefined;  // add
+    blendComponent.srcFactor = wgpu::BlendFactor::Undefined;     // one
+    blendComponent.dstFactor = wgpu::BlendFactor::Undefined;     // zero
 
     wgpu::BlendState blend;
     blend.color = blendComponent;
diff --git a/src/dawn/tests/end2end/DepthStencilStateTests.cpp b/src/dawn/tests/end2end/DepthStencilStateTests.cpp
index 2e2e8e7..2071920 100644
--- a/src/dawn/tests/end2end/DepthStencilStateTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilStateTests.cpp
@@ -387,10 +387,11 @@
 // Test compilation and usage of the fixture
 TEST_P(DepthStencilStateTest, Basic) {
     wgpu::StencilFaceState stencilFace;
-    stencilFace.compare = wgpu::CompareFunction::Always;
-    stencilFace.failOp = wgpu::StencilOperation::Keep;
-    stencilFace.depthFailOp = wgpu::StencilOperation::Keep;
-    stencilFace.passOp = wgpu::StencilOperation::Keep;
+    // Spot-test for defaulting of these four fields.
+    stencilFace.compare = wgpu::CompareFunction::Undefined;
+    stencilFace.failOp = wgpu::StencilOperation::Undefined;
+    stencilFace.depthFailOp = wgpu::StencilOperation::Undefined;
+    stencilFace.passOp = wgpu::StencilOperation::Undefined;
 
     wgpu::DepthStencilState state;
     state.depthWriteEnabled = false;
diff --git a/src/dawn/tests/end2end/RenderPassTests.cpp b/src/dawn/tests/end2end/RenderPassTests.cpp
index 8a01e10..f11aa93 100644
--- a/src/dawn/tests/end2end/RenderPassTests.cpp
+++ b/src/dawn/tests/end2end/RenderPassTests.cpp
@@ -161,7 +161,10 @@
         utils::ComboRenderPipelineDescriptor descriptor;
         descriptor.vertex.module = mVSModule;
         descriptor.cFragment.module = fsModule;
-        descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
+        // (Off-topic) spot-test for defaulting of these three fields.
+        descriptor.primitive.topology = wgpu::PrimitiveTopology::Undefined;
+        descriptor.primitive.frontFace = wgpu::FrontFace::Undefined;
+        descriptor.primitive.cullMode = wgpu::CullMode::Undefined;
         descriptor.cTargets[0].format = kFormat;
         descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
 
diff --git a/src/dawn/tests/end2end/VertexStateTests.cpp b/src/dawn/tests/end2end/VertexStateTests.cpp
index 7d0e8b5..9a167d0b 100644
--- a/src/dawn/tests/end2end/VertexStateTests.cpp
+++ b/src/dawn/tests/end2end/VertexStateTests.cpp
@@ -558,7 +558,8 @@
     // All the other vertex buffers default to no attributes
     vertexState.vertexBufferCount = kMaxVertexBuffers;
     vertexState.cVertexBuffers[kBufferIndex].arrayStride = 4 * sizeof(float);
-    vertexState.cVertexBuffers[kBufferIndex].stepMode = VertexStepMode::Vertex;
+    // (Off-topic) spot-test for defaulting of .stepMode.
+    vertexState.cVertexBuffers[kBufferIndex].stepMode = VertexStepMode::Undefined;
     vertexState.cVertexBuffers[kBufferIndex].attributeCount = 1;
     vertexState.cVertexBuffers[kBufferIndex].attributes = &vertexState.cAttributes[0];
     vertexState.cAttributes[0].shaderLocation = 0;