Add depth-clamping support for Metal
This CL adds depth clamping support to Metal by invoking MTLRenderCommandEncoder::setDepthClipMode. I only implemented the feature for the new-style of RenderPipelineDescriptor since the old one seems to be deprecated. Bug: dawn:716 Change-Id: Icd63c72294546042ae452360863a7f9c16b40f95 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/45640 Commit-Queue: Brian Ho <hob@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
cb0bdb3401
commit
2cccd5a70c
14
dawn.json
14
dawn.json
|
@ -832,7 +832,8 @@
|
|||
{"name": "shader float16", "type": "bool", "default": "false"},
|
||||
{"name": "pipeline statistics query", "type": "bool", "default": "false"},
|
||||
{"name": "timestamp query", "type": "bool", "default": "false"},
|
||||
{"name": "multi planar formats", "type": "bool", "default": "false"}
|
||||
{"name": "multi planar formats", "type": "bool", "default": "false"},
|
||||
{"name": "depth clamping", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
"depth stencil state descriptor": {
|
||||
|
@ -1598,6 +1599,14 @@
|
|||
]
|
||||
},
|
||||
|
||||
"primitive depth clamping state": {
|
||||
"category": "structure",
|
||||
"chained": true,
|
||||
"members": [
|
||||
{"name": "clamp depth", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
|
||||
"depth stencil state": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
|
@ -1866,7 +1875,8 @@
|
|||
{"value": 5, "name": "shader module SPIRV descriptor"},
|
||||
{"value": 6, "name": "shader module WGSL descriptor"},
|
||||
{"value": 7, "name": "sampler descriptor dummy anisotropic filtering"},
|
||||
{"value": 8, "name": "render pipeline descriptor dummy extension"}
|
||||
{"value": 8, "name": "render pipeline descriptor dummy extension"},
|
||||
{"value": 9, "name": "primitive depth clamping state"}
|
||||
]
|
||||
},
|
||||
"texture": {
|
||||
|
|
|
@ -52,7 +52,11 @@ namespace dawn_native {
|
|||
{"multiplanar_formats",
|
||||
"Import and use multi-planar texture formats with per plane views",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=551"},
|
||||
&WGPUDeviceProperties::multiPlanarFormats}}};
|
||||
&WGPUDeviceProperties::multiPlanarFormats},
|
||||
{Extension::DepthClamping,
|
||||
{"depth_clamping", "Clamp depth to [0, 1] in NDC space instead of clipping",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=716"},
|
||||
&WGPUDeviceProperties::depthClamping}}};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace dawn_native {
|
|||
PipelineStatisticsQuery,
|
||||
TimestampQuery,
|
||||
MultiPlanarFormats,
|
||||
DepthClamping,
|
||||
|
||||
EnumCount,
|
||||
InvalidEnum = EnumCount,
|
||||
|
|
|
@ -131,9 +131,16 @@ namespace dawn_native {
|
|||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidatePrimitiveState(const PrimitiveState* descriptor) {
|
||||
if (descriptor->nextInChain != nullptr) {
|
||||
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
||||
MaybeError ValidatePrimitiveState(const DeviceBase* device,
|
||||
const PrimitiveState* descriptor) {
|
||||
const ChainedStruct* chained = descriptor->nextInChain;
|
||||
if (chained != nullptr) {
|
||||
if (chained->sType != wgpu::SType::PrimitiveDepthClampingState) {
|
||||
return DAWN_VALIDATION_ERROR("Unsupported sType");
|
||||
}
|
||||
if (!device->IsExtensionEnabled(Extension::DepthClamping)) {
|
||||
return DAWN_VALIDATION_ERROR("The depth clamping feature is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
DAWN_TRY(ValidatePrimitiveTopology(descriptor->topology));
|
||||
|
@ -269,7 +276,6 @@ namespace dawn_native {
|
|||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// Helper functions
|
||||
|
@ -306,7 +312,7 @@ namespace dawn_native {
|
|||
|
||||
DAWN_TRY(ValidateVertexState(device, &descriptor->vertex, descriptor->layout));
|
||||
|
||||
DAWN_TRY(ValidatePrimitiveState(&descriptor->primitive));
|
||||
DAWN_TRY(ValidatePrimitiveState(device, &descriptor->primitive));
|
||||
|
||||
if (descriptor->depthStencil) {
|
||||
DAWN_TRY(ValidateDepthStencilState(device, descriptor->depthStencil));
|
||||
|
@ -393,6 +399,12 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
mPrimitive = descriptor->primitive;
|
||||
const ChainedStruct* chained = mPrimitive.nextInChain;
|
||||
if (chained != nullptr) {
|
||||
ASSERT(chained->sType == wgpu::SType::PrimitiveDepthClampingState);
|
||||
const auto* clampState = static_cast<const PrimitiveDepthClampingState*>(chained);
|
||||
mClampDepth = clampState->clampDepth;
|
||||
}
|
||||
mMultisample = descriptor->multisample;
|
||||
|
||||
if (mAttachmentState->HasDepthStencilAttachment()) {
|
||||
|
@ -532,6 +544,11 @@ namespace dawn_native {
|
|||
return mDepthStencil.depthBiasClamp;
|
||||
}
|
||||
|
||||
bool RenderPipelineBase::ShouldClampDepth() const {
|
||||
ASSERT(!IsError());
|
||||
return mClampDepth;
|
||||
}
|
||||
|
||||
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
|
||||
RenderPipelineBase::GetColorAttachmentsMask() const {
|
||||
ASSERT(!IsError());
|
||||
|
@ -624,7 +641,7 @@ namespace dawn_native {
|
|||
|
||||
// Record primitive state
|
||||
recorder.Record(mPrimitive.topology, mPrimitive.stripIndexFormat, mPrimitive.frontFace,
|
||||
mPrimitive.cullMode);
|
||||
mPrimitive.cullMode, mClampDepth);
|
||||
|
||||
// Record multisample state
|
||||
// Sample count hashed as part of the attachment state
|
||||
|
@ -738,7 +755,8 @@ namespace dawn_native {
|
|||
const PrimitiveState& stateB = b->mPrimitive;
|
||||
if (stateA.topology != stateB.topology ||
|
||||
stateA.stripIndexFormat != stateB.stripIndexFormat ||
|
||||
stateA.frontFace != stateB.frontFace || stateA.cullMode != stateB.cullMode) {
|
||||
stateA.frontFace != stateB.frontFace || stateA.cullMode != stateB.cullMode ||
|
||||
a->mClampDepth != b->mClampDepth) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace dawn_native {
|
|||
int32_t GetDepthBias() const;
|
||||
float GetDepthBiasSlopeScale() const;
|
||||
float GetDepthBiasClamp() const;
|
||||
bool ShouldClampDepth() const;
|
||||
|
||||
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> GetColorAttachmentsMask() const;
|
||||
bool HasDepthStencilAttachment() const;
|
||||
|
@ -116,6 +117,7 @@ namespace dawn_native {
|
|||
PrimitiveState mPrimitive;
|
||||
DepthStencilState mDepthStencil;
|
||||
MultisampleState mMultisample;
|
||||
bool mClampDepth = false;
|
||||
};
|
||||
|
||||
} // namespace dawn_native
|
||||
|
|
|
@ -227,6 +227,9 @@ namespace dawn_native { namespace metal {
|
|||
// See https://github.com/gpuweb/gpuweb/issues/1325
|
||||
}
|
||||
}
|
||||
if (@available(macOS 10.11, iOS 11.0, *)) {
|
||||
mSupportedExtensions.EnableExtension(Extension::DepthClamping);
|
||||
}
|
||||
|
||||
mSupportedExtensions.EnableExtension(Extension::ShaderFloat16);
|
||||
}
|
||||
|
|
|
@ -1193,6 +1193,11 @@ namespace dawn_native { namespace metal {
|
|||
[encoder setDepthBias:newPipeline->GetDepthBias()
|
||||
slopeScale:newPipeline->GetDepthBiasSlopeScale()
|
||||
clamp:newPipeline->GetDepthBiasClamp()];
|
||||
if (@available(macOS 10.11, iOS 11.0, *)) {
|
||||
MTLDepthClipMode clipMode = newPipeline->ShouldClampDepth() ?
|
||||
MTLDepthClipModeClamp : MTLDepthClipModeClip;
|
||||
[encoder setDepthClipMode:clipMode];
|
||||
}
|
||||
newPipeline->Encode(encoder);
|
||||
|
||||
lastPipeline = newPipeline;
|
||||
|
|
|
@ -321,6 +321,7 @@ source_set("dawn_end2end_tests_sources") {
|
|||
"end2end/ObjectCachingTests.cpp",
|
||||
"end2end/OpArrayLengthTests.cpp",
|
||||
"end2end/PipelineLayoutTests.cpp",
|
||||
"end2end/PrimitiveStateTests.cpp",
|
||||
"end2end/PrimitiveTopologyTests.cpp",
|
||||
"end2end/QueryTests.cpp",
|
||||
"end2end/QueueTests.cpp",
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
// Copyright 2021 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/WGPUHelpers.h"
|
||||
|
||||
constexpr static unsigned int kRTSize = 1;
|
||||
|
||||
class DepthClampingTest : public DawnTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
DawnTest::SetUp();
|
||||
DAWN_SKIP_TEST_IF(!SupportsExtensions({"depth_clamping"}));
|
||||
|
||||
wgpu::TextureDescriptor renderTargetDescriptor;
|
||||
renderTargetDescriptor.size = {kRTSize, kRTSize};
|
||||
renderTargetDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
renderTargetDescriptor.usage =
|
||||
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
|
||||
renderTarget = device.CreateTexture(&renderTargetDescriptor);
|
||||
|
||||
renderTargetView = renderTarget.CreateView();
|
||||
|
||||
wgpu::TextureDescriptor depthDescriptor;
|
||||
depthDescriptor.dimension = wgpu::TextureDimension::e2D;
|
||||
depthDescriptor.size = {kRTSize, kRTSize};
|
||||
depthDescriptor.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||
depthDescriptor.usage = wgpu::TextureUsage::RenderAttachment;
|
||||
depthTexture = device.CreateTexture(&depthDescriptor);
|
||||
|
||||
depthTextureView = depthTexture.CreateView();
|
||||
|
||||
vsModule = utils::CreateShaderModule(device, R"(
|
||||
[[block]] struct UBO {
|
||||
color : vec3<f32>;
|
||||
depth : f32;
|
||||
};
|
||||
[[group(0), binding(0)]] var<uniform> ubo : UBO;
|
||||
[[builtin(position)]] var<out> Position : vec4<f32>;
|
||||
|
||||
[[stage(vertex)]] fn main() -> void {
|
||||
Position = vec4<f32>(0.0, 0.0, ubo.depth, 1.0);
|
||||
})");
|
||||
|
||||
fsModule = utils::CreateShaderModule(device, R"(
|
||||
[[block]] struct UBO {
|
||||
color : vec3<f32>;
|
||||
depth : f32;
|
||||
};
|
||||
[[group(0), binding(0)]] var<uniform> ubo : UBO;
|
||||
|
||||
[[location(0)]] var<out> fragColor : vec4<f32>;
|
||||
|
||||
[[stage(fragment)]] fn main() -> void {
|
||||
fragColor = vec4<f32>(ubo.color, 1.0);
|
||||
})");
|
||||
}
|
||||
|
||||
std::vector<const char*> GetRequiredExtensions() override {
|
||||
std::vector<const char*> requiredExtensions = {};
|
||||
if (SupportsExtensions({"depth_clamping"})) {
|
||||
requiredExtensions.push_back("depth_clamping");
|
||||
}
|
||||
return requiredExtensions;
|
||||
}
|
||||
|
||||
struct TestSpec {
|
||||
wgpu::PrimitiveDepthClampingState* depthClampingState;
|
||||
RGBA8 color;
|
||||
float depth;
|
||||
wgpu::CompareFunction depthCompareFunction;
|
||||
};
|
||||
|
||||
// Each test param represents a pair of triangles with a color, depth, stencil value, and
|
||||
// depthStencil state, one frontfacing, one backfacing Draw the triangles in order and check the
|
||||
// expected colors for the frontfaces and backfaces
|
||||
void DoTest(const std::vector<TestSpec>& testParams, const RGBA8& expected) {
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
|
||||
struct TriangleData {
|
||||
float color[3];
|
||||
float depth;
|
||||
};
|
||||
|
||||
utils::ComboRenderPassDescriptor renderPass({renderTargetView}, depthTextureView);
|
||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||
|
||||
for (size_t i = 0; i < testParams.size(); ++i) {
|
||||
const TestSpec& test = testParams[i];
|
||||
|
||||
TriangleData data = {
|
||||
{static_cast<float>(test.color.r) / 255.f, static_cast<float>(test.color.g) / 255.f,
|
||||
static_cast<float>(test.color.b) / 255.f},
|
||||
test.depth,
|
||||
};
|
||||
// Upload a buffer for each triangle's depth and color data
|
||||
wgpu::Buffer buffer = utils::CreateBufferFromData(device, &data, sizeof(TriangleData),
|
||||
wgpu::BufferUsage::Uniform);
|
||||
|
||||
// Create a pipeline for the triangles with the test spec's params.
|
||||
utils::ComboRenderPipelineDescriptor2 descriptor;
|
||||
descriptor.primitive.nextInChain = test.depthClampingState;
|
||||
descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
|
||||
descriptor.vertex.module = vsModule;
|
||||
descriptor.cFragment.module = fsModule;
|
||||
wgpu::DepthStencilState* depthStencil = descriptor.EnableDepthStencil();
|
||||
depthStencil->depthWriteEnabled = true;
|
||||
depthStencil->depthCompare = test.depthCompareFunction;
|
||||
depthStencil->format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline2(&descriptor);
|
||||
|
||||
// Create a bind group for the data
|
||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(
|
||||
device, pipeline.GetBindGroupLayout(0), {{0, buffer}});
|
||||
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.Draw(1);
|
||||
}
|
||||
pass.EndPass();
|
||||
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
|
||||
EXPECT_PIXEL_RGBA8_EQ(expected, renderTarget, 0, 0) << "Pixel check failed";
|
||||
}
|
||||
|
||||
wgpu::Texture renderTarget;
|
||||
wgpu::Texture depthTexture;
|
||||
wgpu::TextureView renderTargetView;
|
||||
wgpu::TextureView depthTextureView;
|
||||
wgpu::ShaderModule vsModule;
|
||||
wgpu::ShaderModule fsModule;
|
||||
};
|
||||
|
||||
// Test that fragments beyond the far plane are clamped to 1.0 if depth clamping is enabled.
|
||||
TEST_P(DepthClampingTest, ClampOnBeyondFarPlane) {
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = true;
|
||||
|
||||
DoTest(
|
||||
{
|
||||
// Draw a red triangle at depth 1.
|
||||
{
|
||||
nullptr, /* depthClampingState */
|
||||
RGBA8(255, 0, 0, 255), /* color */
|
||||
1.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
// Draw a green triangle at depth 2 which should get clamped to 1.
|
||||
{
|
||||
&clampingState,
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
2.f, /* depth */
|
||||
wgpu::CompareFunction::Equal,
|
||||
},
|
||||
},
|
||||
// Since we draw the green triangle with an "equal" depth compare function, the resulting
|
||||
// fragment should be green.
|
||||
RGBA8(0, 255, 0, 255));
|
||||
}
|
||||
|
||||
// Test that fragments beyond the near plane are clamped to 0.0 if depth clamping is enabled.
|
||||
TEST_P(DepthClampingTest, ClampOnBeyondNearPlane) {
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = true;
|
||||
|
||||
DoTest(
|
||||
{
|
||||
// Draw a red triangle at depth 0.
|
||||
{
|
||||
nullptr, /* depthClampingState */
|
||||
RGBA8(255, 0, 0, 255), /* color */
|
||||
0.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
// Draw a green triangle at depth -1 which should get clamped to 0.
|
||||
{
|
||||
&clampingState,
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
-1.f, /* depth */
|
||||
wgpu::CompareFunction::Equal,
|
||||
},
|
||||
},
|
||||
// Since we draw the green triangle with an "equal" depth compare function, the resulting
|
||||
// fragment should be green.
|
||||
RGBA8(0, 255, 0, 255));
|
||||
}
|
||||
|
||||
// Test that fragments inside the view frustum are unaffected by depth clamping.
|
||||
TEST_P(DepthClampingTest, ClampOnInsideViewFrustum) {
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = true;
|
||||
|
||||
DoTest(
|
||||
{
|
||||
{
|
||||
&clampingState,
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
0.5f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
},
|
||||
RGBA8(0, 255, 0, 255));
|
||||
}
|
||||
|
||||
|
||||
// Test that fragments outside the view frustum are clipped if depth clamping is disabled.
|
||||
TEST_P(DepthClampingTest, ClampOffOutsideViewFrustum) {
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = false;
|
||||
|
||||
DoTest(
|
||||
{
|
||||
{
|
||||
&clampingState,
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
2.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
{
|
||||
&clampingState,
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
-1.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
},
|
||||
RGBA8(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
// Test that fragments outside the view frustum are clipped if clampDepth is left unspecified.
|
||||
TEST_P(DepthClampingTest, ClampUnspecifiedOutsideViewFrustum) {
|
||||
DoTest(
|
||||
{
|
||||
{
|
||||
nullptr, /* depthClampingState */
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
-1.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
{
|
||||
nullptr, /* depthClampingState */
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
2.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
},
|
||||
RGBA8(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
// Test that fragments are properly clipped or clamped if multiple render pipelines are used
|
||||
// within the same render pass with differing clampDepth values.
|
||||
TEST_P(DepthClampingTest, MultipleRenderPipelines) {
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = true;
|
||||
|
||||
wgpu::PrimitiveDepthClampingState clippingState;
|
||||
clippingState.clampDepth = false;
|
||||
|
||||
DoTest(
|
||||
{
|
||||
// Draw green with clamping
|
||||
{
|
||||
&clampingState,
|
||||
RGBA8(0, 255, 0, 255), /* color */
|
||||
2.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
// Draw red with clipping
|
||||
{
|
||||
&clippingState,
|
||||
RGBA8(255, 0, 0, 255), /* color */
|
||||
2.f, /* depth */
|
||||
wgpu::CompareFunction::Always,
|
||||
},
|
||||
},
|
||||
RGBA8(0, 255, 0, 255)); // Result should be green
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(DepthClampingTest,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
OpenGLBackend(),
|
||||
OpenGLESBackend(),
|
||||
VulkanBackend());
|
|
@ -550,6 +550,28 @@ TEST_F(RenderPipelineValidationTest, StripIndexFormatRequired) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test that specifying a clampDepth value results in an error if the feature is not enabled.
|
||||
TEST_F(RenderPipelineValidationTest, ClampDepthWithoutExtension) {
|
||||
{
|
||||
utils::ComboRenderPipelineDescriptor2 descriptor;
|
||||
descriptor.vertex.module = vsModule;
|
||||
descriptor.cFragment.module = fsModule;
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = true;
|
||||
descriptor.primitive.nextInChain = &clampingState;
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline2(&descriptor));
|
||||
}
|
||||
{
|
||||
utils::ComboRenderPipelineDescriptor2 descriptor;
|
||||
descriptor.vertex.module = vsModule;
|
||||
descriptor.cFragment.module = fsModule;
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = false;
|
||||
descriptor.primitive.nextInChain = &clampingState;
|
||||
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"(
|
||||
|
@ -739,3 +761,34 @@ TEST_F(RenderPipelineValidationTest, DISABLED_BindingsFromCorrectEntryPoint) {
|
|||
descriptor.layout = layout1;
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline2(&descriptor));
|
||||
}
|
||||
|
||||
class DepthClampingValidationTest : public RenderPipelineValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
dawn_native::DeviceDescriptor descriptor;
|
||||
descriptor.requiredExtensions = {"depth_clamping"};
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
// Tests that specifying a clampDepth value succeeds if the extension is enabled.
|
||||
TEST_F(DepthClampingValidationTest, Success) {
|
||||
{
|
||||
utils::ComboRenderPipelineDescriptor2 descriptor;
|
||||
descriptor.vertex.module = vsModule;
|
||||
descriptor.cFragment.module = fsModule;
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = true;
|
||||
descriptor.primitive.nextInChain = &clampingState;
|
||||
device.CreateRenderPipeline2(&descriptor);
|
||||
}
|
||||
{
|
||||
utils::ComboRenderPipelineDescriptor2 descriptor;
|
||||
descriptor.vertex.module = vsModule;
|
||||
descriptor.cFragment.module = fsModule;
|
||||
wgpu::PrimitiveDepthClampingState clampingState;
|
||||
clampingState.clampDepth = false;
|
||||
descriptor.primitive.nextInChain = &clampingState;
|
||||
device.CreateRenderPipeline2(&descriptor);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue