aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Byszewski <piotr.byszewski@mobica.com>2023-04-21 11:47:30 +0200
committerPiotr Byszewski <piotr.byszewski@mobica.com>2023-04-21 11:47:30 +0200
commit4bc032d6e16609ff11f3447e20b0c895d231a86a (patch)
tree5bc7b7ef8dbe37f7489ab7b112dd33db42212eb1
parent1dbd69823db8dd1058994fbc904527d7a0e7d681 (diff)
parente46697b72bf6e3966d233e226a20139a08984299 (diff)
downloaddeqp-4bc032d6e16609ff11f3447e20b0c895d231a86a.tar.gz
Merge vk-gl-cts/vulkan-cts-1.3.1 into vk-gl-cts/vulkan-cts-1.3.2
Change-Id: Ic89a637988dbb5a5fa4e06689b4e3c23f5eb2d3d
-rw-r--r--external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm16bitStorageTests.cpp12
-rw-r--r--external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp179
-rw-r--r--external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp30
-rw-r--r--framework/delibs/debase/deFloat16.h59
4 files changed, 187 insertions, 93 deletions
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm16bitStorageTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm16bitStorageTests.cpp
index cebb0d50c..4cdff5607 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm16bitStorageTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsm16bitStorageTests.cpp
@@ -3603,7 +3603,9 @@ void addGraphics16BitStorageInputOutputFloat32To16Group (tcu::TestCaseGroup* tes
vector<string> extensions;
map<string, string> fragments = passthruFragments();
const deUint32 numDataPoints = 64;
- vector<float> float32Data = getFloat32s(rnd, numDataPoints);
+ // Special values like inf/nan/denormal may not be preserved when float control features are not provided,
+ // thus values generating special float16 values must be excluded in input data here.
+ vector<float> float32Data = getFloat32s(rnd, numDataPoints, DE_FALSE);
extensions.push_back("VK_KHR_16bit_storage");
@@ -3879,7 +3881,9 @@ void addGraphics16BitStorageInputOutputFloat16To16Group (tcu::TestCaseGroup* tes
vector<string> extensions;
map<string, string> fragments = passthruFragments();
const deUint32 numDataPoints = 64;
- vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints));
+ // Special values like inf/nan/denormal may not be preserved when float control features are not provided,
+ // thus those values must be excluded in the input data here.
+ vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints, DE_FALSE));
VulkanFeatures requiredFeatures;
requiredFeatures.ext16BitStorage.storageInputOutput16 = true;
@@ -7952,7 +7956,9 @@ void addGraphics16BitStorageInputOutputFloat64To16Group (tcu::TestCaseGroup* tes
vector<string> extensions;
map<string, string> fragments = passthruFragments();
const deUint32 numDataPoints = 64;
- vector<double> float64Data = getFloat64s(rnd, numDataPoints);
+ // Special values like inf/nan/denormal may not be preserved when float control features are not provided,
+ // thus values generating special float16 values must be excluded in input data here.
+ vector<double> float64Data = getFloat64s(rnd, numDataPoints, DE_FALSE);
extensions.push_back("VK_KHR_16bit_storage");
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
index c80786d8b..997ccad7e 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.cpp
@@ -468,19 +468,19 @@ std::vector<deInt8> getInt8s (de::Random& rnd, const deUint32 count)
// Generate and return 64-bit floats
//
-// The first 24 number pairs are manually picked, while the rest are randomly generated.
-// Expected count to be at least 24 (numPicks).
-std::vector<double> getFloat64s (de::Random& rnd, deUint32 count)
+// If includeSpecialFloat16Values is false, random float64 that can be converted to float16 inf/nan/denormal must be excluded
+// since inf may be clamped, and nan/denormal be flushed without float control features.
+// And expected count to be at least 14 (numPicks).
+// Otherwise, the first 24 number pairs are manually picked, while the rest are randomly generated.
+// And expected count to be at least 24 (numPicks).
+std::vector<double> getFloat64s (de::Random& rnd, deUint32 count, deBool includeSpecialFloat16Values)
{
std::vector<double> float64;
float64.reserve(count);
- if (count >= 24)
+ if (includeSpecialFloat16Values)
{
- // Zero
- float64.push_back(0.f);
- float64.push_back(-0.f);
// Infinity
float64.push_back(std::numeric_limits<double>::infinity());
float64.push_back(-std::numeric_limits<double>::infinity());
@@ -490,44 +490,52 @@ std::vector<double> getFloat64s (de::Random& rnd, deUint32 count)
// QNaN
float64.push_back(std::numeric_limits<double>::quiet_NaN());
float64.push_back(-std::numeric_limits<double>::quiet_NaN());
-
- // Denormalized 64-bit float matching 0 in 16-bit
- float64.push_back(ldexp((double)1.f, -1023));
- float64.push_back(-ldexp((double)1.f, -1023));
-
- // Normalized 64-bit float matching 0 in 16-bit
- float64.push_back(ldexp((double)1.f, -100));
- float64.push_back(-ldexp((double)1.f, -100));
// Normalized 64-bit float with exact denormalized match in 16-bit
float64.push_back(bitwiseCast<double>(deUint64(0x3B0357C299A88EA8)));
float64.push_back(bitwiseCast<double>(deUint64(0xBB0357C299A88EA8)));
-
- // Normalized 64-bit float with exact normalized match in 16-bit
- float64.push_back(ldexp((double)1.f, -14)); // 2e-14: minimum 16-bit positive normalized
- float64.push_back(-ldexp((double)1.f, -14)); // 2e-14: maximum 16-bit negative normalized
- // Normalized 64-bit float falling above half way within two 16-bit normalized
- float64.push_back(bitwiseCast<double>(deUint64(0x3FD2000000000000)));
- float64.push_back(bitwiseCast<double>(deUint64(0xBFD2000000000000)));
- // Normalized 64-bit float falling exact half way within two 16-bit normalized
- float64.push_back(bitwiseCast<double>(deUint64(0x3F100C0000000000)));
- float64.push_back(bitwiseCast<double>(deUint64(0xBF100C0000000000)));
- // Some number
- float64.push_back((double)0.28125f);
- float64.push_back((double)-0.28125f);
// Normalized 64-bit float matching infinity in 16-bit
float64.push_back(ldexp((double)1.f, 100));
float64.push_back(-ldexp((double)1.f, 100));
}
+ // Zero
+ float64.push_back(0.f);
+ float64.push_back(-0.f);
+ // Denormalized 64-bit float matching 0 in 16-bit
+ float64.push_back(ldexp((double)1.f, -1023));
+ float64.push_back(-ldexp((double)1.f, -1023));
+ // Normalized 64-bit float matching 0 in 16-bit
+ float64.push_back(ldexp((double)1.f, -100));
+ float64.push_back(-ldexp((double)1.f, -100));
+ // Normalized 64-bit float with exact normalized match in 16-bit
+ float64.push_back(ldexp((double)1.f, -14)); // 2e-14: minimum 16-bit positive normalized
+ float64.push_back(-ldexp((double)1.f, -14)); // 2e-14: maximum 16-bit negative normalized
+ // Normalized 64-bit float falling above half way within two 16-bit normalized
+ float64.push_back(bitwiseCast<double>(deUint64(0x3FD2000000000000)));
+ float64.push_back(bitwiseCast<double>(deUint64(0xBFD2000000000000)));
+ // Normalized 64-bit float falling exact half way within two 16-bit normalized
+ float64.push_back(bitwiseCast<double>(deUint64(0x3F100C0000000000)));
+ float64.push_back(bitwiseCast<double>(deUint64(0xBF100C0000000000)));
+ // Some number
+ float64.push_back((double)0.28125f);
+ float64.push_back((double)-0.28125f);
const deUint32 numPicks = static_cast<deUint32>(float64.size());
DE_ASSERT(count >= numPicks);
count -= numPicks;
- for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
+ for (deUint32 numNdx = 0; numNdx < count;)
{
- double randValue = rnd.getDouble();
- float64.push_back(randValue);
+ double rndFloat = rnd.getDouble();
+ // If special float16 values must be excluded, generated double values that result in inf/nan/denormal of float16 should be removed.
+ if (!includeSpecialFloat16Values)
+ {
+ deFloat16 rndFloat16 = deFloat64To16(rndFloat);
+ if (deHalfIsInf(rndFloat16) || deHalfIsIEEENaN(rndFloat16) || deHalfIsDenormal(rndFloat16))
+ continue;
+ }
+ float64.push_back(rndFloat);
+ ++numNdx;
}
return float64;
@@ -558,37 +566,44 @@ std::vector<double> getFloat64s (de::Random& rnd, deUint32 count)
// Generate and return 32-bit floats
//
-// The first 24 number pairs are manually picked, while the rest are randomly generated.
-// Expected count to be at least 24 (numPicks).
-std::vector<float> getFloat32s (de::Random& rnd, deUint32 count)
+// If includeSpecialFloat16Values is false, random float32 that can be converted to float16 inf/nan/denormal must be excluded
+// since inf may be clamped, and nan/denormal be flushed without float control features.
+// And expected count to be at least 14 (numPicks).
+// Otherwise, the first 24 number pairs are manually picked, while the rest are randomly generated.
+// And expected count to be at least 24 (numPicks).
+std::vector<float> getFloat32s (de::Random& rnd, deUint32 count, deBool includeSpecialFloat16Values)
{
std::vector<float> float32;
float32.reserve(count);
+ if (includeSpecialFloat16Values)
+ {
+ // Infinity
+ float32.push_back(std::numeric_limits<float>::infinity());
+ float32.push_back(-std::numeric_limits<float>::infinity());
+ // SNaN
+ float32.push_back(std::numeric_limits<float>::signaling_NaN());
+ float32.push_back(-std::numeric_limits<float>::signaling_NaN());
+ // QNaN
+ float32.push_back(std::numeric_limits<float>::quiet_NaN());
+ float32.push_back(-std::numeric_limits<float>::quiet_NaN());
+ // Normalized 32-bit float with exact denormalized match in 16-bit
+ float32.push_back(deFloatLdExp(1.f, -24)); // 2e-24: minimum 16-bit positive denormalized
+ float32.push_back(-deFloatLdExp(1.f, -24)); // 2e-24: maximum 16-bit negative denormalized
+ // Normalized 32-bit float matching infinity in 16-bit
+ float32.push_back(deFloatLdExp(1.f, 100));
+ float32.push_back(-deFloatLdExp(1.f, 100));
+ }
// Zero
float32.push_back(0.f);
float32.push_back(-0.f);
- // Infinity
- float32.push_back(std::numeric_limits<float>::infinity());
- float32.push_back(-std::numeric_limits<float>::infinity());
- // SNaN
- float32.push_back(std::numeric_limits<float>::signaling_NaN());
- float32.push_back(-std::numeric_limits<float>::signaling_NaN());
- // QNaN
- float32.push_back(std::numeric_limits<float>::quiet_NaN());
- float32.push_back(-std::numeric_limits<float>::quiet_NaN());
-
// Denormalized 32-bit float matching 0 in 16-bit
float32.push_back(deFloatLdExp(1.f, -127));
float32.push_back(-deFloatLdExp(1.f, -127));
-
// Normalized 32-bit float matching 0 in 16-bit
float32.push_back(deFloatLdExp(1.f, -100));
float32.push_back(-deFloatLdExp(1.f, -100));
- // Normalized 32-bit float with exact denormalized match in 16-bit
- float32.push_back(deFloatLdExp(1.f, -24)); // 2e-24: minimum 16-bit positive denormalized
- float32.push_back(-deFloatLdExp(1.f, -24)); // 2e-24: maximum 16-bit negative denormalized
// Normalized 32-bit float with exact normalized match in 16-bit
float32.push_back(deFloatLdExp(1.f, -14)); // 2e-14: minimum 16-bit positive normalized
float32.push_back(-deFloatLdExp(1.f, -14)); // 2e-14: maximum 16-bit negative normalized
@@ -601,17 +616,26 @@ std::vector<float> getFloat32s (de::Random& rnd, deUint32 count)
// Some number
float32.push_back(0.28125f);
float32.push_back(-0.28125f);
- // Normalized 32-bit float matching infinity in 16-bit
- float32.push_back(deFloatLdExp(1.f, 100));
- float32.push_back(-deFloatLdExp(1.f, 100));
const deUint32 numPicks = static_cast<deUint32>(float32.size());
DE_ASSERT(count >= numPicks);
count -= numPicks;
- for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
- float32.push_back(rnd.getFloat());
+ for (deUint32 numNdx = 0; numNdx < count;)
+ {
+ float rndFloat = rnd.getFloat();
+ // If special float16 values must be excluded, generated float values that result in inf/nan/denormal of float16 should be removed.
+ if (!includeSpecialFloat16Values)
+ {
+ deFloat16 rndFloat16 = deFloat32To16(rndFloat);
+ if (deHalfIsInf(rndFloat16) || deHalfIsIEEENaN(rndFloat16) || deHalfIsDenormal(rndFloat16))
+ continue;
+ }
+
+ float32.push_back(rndFloat);
+ ++numNdx;
+ }
return float32;
}
@@ -638,32 +662,36 @@ std::vector<float> getFloat32s (de::Random& rnd, deUint32 count)
// 0 111 11 00 0000 1111 (0x7c0f: +SNaN)
// 0 111 11 00 1111 0000 (0x7c0f: +QNaN)
-// Generate and return 16-bit floats and their corresponding 32-bit values.
+// Generate and return 16-bit floats
//
-// The first 14 number pairs are manually picked, while the rest are randomly generated.
-// Expected count to be at least 14 (numPicks).
-std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count)
+// If includeSpecialFloat16Values is false, float16 inf/nan/denormal must be excluded since inf may be clamped,
+// and nan/denormal be flushed without float control features. And expected count to be at least 6 (numPicks).
+// Otherwise, the first 14 number pairs are manually picked, while the rest are randomly generated.
+// And expected count to be at least 14 (numPicks).
+std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count, deBool includeSpecialFloat16Values)
{
std::vector<deFloat16> float16;
float16.reserve(count);
+ if (includeSpecialFloat16Values)
+ {
+ // Infinity
+ float16.push_back(deUint16(0x7c00));
+ float16.push_back(deUint16(0xfc00));
+ // SNaN
+ float16.push_back(deUint16(0x7c0f));
+ float16.push_back(deUint16(0xfc0f));
+ // QNaN
+ float16.push_back(deUint16(0x7cf0));
+ float16.push_back(deUint16(0xfcf0));
+ // Denormalized
+ float16.push_back(deUint16(0x03f0));
+ float16.push_back(deUint16(0x83f0));
+ }
// Zero
float16.push_back(deUint16(0x0000));
float16.push_back(deUint16(0x8000));
- // Infinity
- float16.push_back(deUint16(0x7c00));
- float16.push_back(deUint16(0xfc00));
- // SNaN
- float16.push_back(deUint16(0x7c0f));
- float16.push_back(deUint16(0xfc0f));
- // QNaN
- float16.push_back(deUint16(0x7cf0));
- float16.push_back(deUint16(0xfcf0));
-
- // Denormalized
- float16.push_back(deUint16(0x03f0));
- float16.push_back(deUint16(0x83f0));
// Normalized
float16.push_back(deUint16(0x0401));
float16.push_back(deUint16(0x8401));
@@ -676,8 +704,15 @@ std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count)
DE_ASSERT(count >= numPicks);
count -= numPicks;
- for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
- float16.push_back(rnd.getUint16());
+ for (deUint32 numIdx = 0; numIdx < count;)
+ {
+ deFloat16 rndFloat = rnd.getUint16();
+ // If special float16 values must be excluded, generated values in inf/nan/denormal should be removed.
+ if (!includeSpecialFloat16Values && (deHalfIsInf(rndFloat) || deHalfIsIEEENaN(rndFloat) || deHalfIsDenormal(rndFloat)))
+ continue;
+ float16.push_back(rndFloat);
+ ++numIdx;
+ }
return float16;
}
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
index c40938d46..313803e80 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmUtils.hpp
@@ -306,21 +306,29 @@ std::vector<deInt8> getInt8s (de::Random& rnd, const deUint32 count);
// Generate and return 64-bit floats
//
-// The first 24 number pairs are manually picked, while the rest are randomly generated.
-// Expected count to be at least 24 (numPicks).
-std::vector<double> getFloat64s (de::Random& rnd, deUint32 count);
+// If includeSpecialFloat16Values is false, random float64 that can be converted to float16 inf/nan/denormal must be excluded
+// since inf may be clamped, and nan/denormal be flushed without float control features.
+// And expected count to be at least 14 (numPicks).
+// Otherwise, the first 24 number pairs are manually picked, while the rest are randomly generated.
+// And expected count to be at least 24 (numPicks).
+std::vector<double> getFloat64s (de::Random& rnd, deUint32 count, deBool includeSpecialFloat16Values = DE_TRUE);
// Generate and return 32-bit floats
//
-// The first 24 number pairs are manually picked, while the rest are randomly generated.
-// Expected count to be at least 24 (numPicks).
-std::vector<float> getFloat32s (de::Random& rnd, deUint32 count);
-
-// Generate and return 16-bit floats and their corresponding 32-bit values.
+// If includeSpecialFloat16Values is false, random float32 that can be converted to float16 inf/nan/denormal must be excluded
+// since inf may be clamped, and nan/denormal be flushed without float control features.
+// And expected count to be at least 14 (numPicks).
+// Otherwise, the first 24 number pairs are manually picked, while the rest are randomly generated.
+// And expected count to be at least 24 (numPicks).
+std::vector<float> getFloat32s (de::Random& rnd, deUint32 count, deBool includeSpecialFloat16Values = DE_TRUE);
+
+// Generate and return 16-bit floats
//
-// The first 14 number pairs are manually picked, while the rest are randomly generated.
-// Expected count to be at least 14 (numPicks).
-std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count);
+// If includeSpecialFloat16Values is false, float16 inf/nan/denormal must be excluded since inf may be clamped,
+// and nan/denormal be flushed without float control features. And expected count to be at least 6 (numPicks).
+// Otherwise, the first 14 number pairs are manually picked, while the rest are randomly generated.
+// And expected count to be at least 14 (numPicks).
+std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count, deBool includeSpecialFloat16Values = DE_TRUE);
// Generate an OpCapability Shader line.
std::string getOpCapabilityShader();
diff --git a/framework/delibs/debase/deFloat16.h b/framework/delibs/debase/deFloat16.h
index 4b25c842b..1857ef779 100644
--- a/framework/delibs/debase/deFloat16.h
+++ b/framework/delibs/debase/deFloat16.h
@@ -60,14 +60,41 @@ float deFloat16To32 (deFloat16 val16);
*//*--------------------------------------------------------------------*/
double deFloat16To64 (deFloat16 val16);
+DE_INLINE deUint16 deHalfExponent(deFloat16 x)
+{
+ return (deUint16)((x & 0x7c00u) >> 10);
+}
+
+DE_INLINE deUint16 deHalfMantissa(deFloat16 x)
+{
+ return (deUint16)(x & 0x03ffu);
+}
+
+DE_INLINE deUint16 deHalfHighestMantissaBit(deFloat16 x)
+{
+ return (deUint16)(x & (1u << 9));
+}
+
+DE_INLINE deUint16 deHalfSign(deFloat16 x)
+{
+ return (deUint16)(x >> 15);
+}
+
+static const deUint16 deHalfMaxExponent = 0x1f;
+
+DE_INLINE deBool deHalfIsZero(deFloat16 x)
+{
+ return deHalfExponent(x) == 0 && deHalfMantissa(x) == 0;
+}
+
DE_INLINE deBool deHalfIsPositiveZero(deFloat16 x)
{
- return deFloat16To32(x) == 0 && (x >> 15) == 0;
+ return deHalfIsZero(x) && (deHalfSign(x) == 0);
}
DE_INLINE deBool deHalfIsNegativeZero(deFloat16 x)
{
- return deFloat16To32(x) == 0 && (x >> 15) != 0;
+ return deHalfIsZero(x) && (deHalfSign(x) != 0);
}
static const deFloat16 deFloat16SignalingNaN = 0x7c01;
@@ -75,19 +102,37 @@ static const deFloat16 deFloat16QuietNaN = 0x7e01;
DE_INLINE deBool deHalfIsIEEENaN(deFloat16 x)
{
- deUint16 e = (deUint16)((x & 0x7c00u) >> 10);
- deUint16 m = (x & 0x03ffu);
- return e == 0x1f && m != 0;
+ return deHalfExponent(x) == deHalfMaxExponent && deHalfMantissa(x) != 0;
}
DE_INLINE deBool deHalfIsSignalingNaN(deFloat16 x)
{
- return deHalfIsIEEENaN(x) && (x & (1u << 9)) == 0;
+ return deHalfIsIEEENaN(x) && deHalfHighestMantissaBit(x) == 0;
}
DE_INLINE deBool deHalfIsQuietNaN(deFloat16 x)
{
- return deHalfIsIEEENaN(x) && (x & (1u << 9)) != 0;
+ return deHalfIsIEEENaN(x) && deHalfHighestMantissaBit(x) != 0;
+}
+
+DE_INLINE deBool deHalfIsInf(deFloat16 x)
+{
+ return deHalfExponent(x) == deHalfMaxExponent && deHalfMantissa(x) == 0;
+}
+
+DE_INLINE deBool deHalfIsPositiveInf(deFloat16 x)
+{
+ return deHalfIsInf(x) && (deHalfSign(x) == 0);
+}
+
+DE_INLINE deBool deHalfIsNegativeInf(deFloat16 x)
+{
+ return deHalfIsInf(x) && (deHalfSign(x) != 0);
+}
+
+DE_INLINE deBool deHalfIsDenormal(deFloat16 x)
+{
+ return deHalfExponent(x) == 0 && deHalfMantissa(x) != 0;
}
DE_END_EXTERN_C