Add support for depthBiasClamp
Enabled depthBiasClamp in SwiftShader's PhysicalDeviceFeatures, which
will also enable any dEQP tests that rely on it.
Bug: b/160463658
Tests: dEQP-VK.dynamic_state.rs_state.depth_bias_clamp
Change-Id: Ida3ae12d30fb70a3bd7e508e276fb9a1bfc96231
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/46848
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Sean Risser <srisser@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Device/Context.hpp b/src/Device/Context.hpp
index 1c31201..3ca8216 100644
--- a/src/Device/Context.hpp
+++ b/src/Device/Context.hpp
@@ -103,6 +103,7 @@
float depthBias;
float slopeDepthBias;
+ float depthBiasClamp;
VkFormat renderTargetInternalFormat(int index) const;
int colorWriteActive(int index) const;
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index 825c09f..206f5d8 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -338,6 +338,7 @@
data->halfPixelY = float4(0.5f / H);
data->viewportHeight = abs(viewport.height);
data->slopeDepthBias = context->slopeDepthBias;
+ data->depthBiasClamp = context->depthBiasClamp;
data->depthRange = Z;
data->depthNear = N;
}
diff --git a/src/Device/Renderer.hpp b/src/Device/Renderer.hpp
index 367959f..da9d8fe 100644
--- a/src/Device/Renderer.hpp
+++ b/src/Device/Renderer.hpp
@@ -90,6 +90,7 @@
float slopeDepthBias;
float depthRange;
float depthNear;
+ float depthBiasClamp;
unsigned int *colorBuffer[RENDERTARGETS];
int colorPitchB[RENDERTARGETS];
diff --git a/src/Device/SetupProcessor.cpp b/src/Device/SetupProcessor.cpp
index b0d85f5..ad588b7 100644
--- a/src/Device/SetupProcessor.cpp
+++ b/src/Device/SetupProcessor.cpp
@@ -65,6 +65,7 @@
state.isDrawLine = context->isDrawLine(true);
state.isDrawTriangle = context->isDrawTriangle(true);
state.applySlopeDepthBias = context->isDrawTriangle(false) && (context->slopeDepthBias != 0.0f);
+ state.applyDepthBiasClamp = context->isDrawTriangle(false) && (context->depthBiasClamp != 0.0f);
state.interpolateZ = context->depthBufferActive() || vPosZW;
state.interpolateW = context->pixelShader != nullptr;
state.frontFace = context->frontFace;
diff --git a/src/Device/SetupProcessor.hpp b/src/Device/SetupProcessor.hpp
index 8d6a43c..50290b6 100644
--- a/src/Device/SetupProcessor.hpp
+++ b/src/Device/SetupProcessor.hpp
@@ -49,6 +49,7 @@
bool isDrawLine : 1;
bool isDrawTriangle : 1;
bool applySlopeDepthBias : 1;
+ bool applyDepthBiasClamp : 1;
bool interpolateZ : 1;
bool interpolateW : 1;
VkFrontFace frontFace : BITS(VK_FRONT_FACE_MAX_ENUM);
diff --git a/src/Pipeline/SetupRoutine.cpp b/src/Pipeline/SetupRoutine.cpp
index a34c489..ddfdef3 100644
--- a/src/Pipeline/SetupRoutine.cpp
+++ b/src/Pipeline/SetupRoutine.cpp
@@ -443,6 +443,13 @@
C = Float4(c * *Pointer<Float>(data + OFFSET(DrawData, depthRange)) + *Pointer<Float>(data + OFFSET(DrawData, depthNear)));
+ if(state.applyDepthBiasClamp)
+ {
+ Float clamp = *Pointer<Float>(data + OFFSET(DrawData, depthBiasClamp));
+ Float4 clamp4 = Float4(clamp);
+ C = IfThenElse(clamp > 0.0f, Min(clamp4, C), Max(clamp4, C));
+ }
+
*Pointer<Float4>(primitive + OFFSET(Primitive, z.C), 16) = C;
}
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index df555d0..ab9fb26 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -547,11 +547,9 @@
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS))
{
- // If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
- ASSERT(executionState.dynamicState.depthBiasClamp == 0.0f);
-
context.depthBias = executionState.dynamicState.depthBiasConstantFactor;
context.slopeDepthBias = executionState.dynamicState.depthBiasSlopeFactor;
+ context.depthBiasClamp = executionState.dynamicState.depthBiasClamp;
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS) && context.depthBoundsTestEnable)
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index e42061c..9518a95 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -76,7 +76,7 @@
VK_TRUE, // multiDrawIndirect
VK_TRUE, // drawIndirectFirstInstance
VK_FALSE, // depthClamp
- VK_FALSE, // depthBiasClamp
+ VK_TRUE, // depthBiasClamp
VK_TRUE, // fillModeNonSolid
VK_FALSE, // depthBounds
VK_FALSE, // wideLines
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index f8bb462..1bdbc16 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -260,6 +260,21 @@
context.polygonMode = rasterizationState->polygonMode;
context.depthBias = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasConstantFactor : 0.0f;
context.slopeDepthBias = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasSlopeFactor : 0.0f;
+ context.depthBiasClamp = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasClamp : 0.0f;
+
+ // From the Vulkan spec for vkCmdSetDepthBias:
+ // The bias value O for a polygon is:
+ // O = dbclamp(...)
+ // where dbclamp(x) =
+ // * x depthBiasClamp = 0 or NaN
+ // * min(x, depthBiasClamp) depthBiasClamp > 0
+ // * max(x, depthBiasClamp) depthBiasClamp < 0
+ // So it should be safe to resolve NaNs to 0.0f.
+ if(std::isnan(context.depthBiasClamp))
+ {
+ context.depthBiasClamp = 0.0f;
+ }
+
context.lineWidth = rasterizationState->lineWidth;
const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(rasterizationState->pNext);