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);
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;
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;
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)
// * 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.
//