[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); } }