Add support for depthBias, depthBiasSlope, and depthBiasClamp
Bug: dawn:524 Change-Id: I2586aadbc326f58889314a2d10794bcc0572aaba Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28300 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
326e14f34b
commit
db2c2dd9b9
|
@ -540,6 +540,26 @@ namespace dawn_native {
|
|||
return mRasterizationState.frontFace;
|
||||
}
|
||||
|
||||
bool RenderPipelineBase::IsDepthBiasEnabled() const {
|
||||
ASSERT(!IsError());
|
||||
return mRasterizationState.depthBias != 0 || mRasterizationState.depthBiasSlopeScale != 0;
|
||||
}
|
||||
|
||||
int32_t RenderPipelineBase::GetDepthBias() const {
|
||||
ASSERT(!IsError());
|
||||
return mRasterizationState.depthBias;
|
||||
}
|
||||
|
||||
float RenderPipelineBase::GetDepthBiasSlopeScale() const {
|
||||
ASSERT(!IsError());
|
||||
return mRasterizationState.depthBiasSlopeScale;
|
||||
}
|
||||
|
||||
float RenderPipelineBase::GetDepthBiasClamp() const {
|
||||
ASSERT(!IsError());
|
||||
return mRasterizationState.depthBiasClamp;
|
||||
}
|
||||
|
||||
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
|
||||
RenderPipelineBase::GetColorAttachmentsMask() const {
|
||||
ASSERT(!IsError());
|
||||
|
|
|
@ -76,6 +76,10 @@ namespace dawn_native {
|
|||
wgpu::PrimitiveTopology GetPrimitiveTopology() const;
|
||||
wgpu::CullMode GetCullMode() const;
|
||||
wgpu::FrontFace GetFrontFace() const;
|
||||
bool IsDepthBiasEnabled() const;
|
||||
int32_t GetDepthBias() const;
|
||||
float GetDepthBiasSlopeScale() const;
|
||||
float GetDepthBiasClamp() const;
|
||||
|
||||
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> GetColorAttachmentsMask() const;
|
||||
bool HasDepthStencilAttachment() const;
|
||||
|
|
|
@ -346,10 +346,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
descriptorD3D12.RasterizerState.CullMode = D3D12CullMode(GetCullMode());
|
||||
descriptorD3D12.RasterizerState.FrontCounterClockwise =
|
||||
(GetFrontFace() == wgpu::FrontFace::CCW) ? TRUE : FALSE;
|
||||
descriptorD3D12.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
|
||||
descriptorD3D12.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||
descriptorD3D12.RasterizerState.SlopeScaledDepthBias =
|
||||
D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||
descriptorD3D12.RasterizerState.DepthBias = GetDepthBias();
|
||||
descriptorD3D12.RasterizerState.DepthBiasClamp = GetDepthBiasClamp();
|
||||
descriptorD3D12.RasterizerState.SlopeScaledDepthBias = GetDepthBiasSlopeScale();
|
||||
descriptorD3D12.RasterizerState.DepthClipEnable = TRUE;
|
||||
descriptorD3D12.RasterizerState.MultisampleEnable = (GetSampleCount() > 1) ? TRUE : FALSE;
|
||||
descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
|
||||
|
|
|
@ -1143,6 +1143,9 @@ namespace dawn_native { namespace metal {
|
|||
[encoder setDepthStencilState:newPipeline->GetMTLDepthStencilState()];
|
||||
[encoder setFrontFacingWinding:newPipeline->GetMTLFrontFace()];
|
||||
[encoder setCullMode:newPipeline->GetMTLCullMode()];
|
||||
[encoder setDepthBias:newPipeline->GetDepthBias()
|
||||
slopeScale:newPipeline->GetDepthBiasSlopeScale()
|
||||
clamp:newPipeline->GetDepthBiasClamp()];
|
||||
newPipeline->Encode(encoder);
|
||||
|
||||
lastPipeline = newPipeline;
|
||||
|
|
|
@ -264,6 +264,19 @@ namespace dawn_native { namespace opengl {
|
|||
gl.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
|
||||
}
|
||||
|
||||
if (IsDepthBiasEnabled()) {
|
||||
gl.Enable(GL_POLYGON_OFFSET_FILL);
|
||||
float depthBias = GetDepthBias();
|
||||
float slopeScale = GetDepthBiasSlopeScale();
|
||||
if (gl.PolygonOffsetClamp != nullptr) {
|
||||
gl.PolygonOffsetClamp(slopeScale, depthBias, GetDepthBiasClamp());
|
||||
} else {
|
||||
gl.PolygonOffset(slopeScale, depthBias);
|
||||
}
|
||||
} else {
|
||||
gl.Disable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
|
||||
for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
|
||||
ApplyColorState(gl, attachmentSlot, GetColorStateDescriptor(attachmentSlot));
|
||||
}
|
||||
|
|
|
@ -298,6 +298,8 @@ namespace dawn_native { namespace vulkan {
|
|||
usedKnobs.features.imageCubeArray = VK_TRUE;
|
||||
// Always require fragmentStoresAndAtomics because it is required by end2end tests.
|
||||
usedKnobs.features.fragmentStoresAndAtomics = VK_TRUE;
|
||||
// Always require depthBiasClamp because it is a core Dawn feature
|
||||
usedKnobs.features.depthBiasClamp = VK_TRUE;
|
||||
|
||||
if (IsRobustnessEnabled()) {
|
||||
usedKnobs.features.robustBufferAccess = VK_TRUE;
|
||||
|
|
|
@ -379,10 +379,10 @@ namespace dawn_native { namespace vulkan {
|
|||
rasterization.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterization.cullMode = VulkanCullMode(GetCullMode());
|
||||
rasterization.frontFace = VulkanFrontFace(GetFrontFace());
|
||||
rasterization.depthBiasEnable = VK_FALSE;
|
||||
rasterization.depthBiasConstantFactor = 0.0f;
|
||||
rasterization.depthBiasClamp = 0.0f;
|
||||
rasterization.depthBiasSlopeFactor = 0.0f;
|
||||
rasterization.depthBiasEnable = IsDepthBiasEnabled();
|
||||
rasterization.depthBiasConstantFactor = GetDepthBias();
|
||||
rasterization.depthBiasClamp = GetDepthBiasClamp();
|
||||
rasterization.depthBiasSlopeFactor = GetDepthBiasSlopeScale();
|
||||
rasterization.lineWidth = 1.0f;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisample;
|
||||
|
@ -432,12 +432,11 @@ namespace dawn_native { namespace vulkan {
|
|||
colorBlend.blendConstants[2] = 0.0f;
|
||||
colorBlend.blendConstants[3] = 0.0f;
|
||||
|
||||
// Tag all state as dynamic but stencil masks.
|
||||
// Tag all state as dynamic but stencil masks and depth bias.
|
||||
VkDynamicState dynamicStates[] = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
|
||||
VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_DEPTH_BIAS,
|
||||
VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_DEPTH_BOUNDS,
|
||||
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
|
||||
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
|
||||
VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
|
||||
VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_REFERENCE,
|
||||
};
|
||||
VkPipelineDynamicStateCreateInfo dynamic;
|
||||
dynamic.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
|
|
|
@ -275,6 +275,7 @@ source_set("dawn_end2end_tests_sources") {
|
|||
"end2end/CullingTests.cpp",
|
||||
"end2end/DebugMarkerTests.cpp",
|
||||
"end2end/DeprecatedAPITests.cpp",
|
||||
"end2end/DepthBiasTests.cpp",
|
||||
"end2end/DepthSamplingTests.cpp",
|
||||
"end2end/DepthStencilCopyTests.cpp",
|
||||
"end2end/DepthStencilStateTests.cpp",
|
||||
|
|
|
@ -0,0 +1,381 @@
|
|||
// Copyright 2020 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 "common/Constants.h"
|
||||
#include "common/Math.h"
|
||||
#include "tests/DawnTest.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/TextureFormatUtils.h"
|
||||
#include "utils/WGPUHelpers.h"
|
||||
|
||||
constexpr static unsigned int kRTSize = 2;
|
||||
|
||||
enum class QuadAngle { Flat, TiltedX };
|
||||
|
||||
class DepthBiasTests : public DawnTest {
|
||||
protected:
|
||||
void RunDepthBiasTest(wgpu::TextureFormat depthFormat,
|
||||
float depthClear,
|
||||
QuadAngle quadAngle,
|
||||
int32_t bias,
|
||||
float biasSlopeScale,
|
||||
float biasClamp) {
|
||||
const char* vertexSource = nullptr;
|
||||
switch (quadAngle) {
|
||||
case QuadAngle::Flat:
|
||||
// Draw a square at z = 0.25
|
||||
vertexSource = R"(
|
||||
#version 450
|
||||
void main() {
|
||||
const vec2 pos[6] = vec2[6](vec2(-1.f, -1.f), vec2(1.f, -1.f), vec2(-1.f, 1.f),
|
||||
vec2(-1.f, 1.f), vec2(1.f, -1.f), vec2( 1.f, 1.f));
|
||||
gl_Position = vec4(pos[gl_VertexIndex], 0.25f, 1.f);
|
||||
})";
|
||||
break;
|
||||
|
||||
case QuadAngle::TiltedX:
|
||||
// Draw a square ranging from 0 to 0.5, bottom to top
|
||||
vertexSource = R"(
|
||||
#version 450
|
||||
void main() {
|
||||
const vec3 pos[6] = vec3[6](vec3(-1.f, -1.f, 0.f ), vec3(1.f, -1.f, 0.f), vec3(-1.f, 1.f, 0.5f),
|
||||
vec3(-1.f, 1.f, 0.5f), vec3(1.f, -1.f, 0.f), vec3( 1.f, 1.f, 0.5f));
|
||||
gl_Position = vec4(pos[gl_VertexIndex], 1.f);
|
||||
})";
|
||||
break;
|
||||
}
|
||||
|
||||
wgpu::ShaderModule vertexModule =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, vertexSource);
|
||||
|
||||
wgpu::ShaderModule fragmentModule =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
fragColor = vec4(1.f, 0.f, 0.f, 1.f);
|
||||
})");
|
||||
|
||||
{
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.size = {kRTSize, kRTSize, 1};
|
||||
descriptor.format = depthFormat;
|
||||
descriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
||||
mDepthTexture = device.CreateTexture(&descriptor);
|
||||
}
|
||||
|
||||
{
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.size = {kRTSize, kRTSize, 1};
|
||||
descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
descriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
||||
mRenderTarget = device.CreateTexture(&descriptor);
|
||||
}
|
||||
|
||||
// Create a render pass which clears depth to depthClear
|
||||
utils::ComboRenderPassDescriptor renderPassDesc({mRenderTarget.CreateView()},
|
||||
mDepthTexture.CreateView());
|
||||
renderPassDesc.cDepthStencilAttachmentInfo.clearDepth = depthClear;
|
||||
|
||||
// Create a render pipeline to render the quad
|
||||
utils::ComboRenderPipelineDescriptor renderPipelineDesc(device);
|
||||
|
||||
renderPipelineDesc.cRasterizationState.depthBias = bias;
|
||||
renderPipelineDesc.cRasterizationState.depthBiasSlopeScale = biasSlopeScale;
|
||||
renderPipelineDesc.cRasterizationState.depthBiasClamp = biasClamp;
|
||||
|
||||
renderPipelineDesc.vertexStage.module = vertexModule;
|
||||
renderPipelineDesc.cFragmentStage.module = fragmentModule;
|
||||
renderPipelineDesc.cDepthStencilState.format = depthFormat;
|
||||
renderPipelineDesc.cDepthStencilState.depthWriteEnabled = true;
|
||||
|
||||
if (depthFormat != wgpu::TextureFormat::Depth32Float) {
|
||||
renderPipelineDesc.cDepthStencilState.depthCompare = wgpu::CompareFunction::Greater;
|
||||
}
|
||||
|
||||
renderPipelineDesc.depthStencilState = &renderPipelineDesc.cDepthStencilState;
|
||||
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
|
||||
|
||||
// Draw the quad (two triangles)
|
||||
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPassDesc);
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.Draw(6);
|
||||
pass.EndPass();
|
||||
|
||||
wgpu::CommandBuffer commands = commandEncoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
// Floating point depth buffers use the following formula to calculate bias
|
||||
// bias = depthBias * 2 ** (exponent(max z of primitive) - number of bits in mantissa) +
|
||||
// slopeScale * maxSlope
|
||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
|
||||
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdSetDepthBias.html
|
||||
// https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1516269-setdepthbias
|
||||
//
|
||||
// To get a final bias of 0.25 for primitives with z = 0.25, we can use
|
||||
// depthBias = 0.25 / (2 ** (-2 - 23)) = 8388608
|
||||
static constexpr int32_t kPointTwoFiveBiasForPointTwoFiveZOnFloat = 8388608;
|
||||
|
||||
wgpu::Texture mDepthTexture;
|
||||
wgpu::Texture mRenderTarget;
|
||||
};
|
||||
|
||||
// Test adding positive bias to output
|
||||
TEST_P(DepthBiasTests, PositiveBiasOnFloat) {
|
||||
// NVIDIA GPUs under Vulkan seem to be using a different scale than everyone else.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsNvidia());
|
||||
|
||||
// SwiftShader incorrectly uses depthBias directly when calculating bias.
|
||||
// TODO(enrico.galli@intel.com): Remove once it has been fixed upstream.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsSwiftshader());
|
||||
|
||||
// OpenGL uses a different scale than the other APIs
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
|
||||
// Draw quad flat on z = 0.25 with 0.25 bias
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0, QuadAngle::Flat,
|
||||
kPointTwoFiveBiasForPointTwoFiveZOnFloat, 0, 0);
|
||||
|
||||
// Quad at z = 0.25 + 0.25 bias = 0.5
|
||||
std::vector<float> expected = {
|
||||
0.5, 0.5, //
|
||||
0.5, 0.5, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding positive bias to output with a clamp
|
||||
TEST_P(DepthBiasTests, PositiveBiasOnFloatWithClamp) {
|
||||
// SwiftShader incorrectly uses depthBias directly when calculating bias.
|
||||
// TODO(enrico.galli@intel.com): Remove once it has been fixed upstream.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsSwiftshader());
|
||||
|
||||
// Clamping support in OpenGL is spotty
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
|
||||
// Draw quad flat on z = 0.25 with 0.25 bias clamped at 0.125.
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0, QuadAngle::Flat,
|
||||
kPointTwoFiveBiasForPointTwoFiveZOnFloat, 0, 0.125);
|
||||
|
||||
// Quad at z = 0.25 + min(0.25 bias, 0.125 clamp) = 0.375
|
||||
std::vector<float> expected = {
|
||||
0.375, 0.375, //
|
||||
0.375, 0.375, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding negative bias to output
|
||||
TEST_P(DepthBiasTests, NegativeBiasOnFloat) {
|
||||
// NVIDIA GPUs seems to be using a different scale than everyone else
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsNvidia());
|
||||
|
||||
// SwiftShader incorrectly uses depthBias directly when calculating bias.
|
||||
// TODO(enrico.galli@intel.com): Remove once it has been fixed upstream.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsSwiftshader());
|
||||
|
||||
// OpenGL uses a different scale than the other APIs
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
|
||||
// Draw quad flat on z = 0.25 with -0.25 bias, depth clear of 0.125
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0.125, QuadAngle::Flat,
|
||||
-kPointTwoFiveBiasForPointTwoFiveZOnFloat, 0, 0);
|
||||
|
||||
// Quad at z = 0.25 - 0.25 bias = 0
|
||||
std::vector<float> expected = {
|
||||
0.0, 0.0, //
|
||||
0.0, 0.0, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding negative bias to output with a clamp
|
||||
TEST_P(DepthBiasTests, NegativeBiasOnFloatWithClamp) {
|
||||
// SwiftShader incorrectly uses depthBias directly when calculating bias.
|
||||
// TODO(enrico.galli@intel.com): Remove once it has been fixed upstream.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsSwiftshader());
|
||||
|
||||
// Clamping support in OpenGL is spotty
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
|
||||
// Draw quad flat on z = 0.25 with -0.25 bias clamped at -0.125.
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0, QuadAngle::Flat,
|
||||
-kPointTwoFiveBiasForPointTwoFiveZOnFloat, 0, -0.125);
|
||||
|
||||
// Quad at z = 0.25 + max(-0.25 bias, -0.125 clamp) = 0.125
|
||||
std::vector<float> expected = {
|
||||
0.125, 0.125, //
|
||||
0.125, 0.125, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding positive infinite slope bias to output
|
||||
TEST_P(DepthBiasTests, PositiveInfinitySlopeBiasOnFloat) {
|
||||
// SwiftShader incorrectly uses depthBias directly when calculating bias.
|
||||
// TODO(enrico.galli@intel.com): Remove once it has been fixed upstream.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsSwiftshader());
|
||||
|
||||
// NVIDIA GPUs do not clamp values to 1 when using Inf slope bias.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsNvidia());
|
||||
|
||||
// Draw quad with z from 0 to 0.5 with inf slope bias
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0.125, QuadAngle::TiltedX, 0,
|
||||
std::numeric_limits<float>::infinity(), 0);
|
||||
|
||||
// Value at the center of the pixel + (0.25 slope * Inf slope bias) = 1 (clamped)
|
||||
std::vector<float> expected = {
|
||||
1.0, 1.0, //
|
||||
1.0, 1.0, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding positive infinite slope bias to output
|
||||
TEST_P(DepthBiasTests, NegativeInfinityBiasOnFloat) {
|
||||
// SwiftShader incorrectly uses depthBias directly when calculating bias.
|
||||
// TODO(enrico.galli@intel.com): Remove once it has been fixed upstream.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsSwiftshader());
|
||||
|
||||
// NVIDIA GPUs do not clamp values to 0 when using -Inf slope bias.
|
||||
DAWN_SKIP_TEST_IF(IsVulkan() && IsNvidia());
|
||||
|
||||
// Draw quad with z from 0 to 0.5 with -inf slope bias
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0.125, QuadAngle::TiltedX, 0,
|
||||
-std::numeric_limits<float>::infinity(), 0);
|
||||
|
||||
// Value at the center of the pixel + (0.25 slope * -Inf slope bias) = 0 (clamped)
|
||||
std::vector<float> expected = {
|
||||
0.0, 0.0, //
|
||||
0.0, 0.0, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test tiledX quad with no bias
|
||||
TEST_P(DepthBiasTests, NoBiasTiltedXOnFloat) {
|
||||
// Draw quad with z from 0 to 0.5 with no bias
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0, QuadAngle::TiltedX, 0, 0, 0);
|
||||
|
||||
// Depth values of TiltedX quad. Values at the center of the pixels.
|
||||
std::vector<float> expected = {
|
||||
0.375, 0.375, //
|
||||
0.125, 0.125, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding positive slope bias to output
|
||||
TEST_P(DepthBiasTests, PositiveSlopeBiasOnFloat) {
|
||||
// Draw quad with z from 0 to 0.5 with a slope bias of 1
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0, QuadAngle::TiltedX, 0, 1, 0);
|
||||
|
||||
// Value at the center of the pixel + (0.25 slope * 1.0 slope bias)
|
||||
std::vector<float> expected = {
|
||||
0.625, 0.625, //
|
||||
0.375, 0.375, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding negative half slope bias to output
|
||||
TEST_P(DepthBiasTests, NegativeHalfSlopeBiasOnFloat) {
|
||||
// Draw quad with z from 0 to 0.5 with a slope bias of -0.5
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0, QuadAngle::TiltedX, 0, -0.5, 0);
|
||||
|
||||
// Value at the center of the pixel + (0.25 slope * -0.5 slope bias)
|
||||
std::vector<float> expected = {
|
||||
0.25, 0.25, //
|
||||
0.0, 0.0, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_EQ(expected.data(), mDepthTexture, 0, 0, kRTSize, kRTSize, 0, 0,
|
||||
wgpu::TextureAspect::DepthOnly);
|
||||
}
|
||||
|
||||
// Test adding positive bias to output
|
||||
TEST_P(DepthBiasTests, PositiveBiasOn24bit) {
|
||||
// Draw quad flat on z = 0.25 with 0.25 bias
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth24PlusStencil8, 0.4f, QuadAngle::Flat,
|
||||
0.25f * (1 << 25), 0, 0);
|
||||
|
||||
// Only the bottom left quad has colors. 0.5 quad > 0.4 clear.
|
||||
// TODO(enrico.galli@intel.com): Switch to depth sampling once feature has been enabled.
|
||||
std::vector<RGBA8> expected = {
|
||||
RGBA8::kRed, RGBA8::kRed, //
|
||||
RGBA8::kRed, RGBA8::kRed, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), mRenderTarget, 0, 0, kRTSize, kRTSize, 0, 0);
|
||||
}
|
||||
|
||||
// Test adding positive bias to output with a clamp
|
||||
TEST_P(DepthBiasTests, PositiveBiasOn24bitWithClamp) {
|
||||
// Clamping support in OpenGL is spotty
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
|
||||
// Draw quad flat on z = 0.25 with 0.25 bias clamped at 0.125.
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth24PlusStencil8, 0.4f, QuadAngle::Flat,
|
||||
0.25f * (1 << 25), 0, 0.1f);
|
||||
|
||||
// Since we cleared with a depth of 0.4 and clamped bias at 0.4, the depth test will fail. 0.25
|
||||
// + 0.125 < 0.4 clear.
|
||||
// TODO(enrico.galli@intel.com): Switch to depth sampling once feature has been enabled.
|
||||
std::vector<RGBA8> zero = {
|
||||
RGBA8::kZero, RGBA8::kZero, //
|
||||
RGBA8::kZero, RGBA8::kZero, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_RGBA8_EQ(zero.data(), mRenderTarget, 0, 0, kRTSize, kRTSize, 0, 0);
|
||||
}
|
||||
|
||||
// Test adding positive bias to output
|
||||
TEST_P(DepthBiasTests, PositiveSlopeBiasOn24bit) {
|
||||
// Draw quad with z from 0 to 0.5 with a slope bias of 1
|
||||
RunDepthBiasTest(wgpu::TextureFormat::Depth24PlusStencil8, 0.4f, QuadAngle::TiltedX, 0, 1, 0);
|
||||
|
||||
// Only the top half of the quad has a depth > 0.4 clear
|
||||
// TODO(enrico.galli@intel.com): Switch to depth sampling once feature has been enabled.
|
||||
std::vector<RGBA8> expected = {
|
||||
RGBA8::kRed, RGBA8::kRed, //
|
||||
RGBA8::kZero, RGBA8::kZero, //
|
||||
};
|
||||
|
||||
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), mRenderTarget, 0, 0, kRTSize, kRTSize, 0, 0);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(DepthBiasTests,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
OpenGLBackend(),
|
||||
VulkanBackend());
|
Loading…
Reference in New Issue