Implement samplerMirrorClampToEdge

This is an optional Vulkan 1.2 feature and also available through the
VK_KHR_sampler_mirror_clamp_to_edge extension.

The addressing code for 16-bit coordinates was (still) correct from the
Direct3D 9 days, but the 32-bit path needed fixing.

Bug: b/194635449
Tests: dEQP-VK.*mirror_clamp_to_edge*
Change-Id: I06f7afbbc26455ba69b2819f11713996d023c43a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/61048
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 8c49337..c6f82ff 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -2340,10 +2340,8 @@
 					break;
 				case ADDRESSING_MIRRORONCE:
 					{
-						Float4 half = As<Float4>(Int4(halfBits));
 						Float4 one = As<Float4>(Int4(oneBits));
-						Float4 two = As<Float4>(Int4(twoBits));
-						coord = one - Abs(two * Frac(Min(Max(coord, -one), two) * half) - one);
+						coord = Min(Abs(coord), one);
 					}
 					break;
 				case ADDRESSING_BORDER:
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 8169fed..b61fefe 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -304,7 +304,7 @@
 template<typename T>
 static void getPhysicalDeviceVulkan12Features(T *features)
 {
-	features->samplerMirrorClampToEdge = VK_FALSE;
+	features->samplerMirrorClampToEdge = VK_TRUE;
 	features->drawIndirectCount = VK_FALSE;
 	getPhysicalDevice8BitStorageFeaturesKHR(features);
 	getPhysicalDeviceShaderAtomicInt64Features(features);
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 33de5c9..90089ed 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -423,6 +423,7 @@
 	{ { VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION } },
 	{ { VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME, VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION } },
 	{ { VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION } },
+	{ { VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION } },
 };
 
 static uint32_t numSupportedExtensions(const ExtensionProperties *extensionProperties, uint32_t extensionPropertiesCount)