Allow fp16 denorm inputs to be flushed to zero.
authorStephen Clarke <stephen.clarke@imgtec.com>
Fri, 15 Jun 2018 13:09:03 +0000 (14:09 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 28 Jun 2018 11:26:11 +0000 (07:26 -0400)
Added a new version of Compare16BitFloat for an fp16 input and a float
result.  Previously, the code was using the version for a float input
with an fp result and switching the original and returned values.
But this function is not symmetric: e.g. a denorm input and zero result
should be allowed, but a zero input and denorm result should not be
allowed.
Also removed the rounding modes parameter, since conversion from fp16
to float is exact.

Affects:
dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.uniform_16struct_to_32struct.*
dEQP-VK.spirv_assembly.instruction.compute.16bit_storage.uniform_32struct_to_16struct.*
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.uniform_16struct_to_32struct.*
dEQP-VK.spirv_assembly.instruction.graphics.16bit_storage.uniform_32struct_to_16struct.*

Components: Vulkan

VK-GL-CTS issue: 1219

Change-Id: I96d01bb428b550de1e86a601b929d08b3131870d

external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm16bitStorageTests.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmGraphicsShaderTestUtil.hpp

index cf47ceaeaf6bcf25dfcd26ed7b434375737b0ea4..2fb78fe2c637bfbe25fd2edb0d7ec2fb026c2843 100644 (file)
@@ -106,12 +106,13 @@ bool compare16Bit (float original, deUint16 returned, RoundingModeFlags flags, t
        return compare16BitFloat (original, returned, flags, log);
 }
 
-bool compare16Bit (deFloat16 returned, float original, RoundingModeFlags flags, tcu::TestLog& log)
+bool compare16Bit (deUint16 original, float returned, RoundingModeFlags flags, tcu::TestLog& log)
 {
-       return compare16BitFloat (original, returned, flags, log);
+       DE_UNREF(flags);
+       return compare16BitFloat (original, returned, log);
 }
 
-bool compare16Bit (deInt16 returned, deInt16 original, RoundingModeFlags flags, tcu::TestLog& log)
+bool compare16Bit (deInt16 original, deInt16 returned, RoundingModeFlags flags, tcu::TestLog& log)
 {
        DE_UNREF(flags);
        DE_UNREF(log);
index adc792077fb1dc7caffb3e2e42ac8d40184750d3..8de4d5c5f6848d98874396cf44d578e34c5cff14 100644 (file)
@@ -2077,7 +2077,8 @@ bool compare16BitFloat (deUint16 original, deUint16 returned, tcu::TestLog& log)
                return false;
        }
 
-       // Any denormalized value input into a shader may be flushed to 0.
+       // Any denormalized value input into a shader or potentially generated by any instruction in a shader
+       // may be flushed to 0.
        if (originalFloat.isDenorm() && returnedFloat.isZero())
                return true;
 
@@ -2101,10 +2102,6 @@ bool compare16BitFloat (deUint16 original, deUint16 returned, tcu::TestLog& log)
                return false;
        }
 
-       // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
-       if (originalFloat.isDenorm() && returnedFloat.isZero())
-               return true;
-
        // If not matched in the above cases, they should have the same bit pattern.
        if (originalFloat.bits() == returnedFloat.bits())
                return true;
@@ -2113,9 +2110,52 @@ bool compare16BitFloat (deUint16 original, deUint16 returned, tcu::TestLog& log)
        return false;
 }
 
-bool compare16BitFloat (deFloat16 returned, float original, RoundingModeFlags flags, tcu::TestLog& log)
+bool compare16BitFloat(deUint16 original, float returned, tcu::TestLog & log)
 {
-       return compare16BitFloat (original, (deUint16)returned, flags, log);
+       const Float16   originalFloat   (original);
+       const Float32   returnedFloat   (returned);
+
+       // Zero are turned into zero under both RTE and RTZ.
+       if (originalFloat.isZero())
+       {
+               if (returnedFloat.isZero())
+                       return true;
+
+               log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
+               return false;
+       }
+
+       // Any denormalized value input into a shader may be flushed to 0.
+       if (originalFloat.isDenorm() && returnedFloat.isZero())
+               return true;
+
+       // Inf are always turned into Inf with the same sign, too.
+       if (originalFloat.isInf())
+       {
+               if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
+                       return true;
+
+               log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
+               return false;
+       }
+
+       // NaN are always turned into NaN, too.
+       if (originalFloat.isNaN())
+       {
+               if (returnedFloat.isNaN())
+                       return true;
+
+               log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
+               return false;
+       }
+
+       // In all other cases, conversion should be exact.
+       const Float32 expectedFloat (deFloat16To32(original));
+       if (expectedFloat.bits() == returnedFloat.bits())
+               return true;
+
+       log << TestLog::Message << "Error: found unmatched 16-bit and 32-bit floats: " << original << " vs " << returnedFloat.bits() << TestLog::EndMessage;
+       return false;
 }
 
 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log)
index 17229b9c74b4ee6ef77b36d7ec0c1de7c17e1ad4..ad8321673abd64723b8b7880d2f0f1d92050a55c 100644 (file)
@@ -602,7 +602,19 @@ void addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const std::ma
 // * Different bit patterns of NaNs are allowed.
 // * For the rest, require exactly the same bit pattern.
 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log);
-bool compare16BitFloat (deFloat16 returned, float original, RoundingModeFlags flags, tcu::TestLog& log);
+
+// Given the original 16-bit float value, computes the corresponding 32-bit
+// float value and compares with the returned 32-bit float value.
+// Returns true if they are considered as equal.
+//
+// The following equivalence criteria are respected:
+// * Positive and negative zeros are considered equivalent.
+// * Denormalized floats are allowed to be flushed to zeros, including
+//   * Inputted 16bit denormalized float
+//   * Generated 32bit denormalized float
+// * Different bit patterns of NaNs are allowed.
+// * For the rest, require exactly the same bit pattern.
+bool compare16BitFloat (deUint16 returned, float original, tcu::TestLog& log);
 
 // Compare the returned 32-bit float against its expected value.
 //