Enable sampling and filtering of 16-bit SNORM formats

Also fix clamping of the smallest negative value to -1.0.
See https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#fundamentals-fixedfpconv

Bug: b/167582422
Tests: dEQP-VK.*
Change-Id: Ie77a048c2a3111c19554329e73d81a864f69cf94
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/50948
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 f3c32ee..7bdc302 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -178,6 +178,14 @@
 					c.z *= Float4(1.0f / 0xFF00u);
 					c.w *= Float4(1.0f / 0xFF00u);
 					break;
+				case VK_FORMAT_R16_SNORM:
+				case VK_FORMAT_R16G16_SNORM:
+				case VK_FORMAT_R16G16B16A16_SNORM:
+					c.x = Max(c.x * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+					c.y = Max(c.y * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+					c.z = Max(c.z * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+					c.w = Max(c.w * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+					break;
 				default:
 					for(int component = 0; component < textureComponentCount(); component++)
 					{
@@ -232,6 +240,14 @@
 				c.z = Float4(As<UShort4>(cs.z)) * Float4(1.0f / 0xFF00u);
 				c.w = Float4(As<UShort4>(cs.w)) * Float4(1.0f / 0xFF00u);
 				break;
+			case VK_FORMAT_R16_SNORM:
+			case VK_FORMAT_R16G16_SNORM:
+			case VK_FORMAT_R16G16B16A16_SNORM:
+				c.x = Max(Float4(cs.x) * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+				c.y = Max(Float4(cs.y) * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+				c.z = Max(Float4(cs.z) * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+				c.w = Max(Float4(cs.w) * Float4(1.0f / 0x7FFF), Float4(-1.0f));
+				break;
 			default:
 				for(int component = 0; component < textureComponentCount(); component++)
 				{
diff --git a/src/Vulkan/VkFormat.cpp b/src/Vulkan/VkFormat.cpp
index 3f6f7e9..a8c211b 100644
--- a/src/Vulkan/VkFormat.cpp
+++ b/src/Vulkan/VkFormat.cpp
@@ -2097,6 +2097,7 @@
 		case VK_FORMAT_R16G16_UNORM:
 		case VK_FORMAT_R16G16_SNORM:
 		case VK_FORMAT_R16G16B16A16_UNORM:
+		case VK_FORMAT_R16G16B16A16_SNORM:
 		case VK_FORMAT_R32_SINT:
 		case VK_FORMAT_R32_UINT:
 		case VK_FORMAT_R32G32_SINT:
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 04844e8..f1bb800 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -793,10 +793,13 @@
 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
 		case VK_FORMAT_R16_UNORM:
+		case VK_FORMAT_R16_SNORM:
 		case VK_FORMAT_R16_SFLOAT:
 		case VK_FORMAT_R16G16_UNORM:
+		case VK_FORMAT_R16G16_SNORM:
 		case VK_FORMAT_R16G16_SFLOAT:
 		case VK_FORMAT_R16G16B16A16_UNORM:
+		case VK_FORMAT_R16G16B16A16_SNORM:
 		case VK_FORMAT_R16G16B16A16_SFLOAT:
 		case VK_FORMAT_R32_SFLOAT:
 		case VK_FORMAT_R32G32_SFLOAT: