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)