[webgpu-headers] Fold DepthClipControl into PrimitiveState

The following CL must be merged before:
- https://chromium-review.googlesource.com/c/chromium/src/+/5688517

https://github.com/webgpu-native/webgpu-headers/pull/311

Bug: 42241174
Change-Id: Ia425ba7a25494e9dcb96de0492d045c670f8f30c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/197634
Commit-Queue: Fr <beaufort.francois@gmail.com>
Reviewed-by: Kai Ninomiya (OOO until 8月23日) <kainino@chromium.org>
diff --git a/generator/templates/api.h b/generator/templates/api.h
index abd55e4..3322b6b 100644
--- a/generator/templates/api.h
+++ b/generator/templates/api.h
@@ -72,6 +72,8 @@
 #define {{API}}_NULLABLE
 #endif
 
+#define WGPU_BREAKING_CHANGE_DEPTH_CLIP_CONTROL
+
 #include <stdint.h>
 #include <stddef.h>
 
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 4c68450..2022809 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -3756,7 +3756,8 @@
             {"name": "topology", "type": "primitive topology", "default": "triangle list"},
             {"name": "strip index format", "type": "index format", "default": "undefined"},
             {"name": "front face", "type": "front face", "default": "CCW"},
-            {"name": "cull mode", "type": "cull mode", "default": "none"}
+            {"name": "cull mode", "type": "cull mode", "default": "none"},
+            {"name": "unclipped depth", "type": "bool", "default": "false"}
         ]
     },
 
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index afb3905..aeb6907 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -256,8 +256,7 @@
 MaybeError ValidatePrimitiveState(const DeviceBase* device, const PrimitiveState* rawDescriptor) {
     UnpackedPtr<PrimitiveState> descriptor;
     DAWN_TRY_ASSIGN(descriptor, ValidateAndUnpack(rawDescriptor));
-    const auto* depthClipControl = descriptor.Get<PrimitiveDepthClipControl>();
-    DAWN_INVALID_IF(depthClipControl && !device->HasFeature(Feature::DepthClipControl),
+    DAWN_INVALID_IF(descriptor->unclippedDepth && !device->HasFeature(Feature::DepthClipControl),
                     "%s is not supported", wgpu::FeatureName::DepthClipControl);
     DAWN_TRY(ValidatePrimitiveTopology(descriptor->topology));
     DAWN_TRY(ValidateIndexFormat(descriptor->stripIndexFormat));
@@ -984,11 +983,6 @@
     }
 
     mPrimitive = descriptor->primitive.WithTrivialFrontendDefaults();
-    UnpackedPtr<PrimitiveState> unpackedPrimitive = Unpack(&mPrimitive);
-    if (auto* depthClipControl = unpackedPrimitive.Get<PrimitiveDepthClipControl>()) {
-        mUnclippedDepth = depthClipControl->unclippedDepth;
-    }
-
     mMultisample = descriptor->multisample;
 
     if (mAttachmentState->HasDepthStencilAttachment()) {
@@ -1197,7 +1191,7 @@
 
 bool RenderPipelineBase::HasUnclippedDepth() const {
     DAWN_ASSERT(!IsError());
-    return mUnclippedDepth;
+    return mPrimitive.unclippedDepth;
 }
 
 ColorAttachmentMask RenderPipelineBase::GetColorAttachmentsMask() const {
@@ -1315,7 +1309,7 @@
 
     // Record primitive state
     recorder.Record(mPrimitive.topology, mPrimitive.stripIndexFormat, mPrimitive.frontFace,
-                    mPrimitive.cullMode, mUnclippedDepth);
+                    mPrimitive.cullMode, mPrimitive.unclippedDepth);
 
     // Record multisample state
     // Sample count hashed as part of the attachment state
@@ -1431,7 +1425,7 @@
         if (stateA.topology != stateB.topology ||
             stateA.stripIndexFormat != stateB.stripIndexFormat ||
             stateA.frontFace != stateB.frontFace || stateA.cullMode != stateB.cullMode ||
-            a->mUnclippedDepth != b->mUnclippedDepth) {
+            stateA.unclippedDepth != stateB.unclippedDepth) {
             return false;
         }
     }
diff --git a/src/dawn/native/RenderPipeline.h b/src/dawn/native/RenderPipeline.h
index f83eeac..98d6cdc 100644
--- a/src/dawn/native/RenderPipeline.h
+++ b/src/dawn/native/RenderPipeline.h
@@ -173,7 +173,6 @@
     PrimitiveState mPrimitive;
     DepthStencilState mDepthStencil;
     MultisampleState mMultisample;
-    bool mUnclippedDepth = false;
     bool mWritesDepth = false;
     bool mWritesStencil = false;
     bool mUsesFragDepth = false;
diff --git a/src/dawn/node/binding/Converter.cpp b/src/dawn/node/binding/Converter.cpp
index f163fdc..12e123e 100644
--- a/src/dawn/node/binding/Converter.cpp
+++ b/src/dawn/node/binding/Converter.cpp
@@ -879,15 +879,10 @@
 bool Converter::Convert(wgpu::PrimitiveState& out, const interop::GPUPrimitiveState& in) {
     out = {};
 
-    if (in.unclippedDepth) {
-        wgpu::PrimitiveDepthClipControl* depthClip = Allocate<wgpu::PrimitiveDepthClipControl>();
-        depthClip->unclippedDepth = true;
-        out.nextInChain = depthClip;
-    }
-
     return Convert(out.topology, in.topology) &&
            Convert(out.stripIndexFormat, in.stripIndexFormat) &&
-           Convert(out.frontFace, in.frontFace) && Convert(out.cullMode, in.cullMode);
+           Convert(out.frontFace, in.frontFace) && Convert(out.cullMode, in.cullMode) &&
+           Convert(out.unclippedDepth, in.unclippedDepth);
 }
 
 bool Converter::Convert(wgpu::ColorTargetState& out, const interop::GPUColorTargetState& in) {
diff --git a/src/dawn/tests/end2end/PrimitiveStateTests.cpp b/src/dawn/tests/end2end/PrimitiveStateTests.cpp
index 15b2f88..154bcf2 100644
--- a/src/dawn/tests/end2end/PrimitiveStateTests.cpp
+++ b/src/dawn/tests/end2end/PrimitiveStateTests.cpp
@@ -94,7 +94,7 @@
     }
 
     struct TestSpec {
-        raw_ptr<wgpu::PrimitiveDepthClipControl> depthClipControl;
+        bool unclippedDepth;
         utils::RGBA8 color;
         float depth;
     };
@@ -127,7 +127,7 @@
 
             // Create a pipeline for the triangles with the test spec's params.
             utils::ComboRenderPipelineDescriptor descriptor;
-            descriptor.primitive.nextInChain = test.depthClipControl;
+            descriptor.primitive.unclippedDepth = test.unclippedDepth;
             descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
             descriptor.vertex.module = vsModule;
             descriptor.cFragment.module = fsModule;
@@ -163,20 +163,17 @@
 
 // Test that fragments beyond the far plane are not clipped if unclippedDepth is true
 TEST_P(DepthClippingTest, UnclippedBeyondFarPlane) {
-    wgpu::PrimitiveDepthClipControl depthClipControl;
-    depthClipControl.unclippedDepth = true;
-
     DoTest(
         {
             // Draw a red triangle at depth 1.
             {
-                nullptr,                      /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(255, 0, 0, 255), /* color */
                 1.f,                          /* depth */
             },
             // Draw a green triangle at depth 2 which should not be clipped.
             {
-                &depthClipControl,            /* depthClipControl */
+                true,                         /* unclippedDepth */
                 utils::RGBA8(0, 255, 0, 255), /* color */
                 2.f,                          /* depth */
             },
@@ -188,20 +185,17 @@
 
 // Test that fragments beyond the far plane are clipped if unclippedDepth is false
 TEST_P(DepthClippingTest, ClippedBeyondFarPlane) {
-    wgpu::PrimitiveDepthClipControl depthClipControl;
-    depthClipControl.unclippedDepth = false;
-
     DoTest(
         {
             // Draw a red triangle at depth 1.
             {
-                nullptr,                      /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(255, 0, 0, 255), /* color */
                 1.f,                          /* depth */
             },
             // Draw a green triangle at depth 2 which should be clipped.
             {
-                &depthClipControl,            /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(0, 255, 0, 255), /* color */
                 2.f,                          /* depth */
             },
@@ -217,13 +211,13 @@
         {
             // Draw a red triangle at depth 1.
             {
-                nullptr,                      /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(255, 0, 0, 255), /* color */
                 1.f,                          /* depth */
             },
             // Draw a green triangle at depth 2 which should be clipped.
             {
-                nullptr,                      /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(0, 255, 0, 255), /* color */
                 2.f,                          /* depth */
             },
@@ -235,20 +229,17 @@
 
 // Test that fragments beyond the near plane are not clipped if unclippedDepth is true
 TEST_P(DepthClippingTest, UnclippedBeyondNearPlane) {
-    wgpu::PrimitiveDepthClipControl depthClipControl;
-    depthClipControl.unclippedDepth = true;
-
     DoTest(
         {
             // Draw a red triangle at depth 0.
             {
-                nullptr,                      /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(255, 0, 0, 255), /* color */
                 0.f,                          /* depth */
             },
             // Draw a green triangle at depth -1 which should not be clipped.
             {
-                &depthClipControl,            /* depthClipControl */
+                true,                         /* unclippedDepth */
                 utils::RGBA8(0, 255, 0, 255), /* color */
                 -1.f,                         /* depth */
             },
@@ -260,42 +251,17 @@
 
 // Test that fragments beyond the near plane are clipped if unclippedDepth is false
 TEST_P(DepthClippingTest, ClippedBeyondNearPlane) {
-    wgpu::PrimitiveDepthClipControl depthClipControl;
-    depthClipControl.unclippedDepth = false;
-
     DoTest(
         {
             // Draw a red triangle at depth 0.
             {
-                nullptr,                      /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(255, 0, 0, 255), /* color */
                 0.f,                          /* depth */
             },
             // Draw a green triangle at depth -1 which should be clipped.
             {
-                &depthClipControl,            /* depthClipControl */
-                utils::RGBA8(0, 255, 0, 255), /* color */
-                -1.f,                         /* depth */
-            },
-        },
-        // The resulting fragment should be red because the green triangle is
-        // outside the clip volume.
-        utils::RGBA8(255, 0, 0, 255));
-}
-
-// Test that fragments beyond the near plane are clipped if unclippedDepth is not specified
-TEST_P(DepthClippingTest, ClippedBeyondNearPlaneFeatureUnused) {
-    DoTest(
-        {
-            // Draw a red triangle at depth 0.
-            {
-                nullptr,                      /* depthClipControl */
-                utils::RGBA8(255, 0, 0, 255), /* color */
-                0.f,                          /* depth */
-            },
-            // Draw a green triangle at depth -1 which should be clipped.
-            {
-                nullptr,                      /* depthClipControl */
+                false,                        /* unclippedDepth */
                 utils::RGBA8(0, 255, 0, 255), /* color */
                 -1.f,                         /* depth */
             },
@@ -308,23 +274,19 @@
 // Test that fragments are properly clipped or clamped if multiple render pipelines are used
 // within the same render pass with differing unclippedDepth values.
 TEST_P(DepthClippingTest, MultipleRenderPipelines) {
-    wgpu::PrimitiveDepthClipControl depthClipControl1;
-    depthClipControl1.unclippedDepth = true;
-
-    wgpu::PrimitiveDepthClipControl depthClipControl2;
-    depthClipControl2.unclippedDepth = false;
-
     DoTest(
         {
             // Draw green with no clipping
             {
-                &depthClipControl1, utils::RGBA8(0, 255, 0, 255), /* color */
-                2.f,                                              /* depth */
+                true,                         /* unclippedDepth */
+                utils::RGBA8(0, 255, 0, 255), /* color */
+                2.f,                          /* depth */
             },
             // Draw red with clipping
             {
-                &depthClipControl2, utils::RGBA8(255, 0, 0, 255), /* color */
-                2.f,                                              /* depth */
+                false,                        /* unclippedDepth */
+                utils::RGBA8(255, 0, 0, 255), /* color */
+                2.f,                          /* depth */
             },
         },
         utils::RGBA8(0, 255, 0, 255));  // Result should be green
@@ -334,12 +296,9 @@
 // depths are not being clamped instead. In the fragment shader, we should see
 // depth values outside the viewport.
 TEST_P(DepthClippingTest, UnclippedNotClamped) {
-    wgpu::PrimitiveDepthClipControl depthClipControl;
-    depthClipControl.unclippedDepth = true;
-
     // Create a pipeline to render a point.
     utils::ComboRenderPipelineDescriptor descriptor;
-    descriptor.primitive.nextInChain = &depthClipControl;
+    descriptor.primitive.unclippedDepth = true;
     descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
     // Draw the point at (0, 0) with depth 2.0.
     descriptor.vertex.module = utils::CreateShaderModule(device, R"(
diff --git a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
index ebb02be..2f981ea 100644
--- a/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp
@@ -1338,49 +1338,20 @@
     }
 }
 
-// Test that specifying a unclippedDepth value is an error if the feature is not enabled.
+// Test that setting unclippedDepth to true is an error if the feature is not enabled.
 TEST_F(RenderPipelineValidationTest, UnclippedDepthWithoutFeature) {
     {
         utils::ComboRenderPipelineDescriptor descriptor;
         descriptor.vertex.module = vsModule;
         descriptor.cFragment.module = fsModule;
-        wgpu::PrimitiveDepthClipControl depthClipControl;
-        depthClipControl.unclippedDepth = true;
-        descriptor.primitive.nextInChain = &depthClipControl;
-        ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
-                            testing::HasSubstr("not supported"));
+        descriptor.primitive.unclippedDepth = false;
+        device.CreateRenderPipeline(&descriptor);
     }
     {
         utils::ComboRenderPipelineDescriptor descriptor;
         descriptor.vertex.module = vsModule;
         descriptor.cFragment.module = fsModule;
-        wgpu::PrimitiveDepthClipControl depthClipControl;
-        depthClipControl.unclippedDepth = false;
-        descriptor.primitive.nextInChain = &depthClipControl;
-        ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
-                            testing::HasSubstr("not supported"));
-    }
-}
-
-// Test that specifying an unclippedDepth value is an error if the feature is not enabled.
-TEST_F(RenderPipelineValidationTest, DepthClipControlWithoutFeature) {
-    {
-        utils::ComboRenderPipelineDescriptor descriptor;
-        descriptor.vertex.module = vsModule;
-        descriptor.cFragment.module = fsModule;
-        wgpu::PrimitiveDepthClipControl depthClipControl;
-        depthClipControl.unclippedDepth = true;
-        descriptor.primitive.nextInChain = &depthClipControl;
-        ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
-                            testing::HasSubstr("not supported"));
-    }
-    {
-        utils::ComboRenderPipelineDescriptor descriptor;
-        descriptor.vertex.module = vsModule;
-        descriptor.cFragment.module = fsModule;
-        wgpu::PrimitiveDepthClipControl depthClipControl;
-        depthClipControl.unclippedDepth = false;
-        descriptor.primitive.nextInChain = &depthClipControl;
+        descriptor.primitive.unclippedDepth = true;
         ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
                             testing::HasSubstr("not supported"));
     }
@@ -2020,18 +1991,14 @@
         utils::ComboRenderPipelineDescriptor descriptor;
         descriptor.vertex.module = vsModule;
         descriptor.cFragment.module = fsModule;
-        wgpu::PrimitiveDepthClipControl depthClipControl;
-        depthClipControl.unclippedDepth = true;
-        descriptor.primitive.nextInChain = &depthClipControl;
+        descriptor.primitive.unclippedDepth = true;
         device.CreateRenderPipeline(&descriptor);
     }
     {
         utils::ComboRenderPipelineDescriptor descriptor;
         descriptor.vertex.module = vsModule;
         descriptor.cFragment.module = fsModule;
-        wgpu::PrimitiveDepthClipControl depthClipControl;
-        depthClipControl.unclippedDepth = false;
-        descriptor.primitive.nextInChain = &depthClipControl;
+        descriptor.primitive.unclippedDepth = false;
         device.CreateRenderPipeline(&descriptor);
     }
 }