Implement VK_EXT_depth_range_unrestricted This extension allows the viewport's minimum and maximum depth to be outside of the 0.0 to 1.0 range: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_EXT_depth_range_unrestricted.html Note that while most extensions don't change the behavior of the logical device whether they're enabled or not (since they just allow new calls, enums, or values which are otherwise undefined behavior and implementing the functionality of the extension is valid as "undefined" behavior), enabling/disabling this extension does cause an observable difference. Bug: b/163135814 Tests: dEQP-VK.*depth_range_unrestricted* Change-Id: I418a2e7226140719af08601d8919f4cdbc7a237c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/47608 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: Nicolas Capens <nicolascapens@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/Context.hpp b/src/Device/Context.hpp index 3ca8216..8b32b29 100644 --- a/src/Device/Context.hpp +++ b/src/Device/Context.hpp
@@ -104,6 +104,7 @@ float depthBias; float slopeDepthBias; float depthBiasClamp; + bool depthRangeUnrestricted; VkFormat renderTargetInternalFormat(int index) const; int colorWriteActive(int index) const;
diff --git a/src/Device/PixelProcessor.cpp b/src/Device/PixelProcessor.cpp index bccdb3f..6665777 100644 --- a/src/Device/PixelProcessor.cpp +++ b/src/Device/PixelProcessor.cpp
@@ -115,6 +115,10 @@ state.depthTestActive = true; state.depthCompareMode = context->depthCompareMode; state.depthFormat = context->depthBuffer->getFormat(); + + // "For fixed-point depth buffers, fragment depth values are always limited to the range [0,1] by clamping after depth bias addition is performed. + // Unless the VK_EXT_depth_range_unrestricted extension is enabled, fragment depth values are clamped even when the depth buffer uses a floating-point representation." + state.depthClamp = !state.depthFormat.isFloatFormat() || !context->depthRangeUnrestricted; } state.occlusionEnabled = context->occlusionEnabled;
diff --git a/src/Device/PixelProcessor.hpp b/src/Device/PixelProcessor.hpp index 3db3b5f..b2656aa 100644 --- a/src/Device/PixelProcessor.hpp +++ b/src/Device/PixelProcessor.hpp
@@ -92,7 +92,8 @@ bool alphaToCoverage; bool centroid; VkFrontFace frontFace; - VkFormat depthFormat; + vk::Format depthFormat; + bool depthClamp; }; struct State : States
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp index e888883..7d9f349 100644 --- a/src/Pipeline/PixelRoutine.cpp +++ b/src/Pipeline/PixelRoutine.cpp
@@ -90,7 +90,7 @@ x -= *Pointer<Float4>(constants + OFFSET(Constants, X) + q * sizeof(float4)); } - z[q] = interpolate(x, Dz[q], z[q], primitive + OFFSET(Primitive, z), false, false, true); + z[q] = interpolate(x, Dz[q], z[q], primitive + OFFSET(Primitive, z), false, false, state.depthClamp); } }
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp index dc07a78..48a98b0 100644 --- a/src/Vulkan/VkPipeline.cpp +++ b/src/Vulkan/VkPipeline.cpp
@@ -261,6 +261,7 @@ 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; + context.depthRangeUnrestricted = device->hasExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); // From the Vulkan spec for vkCmdSetDepthBias: // The bias value O for a polygon is:
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp index 8b194a5..38037d3 100644 --- a/src/Vulkan/libVulkan.cpp +++ b/src/Vulkan/libVulkan.cpp
@@ -378,6 +378,7 @@ #endif { VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION }, { VK_GOOGLE_SAMPLER_FILTERING_PRECISION_EXTENSION_NAME, VK_GOOGLE_SAMPLER_FILTERING_PRECISION_SPEC_VERSION }, + { VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION } }; static bool hasExtension(const char *extensionName, const VkExtensionProperties *extensionProperties, uint32_t extensionPropertiesCount)