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: