Expose float preserve capability

SwiftShader doesn't perform any fast-math optimizations that would cause
Inf/Nan and negative 0 values to be unpreserved.

Bug: b/236958241
Tests:
dEQP-VK.spirv_assembly.instruction.compute.float_controls_extensionless.*
Tests: dEQP-VK.spirv_assembly.instruction.compute.float_controls.*
Tests: dEQP-VK.spirv_assembly.instruction.graphics.float_controls.*

Change-Id: Ib4be6d2b3b795686c4caf0cbd79caeaf3018f812
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/66908
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Sean Risser <srisser@google.com>
Tested-by: Sean Risser <srisser@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 9dac05c..6265a04 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -446,6 +446,7 @@
 				case spv::CapabilityGroupNonUniformQuad: capabilities.GroupNonUniformQuad = true; break;
 				case spv::CapabilityDeviceGroup: capabilities.DeviceGroup = true; break;
 				case spv::CapabilityMultiView: capabilities.MultiView = true; break;
+				case spv::CapabilitySignedZeroInfNanPreserve: capabilities.SignedZeroInfNanPreserve = true; break;
 				case spv::CapabilityDemoteToHelperInvocation: capabilities.DemoteToHelperInvocation = true; break;
 				case spv::CapabilityStencilExportEXT: capabilities.StencilExportEXT = true; break;
 				case spv::CapabilityVulkanMemoryModel: capabilities.VulkanMemoryModel = true; break;
@@ -1059,6 +1060,9 @@
 	case spv::ExecutionModeOriginUpperLeft:
 		// This is always the case for a Vulkan shader. Do nothing.
 		break;
+	case spv::ExecutionModeSignedZeroInfNanPreserve:
+		// We currently don't perform any aggressive fast-math optimizations.
+		break;
 	default:
 		UNREACHABLE("Execution mode: %d", int(mode));
 	}
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 5d8ddae..02445be 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -720,6 +720,7 @@
 		bool GroupNonUniformQuad : 1;
 		bool DeviceGroup : 1;
 		bool MultiView : 1;
+		bool SignedZeroInfNanPreserve : 1;
 		bool DemoteToHelperInvocation : 1;
 		bool StencilExportEXT : 1;
 		bool VulkanMemoryModel : 1;
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 12f5bf1..6c2941f 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -1109,9 +1109,9 @@
 	// or rounding controls.
 	properties->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
 	properties->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
-	properties->shaderSignedZeroInfNanPreserveFloat16 = VK_FALSE;
-	properties->shaderSignedZeroInfNanPreserveFloat32 = VK_FALSE;
-	properties->shaderSignedZeroInfNanPreserveFloat64 = VK_FALSE;
+	properties->shaderSignedZeroInfNanPreserveFloat16 = VK_TRUE;
+	properties->shaderSignedZeroInfNanPreserveFloat32 = VK_TRUE;
+	properties->shaderSignedZeroInfNanPreserveFloat64 = VK_TRUE;
 	properties->shaderDenormPreserveFloat16 = VK_FALSE;
 	properties->shaderDenormPreserveFloat32 = VK_FALSE;
 	properties->shaderDenormPreserveFloat64 = VK_FALSE;