12f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka/*------------------------------------------------------------------------ 22f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * Vulkan Conformance Tests 32f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * ------------------------ 42f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * 52f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * Copyright (c) 2015 The Khronos Group Inc. 62f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * Copyright (c) 2015 Samsung Electronics Co., Ltd. 7c05b7f1437e619205c96eaa31c0b79ec97a0d47dPyry Haulos * Copyright (c) 2016 The Android Open Source Project 82f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * 9978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License"); 10978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * you may not use this file except in compliance with the License. 11978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * You may obtain a copy of the License at 122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * 13978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * http://www.apache.org/licenses/LICENSE-2.0 142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * 15978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Unless required by applicable law or agreed to in writing, software 16978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS, 17978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * See the License for the specific language governing permissions and 19978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * limitations under the License. 202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * 212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *//*! 222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * \file 232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka * \brief Common built-in function tests. 242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *//*--------------------------------------------------------------------*/ 252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "vktShaderCommonFunctionTests.hpp" 272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "vktShaderExecutor.hpp" 282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "gluContextInfo.hpp" 292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "tcuTestLog.hpp" 302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "tcuFormatUtil.hpp" 312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "tcuFloat.hpp" 322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "tcuInterval.hpp" 332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "tcuFloatFormat.hpp" 342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "deRandom.hpp" 352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "deMath.h" 362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "deString.h" 372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "deArrayUtil.hpp" 382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka#include "deSharedPtr.hpp" 392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkanamespace vkt 412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkanamespace shaderexecutor 442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing std::vector; 482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing std::string; 492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing tcu::TestLog; 502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing tcu::Vec2; 522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing tcu::Vec3; 532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing tcu::Vec4; 542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing tcu::IVec2; 552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing tcu::IVec3; 562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkausing tcu::IVec4; 572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkanamespace 592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka// Utilities 622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<typename T, int Size> 642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastruct VecArrayAccess 652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka VecArrayAccess (const void* ptr) : m_array((tcu::Vector<T, Size>*)ptr) {} 682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ~VecArrayAccess (void) {} 692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Vector<T, Size>& operator[] (size_t offset) const { return m_array[offset]; } 712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Vector<T, Size>& operator[] (size_t offset) { return m_array[offset]; } 722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaprivate: 742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Vector<T, Size>* m_array; 752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<typename T> T randomScalar (de::Random& rnd, T minValue, T maxValue); 782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<> inline float randomScalar (de::Random& rnd, float minValue, float maxValue) { return rnd.getFloat(minValue, maxValue); } 792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<> inline deInt32 randomScalar (de::Random& rnd, deInt32 minValue, deInt32 maxValue) { return rnd.getInt(minValue, maxValue); } 802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<typename T, int Size> 822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline tcu::Vector<T, Size> randomVector (de::Random& rnd, const tcu::Vector<T, Size>& minValue, const tcu::Vector<T, Size>& maxValue) 832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Vector<T, Size> res; 852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < Size; ndx++) 862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka res[ndx] = randomScalar<T>(rnd, minValue[ndx], maxValue[ndx]); 872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return res; 882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<typename T, int Size> 912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic void fillRandomVectors (de::Random& rnd, const tcu::Vector<T, Size>& minValue, const tcu::Vector<T, Size>& maxValue, void* dst, int numValues, int offset = 0) 922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka VecArrayAccess<T, Size> access(dst); 942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues; ndx++) 952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka access[offset + ndx] = randomVector<T, Size>(rnd, minValue, maxValue); 962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<typename T> 992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic void fillRandomScalars (de::Random& rnd, T minValue, T maxValue, void* dst, int numValues, int offset = 0) 1002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka T* typedPtr = (T*)dst; 1022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues; ndx++) 1032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka typedPtr[offset + ndx] = randomScalar<T>(rnd, minValue, maxValue); 1042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline int numBitsLostInOp (float input, float output) 1072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int inExp = tcu::Float32(input).exponent(); 1092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int outExp = tcu::Float32(output).exponent(); 1102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return de::max(0, inExp-outExp); // Lost due to mantissa shift. 1122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline deUint32 getUlpDiff (float a, float b) 1152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 aBits = tcu::Float32(a).bits(); 1172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 bBits = tcu::Float32(b).bits(); 1182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return aBits > bBits ? aBits - bBits : bBits - aBits; 1192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline deUint32 getUlpDiffIgnoreZeroSign (float a, float b) 1222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (tcu::Float32(a).isZero()) 1242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return getUlpDiff(tcu::Float32::construct(tcu::Float32(b).sign(), 0, 0).asFloat(), b); 1252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else if (tcu::Float32(b).isZero()) 1262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return getUlpDiff(a, tcu::Float32::construct(tcu::Float32(a).sign(), 0, 0).asFloat()); 1272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 1282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return getUlpDiff(a, b); 1292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline bool supportsSignedZero (glu::Precision precision) 1322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // \note GLSL ES 3.1 doesn't really require support for -0, but we require it for highp 1342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // as it is very widely supported. 1352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return precision == glu::PRECISION_HIGHP; 1362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline float getEpsFromMaxUlpDiff (float value, deUint32 ulpDiff) 1392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int exp = tcu::Float32(value).exponent(); 1412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return tcu::Float32::construct(+1, exp, (1u<<23) | ulpDiff).asFloat() - tcu::Float32::construct(+1, exp, 1u<<23).asFloat(); 1422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline deUint32 getMaxUlpDiffFromBits (int numAccurateBits) 1452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numGarbageBits = 23-numAccurateBits; 1472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 mask = (1u<<numGarbageBits)-1u; 1482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return mask; 1502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkainline float getEpsFromBits (float value, int numAccurateBits) 1532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return getEpsFromMaxUlpDiff(value, getMaxUlpDiffFromBits(numAccurateBits)); 1552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic int getMinMantissaBits (glu::Precision precision) 1582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int bits[] = 1602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7, // lowp 1622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10, // mediump 1632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23 // highp 1642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 1652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(bits) == glu::PRECISION_LAST); 1662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(bits))); 1672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return bits[precision]; 1682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic int getMaxNormalizedValueExponent (glu::Precision precision) 1712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int exponent[] = 1732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 0, // lowp 1752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13, // mediump 1762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 127 // highp 1772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 1782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(exponent) == glu::PRECISION_LAST); 1792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(exponent))); 1802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return exponent[precision]; 1812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic int getMinNormalizedValueExponent (glu::Precision precision) 1842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int exponent[] = 1862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka -7, // lowp 1882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka -13, // mediump 1892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka -126 // highp 1902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 1912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(exponent) == glu::PRECISION_LAST); 1922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(exponent))); 1932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return exponent[precision]; 1942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 1952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 1962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic float makeFloatRepresentable (float f, glu::Precision precision) 1972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 1982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP) 1992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // \note: assuming f is not extended-precision 2012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return f; 2022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 2032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 2042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numMantissaBits = getMinMantissaBits(precision); 2062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int maxNormalizedValueExponent = getMaxNormalizedValueExponent(precision); 2072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int minNormalizedValueExponent = getMinNormalizedValueExponent(precision); 2082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 representableMantissaMask = ((deUint32(1) << numMantissaBits) - 1) << (23 - (deUint32)numMantissaBits); 2092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float largestRepresentableValue = tcu::Float32::constructBits(+1, maxNormalizedValueExponent, ((1u << numMantissaBits) - 1u) << (23u - (deUint32)numMantissaBits)).asFloat(); 2102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool zeroNotRepresentable = (precision == glu::PRECISION_LOWP); 2112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // if zero is not required to be representable, use smallest positive non-subnormal value 2132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float zeroValue = (zeroNotRepresentable) ? (tcu::Float32::constructBits(+1, minNormalizedValueExponent, 1).asFloat()) : (0.0f); 2142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Float32 float32Representation (f); 2162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (float32Representation.exponent() < minNormalizedValueExponent) 2182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // flush too small values to zero 2202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return zeroValue; 2212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 2222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else if (float32Representation.exponent() > maxNormalizedValueExponent) 2232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // clamp too large values 2252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return (float32Representation.sign() == +1) ? (largestRepresentableValue) : (-largestRepresentableValue); 2262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 2272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 2282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // remove unrepresentable mantissa bits 2302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Float32 targetRepresentation(tcu::Float32::constructBits(float32Representation.sign(), 2312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka float32Representation.exponent(), 2322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka float32Representation.mantissaBits() & representableMantissaMask)); 2332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return targetRepresentation.asFloat(); 2352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 2362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 2372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 2382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic vector<int> getScalarSizes (const vector<Symbol>& symbols) 2402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 2412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka vector<int> sizes(symbols.size()); 2422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < (int)symbols.size(); ++ndx) 2432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka sizes[ndx] = symbols[ndx].varType.getScalarSize(); 2442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return sizes; 2452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 2462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic int computeTotalScalarSize (const vector<Symbol>& symbols) 2482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 2492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int totalSize = 0; 2502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (vector<Symbol>::const_iterator sym = symbols.begin(); sym != symbols.end(); ++sym) 2512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka totalSize += sym->varType.getScalarSize(); 2522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return totalSize; 2532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 2542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic vector<void*> getInputOutputPointers (const vector<Symbol>& symbols, vector<deUint32>& data, const int numValues) 2562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 2572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka vector<void*> pointers (symbols.size()); 2582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int curScalarOffset = 0; 2592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int varNdx = 0; varNdx < (int)symbols.size(); ++varNdx) 2612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Symbol& var = symbols[varNdx]; 2632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = var.varType.getScalarSize(); 2642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Uses planar layout as input/output specs do not support strides. 2662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka pointers[varNdx] = &data[curScalarOffset]; 2672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka curScalarOffset += scalarSize*numValues; 2682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 2692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(curScalarOffset == (int)data.size()); 2712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return pointers; 2732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 2742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka// \todo [2013-08-08 pyry] Make generic utility and move to glu? 2762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastruct HexFloat 2782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 2792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float value; 2802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka HexFloat (const float value_) : value(value_) {} 2812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 2822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastd::ostream& operator<< (std::ostream& str, const HexFloat& v) 2842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 2852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return str << v.value << " / " << tcu::toHex(tcu::Float32(v.value).bits()); 2862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 2872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastruct HexBool 2892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 2902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 value; 2912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka HexBool (const deUint32 value_) : value(value_) {} 2922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 2932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastd::ostream& operator<< (std::ostream& str, const HexBool& v) 2952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 2962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return str << (v.value ? "true" : "false") << " / " << tcu::toHex(v.value); 2972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 2982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 2992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastruct VarValue 3002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 3012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::VarType& type; 3022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const void* value; 3032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka VarValue (const glu::VarType& type_, const void* value_) : type(type_), value(value_) {} 3052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 3062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastd::ostream& operator<< (std::ostream& str, const VarValue& varValue) 3082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 3092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(varValue.type.isBasicType()); 3102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType basicType = varValue.type.getBasicType(); 3122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType scalarType = glu::getDataTypeScalarType(basicType); 3132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numComponents = glu::getDataTypeScalarSize(basicType); 3142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (numComponents > 1) 3162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka str << glu::getDataTypeName(basicType) << "("; 3172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < numComponents; compNdx++) 3192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 3202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (compNdx != 0) 3212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka str << ", "; 3222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka switch (scalarType) 3242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 3252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka case glu::TYPE_FLOAT: str << HexFloat(((const float*)varValue.value)[compNdx]); break; 3262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka case glu::TYPE_INT: str << ((const deInt32*)varValue.value)[compNdx]; break; 3272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka case glu::TYPE_UINT: str << tcu::toHex(((const deUint32*)varValue.value)[compNdx]); break; 3282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka case glu::TYPE_BOOL: str << HexBool(((const deUint32*)varValue.value)[compNdx]); break; 3292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka default: 3312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(false); 3322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 3332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 3342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (numComponents > 1) 3362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka str << ")"; 3372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return str; 3392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 3402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic const char* getPrecisionPostfix (glu::Precision precision) 3422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 3432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka static const char* s_postfix[] = 3442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 3452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_lowp", 3462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_mediump", 3472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_highp" 3482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 3492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_postfix) == glu::PRECISION_LAST); 3502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(s_postfix))); 3512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return s_postfix[precision]; 3522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 3532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic const char* getShaderTypePostfix (glu::ShaderType shaderType) 3552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 3562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka static const char* s_postfix[] = 3572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 3582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_vertex", 3592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_fragment", 3602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_geometry", 3612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_tess_control", 3622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_tess_eval", 3632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka "_compute" 3642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 3652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_postfix))); 3662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return s_postfix[shaderType]; 3672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 3682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic std::string getCommonFuncCaseName (glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 3702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 3712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return string(glu::getDataTypeName(baseType)) + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType); 3722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 3732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic inline void frexp (float in, float* significand, int* exponent) 3752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 3762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Float32 fpValue(in); 3772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!fpValue.isZero()) 3792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 3802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Construct float that has exactly the mantissa, and exponent of -1. 3812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *significand = tcu::Float32::construct(fpValue.sign(), -1, fpValue.mantissa()).asFloat(); 3822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *exponent = fpValue.exponent()+1; 3832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 3842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 3852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 3862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *significand = fpValue.sign() < 0 ? -0.0f : 0.0f; 3872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *exponent = 0; 3882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 3892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 3902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic inline float ldexp (float significand, int exponent) 3922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 3932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Float32 mant(significand); 3942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 3952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (exponent == 0 && mant.isZero()) 3962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 3972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return mant.sign() < 0 ? -0.0f : 0.0f; 3982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 3992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 4002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 4012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return tcu::Float32::construct(mant.sign(), exponent+mant.exponent(), mant.mantissa()).asFloat(); 4022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 4032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 4042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatemplate<class TestClass> 4062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic void addFunctionCases (tcu::TestCaseGroup* parent, const char* functionName, bool floatTypes, bool intTypes, bool uintTypes, deUint32 shaderBits) 4072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 4082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::TestCaseGroup* group = new tcu::TestCaseGroup(parent->getTestContext(), functionName, functionName); 4092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka parent->addChild(group); 4102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType scalarTypes[] = 4122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 4132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka glu::TYPE_FLOAT, 4142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka glu::TYPE_INT, 4152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka glu::TYPE_UINT 4162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 4172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int scalarTypeNdx = 0; scalarTypeNdx < DE_LENGTH_OF_ARRAY(scalarTypes); scalarTypeNdx++) 4192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 4202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType scalarType = scalarTypes[scalarTypeNdx]; 4212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if ((!floatTypes && scalarType == glu::TYPE_FLOAT) || 4232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka (!intTypes && scalarType == glu::TYPE_INT) || 4242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka (!uintTypes && scalarType == glu::TYPE_UINT)) 4252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka continue; 4262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int vecSize = 1; vecSize <= 4; vecSize++) 4282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 42932c0175b73b2d428516a6db91e809ebd13c49999Csaba Osztrogonác for (int prec = glu::PRECISION_MEDIUMP; prec <= glu::PRECISION_HIGHP; prec++) 4302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 4312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int shaderTypeNdx = 0; shaderTypeNdx < glu::SHADERTYPE_LAST; shaderTypeNdx++) 4322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 4332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (shaderBits & (1<<shaderTypeNdx)) 4342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka group->addChild(new TestClass(parent->getTestContext(), glu::DataType(scalarType + vecSize - 1), glu::Precision(prec), glu::ShaderType(shaderTypeNdx))); 4352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 4362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 4372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 4382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 4392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 4402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka// CommonFunctionCase 4422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass CommonFunctionCase : public TestCase 4442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 4452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 4462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka CommonFunctionCase (tcu::TestContext& testCtx, const char* name, const char* description, glu::ShaderType shaderType); 4472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ~CommonFunctionCase (void); 4482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka virtual void initPrograms (vk::SourceCollections& programCollection) const 4492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 450b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos generateSources(m_shaderType, m_spec, programCollection); 4512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 4522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka virtual TestInstance* createInstance (Context& context) const = 0; 4542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaprotected: 456b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos CommonFunctionCase (const CommonFunctionCase&); 457b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos CommonFunctionCase& operator= (const CommonFunctionCase&); 4582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::ShaderType m_shaderType; 4602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ShaderSpec m_spec; 4612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int m_numValues; 4622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 4632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4642f7ef42cc1930880dc119fd9659d673a2f15474eRobert SipkaCommonFunctionCase::CommonFunctionCase (tcu::TestContext& testCtx, const char* name, const char* description, glu::ShaderType shaderType) 4652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : TestCase (testCtx, name, description) 4662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka , m_shaderType (shaderType) 4672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka , m_numValues (100) 4682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 4692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 4702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4712f7ef42cc1930880dc119fd9659d673a2f15474eRobert SipkaCommonFunctionCase::~CommonFunctionCase (void) 4722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 4732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 4742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka// CommonFunctionTestInstance 4762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass CommonFunctionTestInstance : public TestInstance 4782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 4792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 480b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos CommonFunctionTestInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 4812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : TestInstance (context) 4822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka , m_shaderType (shaderType) 4832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka , m_spec (spec) 4842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka , m_numValues (numValues) 4852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka , m_name (name) 486b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos , m_executor (createExecutor(context, shaderType, spec)) 4872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 4882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 4892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka virtual tcu::TestStatus iterate (void); 4902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaprotected: 4922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka virtual void getInputValues (int numValues, void* const* values) const = 0; 4932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka virtual bool compare (const void* const* inputs, const void* const* outputs) = 0; 4942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 4952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::ShaderType m_shaderType; 496b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos const ShaderSpec m_spec; 4972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int m_numValues; 4982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 499b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos // \todo [2017-03-07 pyry] Hack used to generate seeds for test cases - get rid of this. 500e148980e7f95d8a113a7dc84b13ca9906f33869fPyry Haulos const char* m_name; 5012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::ostringstream m_failMsg; //!< Comparison failure help message. 5032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 504b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos de::UniquePtr<ShaderExecutor> m_executor; 5052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 5062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkatcu::TestStatus CommonFunctionTestInstance::iterate (void) 5082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 5092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numInputScalars = computeTotalScalarSize(m_spec.inputs); 5102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numOutputScalars = computeTotalScalarSize(m_spec.outputs); 5112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka vector<deUint32> inputData (numInputScalars * m_numValues); 5122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka vector<deUint32> outputData (numOutputScalars * m_numValues); 5132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const vector<void*> inputPointers = getInputOutputPointers(m_spec.inputs, inputData, m_numValues); 5142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const vector<void*> outputPointers = getInputOutputPointers(m_spec.outputs, outputData, m_numValues); 5152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Initialize input data. 5172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka getInputValues(m_numValues, &inputPointers[0]); 5182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Execute shader. 520b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos m_executor->execute(m_numValues, &inputPointers[0], &outputPointers[0]); 5212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Compare results. 5232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 5242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const vector<int> inScalarSizes = getScalarSizes(m_spec.inputs); 5252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const vector<int> outScalarSizes = getScalarSizes(m_spec.outputs); 5262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka vector<void*> curInputPtr (inputPointers.size()); 5272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka vector<void*> curOutputPtr (outputPointers.size()); 5282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int numFailed = 0; 5292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::TestContext& testCtx = m_context.getTestContext(); 5302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int valNdx = 0; valNdx < m_numValues; valNdx++) 5322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 5332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Set up pointers for comparison. 5342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int inNdx = 0; inNdx < (int)curInputPtr.size(); ++inNdx) 5352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka curInputPtr[inNdx] = (deUint32*)inputPointers[inNdx] + inScalarSizes[inNdx]*valNdx; 5362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); ++outNdx) 5382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka curOutputPtr[outNdx] = (deUint32*)outputPointers[outNdx] + outScalarSizes[outNdx]*valNdx; 5392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!compare(&curInputPtr[0], &curOutputPtr[0])) 5412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 5422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // \todo [2013-08-08 pyry] We probably want to log reference value as well? 5432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka testCtx.getLog() << TestLog::Message << "ERROR: comparison failed for value " << valNdx << ":\n " << m_failMsg.str() << TestLog::EndMessage; 5452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka testCtx.getLog() << TestLog::Message << " inputs:" << TestLog::EndMessage; 5472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int inNdx = 0; inNdx < (int)curInputPtr.size(); inNdx++) 5482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka testCtx.getLog() << TestLog::Message << " " << m_spec.inputs[inNdx].name << " = " 5492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << VarValue(m_spec.inputs[inNdx].varType, curInputPtr[inNdx]) 5502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << TestLog::EndMessage; 5512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka testCtx.getLog() << TestLog::Message << " outputs:" << TestLog::EndMessage; 5532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); outNdx++) 5542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka testCtx.getLog() << TestLog::Message << " " << m_spec.outputs[outNdx].name << " = " 5552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << VarValue(m_spec.outputs[outNdx].varType, curOutputPtr[outNdx]) 5562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << TestLog::EndMessage; 5572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg.str(""); 5592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg.clear(); 5602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka numFailed += 1; 5612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 5622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 5632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka testCtx.getLog() << TestLog::Message << (m_numValues - numFailed) << " / " << m_numValues << " values passed" << TestLog::EndMessage; 5652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (numFailed == 0) 5672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return tcu::TestStatus::pass("Pass"); 5682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 5692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return tcu::TestStatus::fail("Result comparison failed"); 5702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 5712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 5722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka// Test cases 5742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass AbsCaseInstance : public CommonFunctionTestInstance 5762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 5772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 578b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos AbsCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 579b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 5802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 5812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 5822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 5842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 5852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 floatRanges[] = 5862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 5872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 5882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 5892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 5902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 5912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const IVec2 intRanges[] = 5922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 5932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IVec2(-(1<<7)+1, (1<<7)-1), 5942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IVec2(-(1<<15)+1, (1<<15)-1), 5952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IVec2(0x80000001, 0x7fffffff) 5962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 5972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 5982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0x235facu); 5992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 6002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 6012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 6022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (glu::isDataTypeFloatOrVec(type)) 6042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, floatRanges[precision].x(), floatRanges[precision].y(), values[0], numValues*scalarSize); 6052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 6062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, intRanges[precision].x(), intRanges[precision].y(), values[0], numValues*scalarSize); 6072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 6102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 6122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 6132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 6142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (glu::isDataTypeFloatOrVec(type)) 6162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 6182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = (1u<<(23-mantissaBits))-1u; 6192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 6212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 6232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 6242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref0 = de::abs(in0); 6252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff0 = getUlpDiff(out0, ref0); 6262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff0 > maxUlpDiff) 6282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref0) << " with ULP threshold " << maxUlpDiff << ", got ULP diff " << ulpDiff0; 6302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 6312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 6352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 6372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int in0 = ((const int*)inputs[0])[compNdx]; 6392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int out0 = ((const int*)outputs[0])[compNdx]; 6402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int ref0 = de::abs(in0); 6412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (out0 != ref0) 6432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << ref0; 6452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 6462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 6512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 6532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass AbsCase : public CommonFunctionCase 6552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 6562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 6572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka AbsCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 6582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "abs", shaderType) 6592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 6612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 6622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = abs(in0);"; 6632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 6662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 667b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new AbsCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 6682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 6702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass SignCaseInstance : public CommonFunctionTestInstance 6722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 6732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 674b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos SignCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 675b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 6762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 6782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 6802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 floatRanges[] = 6822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 6842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e4f, 1e4f), // mediump - note: may end up as inf 6852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e8f, 1e8f) // highp - note: may end up as inf 6862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 6872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const IVec2 intRanges[] = 6882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 6892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IVec2(-(1<<7), (1<<7)-1), 6902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IVec2(-(1<<15), (1<<15)-1), 6912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IVec2(0x80000000, 0x7fffffff) 6922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 6932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0x324u); 6952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 6962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 6972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 6982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 6992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (glu::isDataTypeFloatOrVec(type)) 7002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Special cases. 7022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((float*)values[0], (float*)values[0] + scalarSize, +1.0f); 7032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((float*)values[0], (float*)values[0] + scalarSize, -1.0f); 7042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((float*)values[0], (float*)values[0] + scalarSize, 0.0f); 7052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, floatRanges[precision].x(), floatRanges[precision].y(), (float*)values[0] + scalarSize*3, (numValues-3)*scalarSize); 7062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 7082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((int*)values[0], (int*)values[0] + scalarSize, +1); 7102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((int*)values[0], (int*)values[0] + scalarSize, -1); 7112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((int*)values[0], (int*)values[0] + scalarSize, 0); 7122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, intRanges[precision].x(), intRanges[precision].y(), (int*)values[0] + scalarSize*3, (numValues-3)*scalarSize); 7132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 7172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 7192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 7202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 7212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (glu::isDataTypeFloatOrVec(type)) 7232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Both highp and mediump should be able to represent -1, 0, and +1 exactly 7252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = precision == glu::PRECISION_LOWP ? getMaxUlpDiffFromBits(getMinMantissaBits(precision)) : 0; 7262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 7282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 7302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 7312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref0 = in0 < 0.0f ? -1.0f : 7322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka in0 > 0.0f ? +1.0f : 0.0f; 7332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff0 = getUlpDiff(out0, ref0); 7342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff0 > maxUlpDiff) 7362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref0) << " with ULP threshold " << maxUlpDiff << ", got ULP diff " << ulpDiff0; 7382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 7392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 7432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 7452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int in0 = ((const int*)inputs[0])[compNdx]; 7472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int out0 = ((const int*)outputs[0])[compNdx]; 7482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int ref0 = in0 < 0 ? -1 : 7492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka in0 > 0 ? +1 : 0; 7502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (out0 != ref0) 7522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << ref0; 7542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 7552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 7602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 7622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass SignCase : public CommonFunctionCase 7642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 7652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 7662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka SignCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 7672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "sign", shaderType) 7682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 7702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 7712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = sign(in0);"; 7722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 7752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 776b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new SignCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 7772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 7792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkastatic float roundEven (float v) 7812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 7822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float q = deFloatFrac(v); 7832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int truncated = int(v-q); 7842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int rounded = (q > 0.5f) ? (truncated + 1) : // Rounded up 7852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka (q == 0.5f && (truncated % 2 != 0)) ? (truncated + 1) : // Round to nearest even at 0.5 7862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka truncated; // Rounded down 7872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return float(rounded); 7892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 7902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass RoundEvenCaseInstance : public CommonFunctionTestInstance 7922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 7932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 794b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos RoundEvenCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 795b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance(context, shaderType, spec, numValues, name) 7962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 7972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 7982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 7992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 8002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 8022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 8042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 8052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 8062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 8072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 8092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 8102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 8112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 8122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int numSpecialCases = 0; 8132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Special cases. 8152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision != glu::PRECISION_LOWP) 8162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(numValues >= 20); 8182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < 20; ndx++) 8192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float v = de::clamp(float(ndx) - 10.5f, ranges[precision].x(), ranges[precision].y()); 8212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((float*)values[0], (float*)values[0] + scalarSize, v); 8222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka numSpecialCases += 1; 8232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Random cases. 8272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[0] + numSpecialCases*scalarSize, (numValues-numSpecialCases)*scalarSize); 8282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // If precision is mediump, make sure values can be represented in fp16 exactly 8302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_MEDIUMP) 8312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues*scalarSize; ndx++) 8332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[ndx] = tcu::Float16(((float*)values[0])[ndx]).asFloat(); 8342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 8382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 8402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 8412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool hasSignedZero = supportsSignedZero(precision); 8422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 8432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP || precision == glu::PRECISION_MEDIUMP) 8452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Require exact rounding result. 8472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 8482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 8502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 8512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref = roundEven(in0); 8522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = hasSignedZero ? getUlpDiff(out0, ref) : getUlpDiffIgnoreZeroSign(out0, ref); 8542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > 0) 8562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref) << ", got ULP diff " << tcu::toHex(ulpDiff); 8582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 8592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 8632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 8652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 8662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float eps = getEpsFromBits(1.0f, mantissaBits); // epsilon for rounding bounds 8672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 8692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 8712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 8722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int minRes = int(roundEven(in0-eps)); 8732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int maxRes = int(roundEven(in0+eps)); 8742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool anyOk = false; 8752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int roundedVal = minRes; roundedVal <= maxRes; roundedVal++) 8772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiffIgnoreZeroSign(out0, float(roundedVal)); 8792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff <= maxUlpDiff) 8812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka anyOk = true; 8832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka break; 8842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!anyOk) 8882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 8892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = [" << minRes << ", " << maxRes << "] with ULP threshold " << tcu::toHex(maxUlpDiff); 8902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 8912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 8962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 8972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 8982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 8992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass RoundEvenCase : public CommonFunctionCase 9002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 9012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 9022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka RoundEvenCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 9032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "roundEven", shaderType) 9042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 9062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 9072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = roundEven(in0);"; 9082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 9112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 912b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new RoundEvenCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 9132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 9152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass ModfCaseInstance : public CommonFunctionTestInstance 9172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 9182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 919b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos ModfCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 920b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance(context, shaderType, spec, numValues, name) 9212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 9252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 9272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 9292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 9302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 9312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 9322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 9342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 9352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 9362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 9372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), values[0], numValues*scalarSize); 9392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 9422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 9442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 9452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool hasZeroSign = supportsSignedZero(precision); 9462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 9472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 9492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 9512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 9532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 9542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out1 = ((const float*)outputs[1])[compNdx]; 9552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float refOut1 = float(int(in0)); 9572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float refOut0 = in0 - refOut1; 9582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int bitsLost = precision != glu::PRECISION_HIGHP ? numBitsLostInOp(in0, refOut0) : 0; 9602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(de::max(mantissaBits - bitsLost, 0)); 9612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float resSum = out0 + out1; 9632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = hasZeroSign ? getUlpDiff(resSum, in0) : getUlpDiffIgnoreZeroSign(resSum, in0); 9652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > maxUlpDiff) 9672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = (" << HexFloat(refOut0) << ") + (" << HexFloat(refOut1) << ") = " << HexFloat(in0) << " with ULP threshold " 9692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << tcu::toHex(maxUlpDiff) << ", got ULP diff " << tcu::toHex(ulpDiff); 9702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 9712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 9752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 9772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass ModfCase : public CommonFunctionCase 9792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 9802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 9812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ModfCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 9822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "modf", shaderType) 9832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 9842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 9852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 9862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out1", glu::VarType(baseType, precision))); 9872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = modf(in0, out1);"; 9882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 9912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 992b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new ModfCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 9932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 9942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 9952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 9962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass IsnanCaseInstance : public CommonFunctionTestInstance 9972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 9982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 999b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos IsnanCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1000b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 10012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 10052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xc2a39fu); 10072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 10082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 10092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 10102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 10112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 mantissaMask = ~getMaxUlpDiffFromBits(mantissaBits) & ((1u<<23)-1u); 10122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int valNdx = 0; valNdx < numValues*scalarSize; valNdx++) 10142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool isNan = rnd.getFloat() > 0.3f; 10162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool isInf = !isNan && rnd.getFloat() > 0.4f; 10172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 mantissa = !isInf ? ((1u<<22) | (rnd.getUint32() & mantissaMask)) : 0; 10182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 exp = !isNan && !isInf ? (rnd.getUint32() & 0x7fu) : 0xffu; 10192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 sign = rnd.getUint32() & 0x1u; 10202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 value = (sign << 31) | (exp << 23) | mantissa; 10212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(tcu::Float32(value).isInf() == isInf && tcu::Float32(value).isNaN() == isNan); 10232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((deUint32*)values[0])[valNdx] = value; 10252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 10292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 10312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 10322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 10332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP) 10352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Only highp is required to support inf/nan 10372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 10382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 10402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool out0 = ((const deUint32*)outputs[0])[compNdx] != 0; 10412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool ref = tcu::Float32(in0).isNaN(); 10422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (out0 != ref) 10442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << (ref ? "true" : "false"); 10462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 10472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else if (precision == glu::PRECISION_MEDIUMP || precision == glu::PRECISION_LOWP) 10512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // NaN support is optional, check that inputs that are not NaN don't result in true. 10532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 10542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 10562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool out0 = ((const deUint32*)outputs[0])[compNdx] != 0; 10572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool ref = tcu::Float32(in0).isNaN(); 10582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!ref && out0) 10602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << (ref ? "true" : "false"); 10622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 10632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 10682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 10702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass IsnanCase : public CommonFunctionCase 10722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 10732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 10742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IsnanCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 10752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "isnan", shaderType) 10762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(glu::isDataTypeFloatOrVec(baseType)); 10782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int vecSize = glu::getDataTypeScalarSize(baseType); 10802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType boolType = vecSize > 1 ? glu::getDataTypeBoolVec(vecSize) : glu::TYPE_BOOL; 10812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 10832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(boolType, glu::PRECISION_LAST))); 10842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = isnan(in0);"; 10852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 10882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1089b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new IsnanCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 10902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 10912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 10922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 10932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass IsinfCaseInstance : public CommonFunctionTestInstance 10942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 10952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1096b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos IsinfCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1097b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance(context, shaderType, spec, numValues, name) 10982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 10992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 11022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xc2a39fu); 11042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 11052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 11062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 11072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 11082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 mantissaMask = ~getMaxUlpDiffFromBits(mantissaBits) & ((1u<<23)-1u); 11092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int valNdx = 0; valNdx < numValues*scalarSize; valNdx++) 11112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool isInf = rnd.getFloat() > 0.3f; 11132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool isNan = !isInf && rnd.getFloat() > 0.4f; 11142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 mantissa = !isInf ? ((1u<<22) | (rnd.getUint32() & mantissaMask)) : 0; 11152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 exp = !isNan && !isInf ? (rnd.getUint32() & 0x7fu) : 0xffu; 11162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 sign = rnd.getUint32() & 0x1u; 11172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 value = (sign << 31) | (exp << 23) | mantissa; 11182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(tcu::Float32(value).isInf() == isInf && tcu::Float32(value).isNaN() == isNan); 11202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((deUint32*)values[0])[valNdx] = value; 11222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 11262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 11282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 11292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 11302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP) 11322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Only highp is required to support inf/nan 11342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 11352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 11372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool out0 = ((const deUint32*)outputs[0])[compNdx] != 0; 11382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool ref = tcu::Float32(in0).isInf(); 11392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (out0 != ref) 11412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexBool(ref); 11432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 11442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else if (precision == glu::PRECISION_MEDIUMP) 11482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Inf support is optional, check that inputs that are not Inf in mediump don't result in true. 11502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 11512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 11532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool out0 = ((const deUint32*)outputs[0])[compNdx] != 0; 11542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool ref = tcu::Float16(in0).isInf(); 11552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!ref && out0) 11572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << (ref ? "true" : "false"); 11592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 11602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // else: no verification can be performed 11642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 11662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 11682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass IsinfCase : public CommonFunctionCase 11702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 11712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 11722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka IsinfCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 11732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "isinf", shaderType) 11742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(glu::isDataTypeFloatOrVec(baseType)); 11762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int vecSize = glu::getDataTypeScalarSize(baseType); 11782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType boolType = vecSize > 1 ? glu::getDataTypeBoolVec(vecSize) : glu::TYPE_BOOL; 11792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 11812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(boolType, glu::PRECISION_LAST))); 11822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = isinf(in0);"; 11832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 11862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1187b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new IsinfCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 11882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 11902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloatBitsToUintIntCaseInstance : public CommonFunctionTestInstance 11922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 11932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1194b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos FloatBitsToUintIntCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1195b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 11962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 11972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 11982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 11992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 12002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 12022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 12042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 12052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 12062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 12072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0x2790au); 12092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 12102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 12112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 12122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), values[0], numValues*scalarSize); 12142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 12172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 12192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 12202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 12212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 12232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); 12242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 12262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 12282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 out0 = ((const deUint32*)outputs[0])[compNdx]; 12292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 refOut0 = tcu::Float32(in0).bits(); 12302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int ulpDiff = de::abs((int)out0 - (int)refOut0); 12312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > maxUlpDiff) 12332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(refOut0) << " with threshold " 12352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << tcu::toHex(maxUlpDiff) << ", got diff " << tcu::toHex(ulpDiff); 12362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 12372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 12412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 12432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloatBitsToUintIntCase : public CommonFunctionCase 12452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 12462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 12472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FloatBitsToUintIntCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType, bool outIsSigned) 12482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), outIsSigned ? "floatBitsToInt" : "floatBitsToUint", shaderType) 12492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int vecSize = glu::getDataTypeScalarSize(baseType); 12512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType intType = outIsSigned ? (vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT) 12522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : (vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT); 12532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 12552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(intType, glu::PRECISION_HIGHP))); 12562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = outIsSigned ? "out0 = floatBitsToInt(in0);" : "out0 = floatBitsToUint(in0);"; 12572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 12602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1261b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new FloatBitsToUintIntCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 12622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 12642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloatBitsToIntCaseInstance : public FloatBitsToUintIntCaseInstance 12662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 12672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1268b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos FloatBitsToIntCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1269b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : FloatBitsToUintIntCaseInstance (context, shaderType, spec, numValues, name) 12702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 12732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloatBitsToIntCase : public FloatBitsToUintIntCase 12752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 12762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 12772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FloatBitsToIntCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 12782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : FloatBitsToUintIntCase (testCtx, baseType, precision, shaderType, true) 12792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 12832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloatBitsToUintCaseInstance : public FloatBitsToUintIntCaseInstance 12852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 12862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1287b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos FloatBitsToUintCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1288b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : FloatBitsToUintIntCaseInstance (context, shaderType, spec, numValues, name) 12892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 12912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 12922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 12932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloatBitsToUintCase : public FloatBitsToUintIntCase 12942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 12952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 12962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FloatBitsToUintCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 12972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : FloatBitsToUintIntCase (testCtx, baseType, precision, shaderType, false) 12982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 12992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 13012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass BitsToFloatCaseInstance : public CommonFunctionTestInstance 13032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 13042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1305b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos BitsToFloatCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1306b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 13072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 13112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xbbb225u); 13132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 13142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 13152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 range (-1e8f, +1e8f); 13162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // \note Filled as floats. 13182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, range.x(), range.y(), values[0], numValues*scalarSize); 13192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 13222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 13242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 13252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = 0; 13262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 13282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 13302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 13312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiff(in0, out0); 13322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > maxUlpDiff) 13342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(tcu::Float32(in0).bits()) << " with ULP threshold " 13362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << tcu::toHex(maxUlpDiff) << ", got ULP diff " << tcu::toHex(ulpDiff); 13372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 13382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 13422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 13442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass BitsToFloatCase : public CommonFunctionCase 13462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 13472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 13482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka BitsToFloatCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::ShaderType shaderType) 13492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, glu::PRECISION_HIGHP, shaderType).c_str(), glu::isDataTypeIntOrIVec(baseType) ? "intBitsToFloat" : "uintBitsToFloat", shaderType) 13502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool inIsSigned = glu::isDataTypeIntOrIVec(baseType); 13522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int vecSize = glu::getDataTypeScalarSize(baseType); 13532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType floatType = vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT; 13542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, glu::PRECISION_HIGHP))); 13562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(floatType, glu::PRECISION_HIGHP))); 13572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = inIsSigned ? "out0 = intBitsToFloat(in0);" : "out0 = uintBitsToFloat(in0);"; 13582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 13612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1362b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new BitsToFloatCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 13632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 13652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloorCaseInstance : public CommonFunctionTestInstance 13672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 13682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1369b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos FloorCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1370b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 13712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 13752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 13772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 13792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 13802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 13812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 13822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 13842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 13852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 13862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 13872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Random cases. 13882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[0], numValues*scalarSize); 13892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // If precision is mediump, make sure values can be represented in fp16 exactly 13912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_MEDIUMP) 13922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 13932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues*scalarSize; ndx++) 13942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[ndx] = tcu::Float16(((float*)values[0])[ndx]).asFloat(); 13952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 13972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 13982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 13992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 14012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 14022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 14032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP || precision == glu::PRECISION_MEDIUMP) 14052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Require exact result. 14072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 14082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 14102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 14112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref = deFloatFloor(in0); 14122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiff(out0, ref); 14142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > 0) 14162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref) << ", got ULP diff " << tcu::toHex(ulpDiff); 14182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 14192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 14232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 14252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 14262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float eps = getEpsFromBits(1.0f, mantissaBits); // epsilon for rounding bounds 14272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 14292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 14312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 14322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int minRes = int(deFloatFloor(in0-eps)); 14332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int maxRes = int(deFloatFloor(in0+eps)); 14342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool anyOk = false; 14352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int roundedVal = minRes; roundedVal <= maxRes; roundedVal++) 14372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiff(out0, float(roundedVal)); 14392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff <= maxUlpDiff) 14412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka anyOk = true; 14432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka break; 14442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!anyOk) 14482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = [" << minRes << ", " << maxRes << "] with ULP threshold " << tcu::toHex(maxUlpDiff); 14502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 14512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 14562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 14582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FloorCase : public CommonFunctionCase 14602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 14612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 14622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FloorCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 14632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "floor", shaderType) 14642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 14662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 14672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = floor(in0);"; 14682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 14712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1472b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new FloorCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 14732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 14752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass TruncCaseInstance : public CommonFunctionTestInstance 14772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 14782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1479b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos TruncCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1480b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 14812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 14832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 14852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 14872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 14882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 14892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 14902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 14912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 14922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 14932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 14942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 14952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 14962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 14972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float specialCases[] = { 0.0f, -0.0f, -0.9f, 0.9f, 1.0f, -1.0f }; 14982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numSpecialCases = DE_LENGTH_OF_ARRAY(specialCases); 14992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Special cases 15012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int caseNdx = 0; caseNdx < numSpecialCases; caseNdx++) 15022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 15042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[caseNdx*scalarSize + scalarNdx] = specialCases[caseNdx]; 15052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Random cases. 15082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[0] + scalarSize*numSpecialCases, (numValues-numSpecialCases)*scalarSize); 15092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // If precision is mediump, make sure values can be represented in fp16 exactly 15112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_MEDIUMP) 15122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues*scalarSize; ndx++) 15142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[ndx] = tcu::Float16(((float*)values[0])[ndx]).asFloat(); 15152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 15192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 15212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 15222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 15232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP || precision == glu::PRECISION_MEDIUMP) 15252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Require exact result. 15272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 15282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 15302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 15312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool isNeg = tcu::Float32(in0).sign() < 0; 15322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref = isNeg ? (-float(int(-in0))) : float(int(in0)); 15332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // \note: trunc() function definition is a bit broad on negative zeros. Ignore result sign if zero. 15352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiffIgnoreZeroSign(out0, ref); 15362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > 0) 15382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref) << ", got ULP diff " << tcu::toHex(ulpDiff); 15402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 15412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 15452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 15472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 15482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float eps = getEpsFromBits(1.0f, mantissaBits); // epsilon for rounding bounds 15492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 15512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 15532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 15542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int minRes = int(in0-eps); 15552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int maxRes = int(in0+eps); 15562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool anyOk = false; 15572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int roundedVal = minRes; roundedVal <= maxRes; roundedVal++) 15592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiffIgnoreZeroSign(out0, float(roundedVal)); 15612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff <= maxUlpDiff) 15632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka anyOk = true; 15652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka break; 15662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!anyOk) 15702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = [" << minRes << ", " << maxRes << "] with ULP threshold " << tcu::toHex(maxUlpDiff); 15722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 15732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 15782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 15802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass TruncCase : public CommonFunctionCase 15822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 15832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 15842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TruncCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 15852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "trunc", shaderType) 15862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 15872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 15882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 15892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = trunc(in0);"; 15902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 15932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1594b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new TruncCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 15952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 15962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 15972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 15982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass RoundCaseInstance : public CommonFunctionTestInstance 15992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 16002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1601b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos RoundCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1602b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 16032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 16072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 16092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 16112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 16122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 16132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 16142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 16162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 16172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 16182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 16192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int numSpecialCases = 0; 16202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Special cases. 16222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision != glu::PRECISION_LOWP) 16232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(numValues >= 10); 16252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < 10; ndx++) 16262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float v = de::clamp(float(ndx) - 5.5f, ranges[precision].x(), ranges[precision].y()); 16282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((float*)values[0], (float*)values[0] + scalarSize, v); 16292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka numSpecialCases += 1; 16302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Random cases. 16342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[0] + numSpecialCases*scalarSize, (numValues-numSpecialCases)*scalarSize); 16352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // If precision is mediump, make sure values can be represented in fp16 exactly 16372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_MEDIUMP) 16382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues*scalarSize; ndx++) 16402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[ndx] = tcu::Float16(((float*)values[0])[ndx]).asFloat(); 16412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 16452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 16472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 16482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool hasZeroSign = supportsSignedZero(precision); 16492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 16502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP || precision == glu::PRECISION_MEDIUMP) 16522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 16542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 16562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 16572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (deFloatFrac(in0) == 0.5f) 16592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Allow both ceil(in) and floor(in) 16612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref0 = deFloatFloor(in0); 16622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref1 = deFloatCeil(in0); 16632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff0 = hasZeroSign ? getUlpDiff(out0, ref0) : getUlpDiffIgnoreZeroSign(out0, ref0); 16642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff1 = hasZeroSign ? getUlpDiff(out0, ref1) : getUlpDiffIgnoreZeroSign(out0, ref1); 16652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff0 > 0 && ulpDiff1 > 0) 16672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref0) << " or " << HexFloat(ref1) << ", got ULP diff " << tcu::toHex(de::min(ulpDiff0, ulpDiff1)); 16692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 16702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 16732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Require exact result 16752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref = roundEven(in0); 16762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = hasZeroSign ? getUlpDiff(out0, ref) : getUlpDiffIgnoreZeroSign(out0, ref); 16772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > 0) 16792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref) << ", got ULP diff " << tcu::toHex(ulpDiff); 16812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 16822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 16862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 16872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 16892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 16902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float eps = getEpsFromBits(1.0f, mantissaBits); // epsilon for rounding bounds 16912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 16922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 16932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 16942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 16952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 16962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int minRes = int(roundEven(in0-eps)); 16972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int maxRes = int(roundEven(in0+eps)); 16982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool anyOk = false; 16992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int roundedVal = minRes; roundedVal <= maxRes; roundedVal++) 17012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiffIgnoreZeroSign(out0, float(roundedVal)); 17032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff <= maxUlpDiff) 17052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka anyOk = true; 17072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka break; 17082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!anyOk) 17122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = [" << minRes << ", " << maxRes << "] with ULP threshold " << tcu::toHex(maxUlpDiff); 17142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 17152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 17202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 17222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass RoundCase : public CommonFunctionCase 17242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 17252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 17262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka RoundCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 17272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "round", shaderType) 17282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 17302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 17312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = round(in0);"; 17322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 17352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1736b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new RoundCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 17372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 17392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass CeilCaseInstance : public CommonFunctionTestInstance 17412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 17422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1743b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos CeilCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1744b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 17452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 17492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 17512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 17532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 17542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 17552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 17562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 17582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 17592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 17602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 17612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Random cases. 17632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[0], numValues*scalarSize); 17642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // If precision is mediump, make sure values can be represented in fp16 exactly 17662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_MEDIUMP) 17672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues*scalarSize; ndx++) 17692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[ndx] = tcu::Float16(((float*)values[0])[ndx]).asFloat(); 17702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 17742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 17762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 17772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool hasZeroSign = supportsSignedZero(precision); 17782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 17792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP || precision == glu::PRECISION_MEDIUMP) 17812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Require exact result. 17832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 17842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 17862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 17872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref = deFloatCeil(in0); 17882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = hasZeroSign ? getUlpDiff(out0, ref) : getUlpDiffIgnoreZeroSign(out0, ref); 17902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 17912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > 0) 17922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 17932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref) << ", got ULP diff " << tcu::toHex(ulpDiff); 17942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 17952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 17982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 17992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 18012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 18022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float eps = getEpsFromBits(1.0f, mantissaBits); // epsilon for rounding bounds 18032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 18052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 18072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 18082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int minRes = int(deFloatCeil(in0-eps)); 18092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int maxRes = int(deFloatCeil(in0+eps)); 18102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool anyOk = false; 18112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int roundedVal = minRes; roundedVal <= maxRes; roundedVal++) 18132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiffIgnoreZeroSign(out0, float(roundedVal)); 18152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff <= maxUlpDiff) 18172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka anyOk = true; 18192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka break; 18202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!anyOk && de::inRange(0, minRes, maxRes)) 18242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Allow -0 as well. 18262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int ulpDiff = de::abs((int)tcu::Float32(out0).bits() - (int)0x80000000u); 18272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka anyOk = ((deUint32)ulpDiff <= maxUlpDiff); 18282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!anyOk) 18312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = [" << minRes << ", " << maxRes << "] with ULP threshold " << tcu::toHex(maxUlpDiff); 18332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 18342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 18392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 18412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass CeilCase : public CommonFunctionCase 18432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 18442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 18452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka CeilCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 18462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "ceil", shaderType) 18472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 18492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 18502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = ceil(in0);"; 18512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 18542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1855b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new CeilCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 18562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 18582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FractCaseInstance : public CommonFunctionTestInstance 18602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 18612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1862b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos FractCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1863b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 18642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 18682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 18702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 18722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 18732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 18742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 18752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 18772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 18782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 18792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 18802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int numSpecialCases = 0; 18812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Special cases. 18832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision != glu::PRECISION_LOWP) 18842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(numValues >= 10); 18862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < 10; ndx++) 18872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 18882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float v = de::clamp(float(ndx) - 5.5f, ranges[precision].x(), ranges[precision].y()); 18892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka std::fill((float*)values[0], (float*)values[0] + scalarSize, v); 18902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka numSpecialCases += 1; 18912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 18932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Random cases. 18952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[0] + numSpecialCases*scalarSize, (numValues-numSpecialCases)*scalarSize); 18962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 18972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // If precision is mediump, make sure values can be represented in fp16 exactly 18982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_MEDIUMP) 18992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int ndx = 0; ndx < numValues*scalarSize; ndx++) 19012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[ndx] = tcu::Float16(((float*)values[0])[ndx]).asFloat(); 19022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 19062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 19082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 19092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool hasZeroSign = supportsSignedZero(precision); 19102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 19112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (precision == glu::PRECISION_HIGHP || precision == glu::PRECISION_MEDIUMP) 19132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Require exact result. 19152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 19162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 19182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 19192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref = deFloatFrac(in0); 19202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = hasZeroSign ? getUlpDiff(out0, ref) : getUlpDiffIgnoreZeroSign(out0, ref); 19222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > 0) 19242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref) << ", got ULP diff " << tcu::toHex(ulpDiff); 19262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 19272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 19312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 19332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float eps = getEpsFromBits(1.0f, mantissaBits); // epsilon for rounding bounds 19342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 19362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 19382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 19392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (int(deFloatFloor(in0-eps)) == int(deFloatFloor(in0+eps))) 19412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float ref = deFloatFrac(in0); 19432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int bitsLost = numBitsLostInOp(in0, ref); 19442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(de::max(0, mantissaBits-bitsLost)); // ULP diff for rounded integer value. 19452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiffIgnoreZeroSign(out0, ref); 19462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > maxUlpDiff) 19482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(ref) << " with ULP threshold " << tcu::toHex(maxUlpDiff) << ", got diff " << tcu::toHex(ulpDiff); 19502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 19512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka else 19542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (out0 >= 1.0f) 19562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] < 1.0"; 19582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 19592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 19652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 19672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FractCase : public CommonFunctionCase 19692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 19702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 19712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FractCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 19722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "fract", shaderType) 19732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 19752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, precision))); 19762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = fract(in0);"; 19772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 19802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1981b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new FractCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 19822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 19842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FrexpCaseInstance : public CommonFunctionTestInstance 19862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 19872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 1988b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos FrexpCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 1989b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 19902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 19922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 19932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 19942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 19962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 19972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 19982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 19992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 20002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 20012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0x2790au); 20032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 20042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 20052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 20062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Special cases 20082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 20092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*0 + compNdx] = 0.0f; 20112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*1 + compNdx] = -0.0f; 20122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*2 + compNdx] = 0.5f; 20132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*3 + compNdx] = -0.5f; 20142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*4 + compNdx] = 1.0f; 20152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*5 + compNdx] = -1.0f; 20162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*6 + compNdx] = 2.0f; 20172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[scalarSize*7 + compNdx] = -2.0f; 20182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[0] + 8*scalarSize, (numValues-8)*scalarSize); 20212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Make sure the values are representable in the target format 20232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int caseNdx = 0; caseNdx < numValues; ++caseNdx) 20242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 20262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka float* const valuePtr = &((float*)values[0])[caseNdx * scalarSize + scalarNdx]; 20282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *valuePtr = makeFloatRepresentable(*valuePtr, precision); 20302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 20352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 20372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 20382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 20392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool transitSupportsSignedZero = (m_shaderType != glu::SHADERTYPE_FRAGMENT); // executor cannot reliably transit negative zero to fragment stage 20402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const bool signedZero = supportsSignedZero(precision) && transitSupportsSignedZero; 20412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 20432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); 20442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 20462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 20482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 20492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int out1 = ((const int*)outputs[1])[compNdx]; 20502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka float refOut0; 20522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int refOut1; 20532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka frexp(in0, &refOut0, &refOut1); 20552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff0 = signedZero ? getUlpDiff(out0, refOut0) : getUlpDiffIgnoreZeroSign(out0, refOut0); 20572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff0 > maxUlpDiff || out1 != refOut1) 20592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(refOut0) << ", " << refOut1 << " with ULP threshold " 20612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << tcu::toHex(maxUlpDiff) << ", got ULP diff " << tcu::toHex(ulpDiff0); 20622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 20632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 20672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 20692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FrexpCase : public CommonFunctionCase 20712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 20722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 20732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FrexpCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 20742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "frexp", shaderType) 20752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int vecSize = glu::getDataTypeScalarSize(baseType); 20772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType intType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 20782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 20802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, glu::PRECISION_HIGHP))); 20812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out1", glu::VarType(intType, glu::PRECISION_HIGHP))); 20822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = frexp(in0, out1);"; 20832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 20862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2087b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new FrexpCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 20882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 20902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass LdexpCaseInstance : public CommonFunctionTestInstance 20922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 20932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 2094b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos LdexpCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 2095b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 20962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 20972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 20982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 20992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 21002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 21022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 21042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e3f, 1e3f), // mediump 21052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 21062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 21072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0x2790au); 21092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 21102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 21112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 21122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int valueNdx = 0; 21132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float easySpecialCases[] = { 0.0f, -0.0f, 0.5f, -0.5f, 1.0f, -1.0f, 2.0f, -2.0f }; 21162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(valueNdx + DE_LENGTH_OF_ARRAY(easySpecialCases) <= numValues); 21182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(easySpecialCases); caseNdx++) 21192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka float in0; 21212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int in1; 21222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka frexp(easySpecialCases[caseNdx], &in0, &in1); 21242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 21262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[valueNdx*scalarSize + compNdx] = in0; 21282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((int*)values[1])[valueNdx*scalarSize + compNdx] = in1; 21292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka valueNdx += 1; 21322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // \note lowp and mediump can not necessarily fit the values in hard cases, so we'll use only easy ones. 21372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numEasyRandomCases = precision == glu::PRECISION_HIGHP ? 50 : (numValues-valueNdx); 21382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(valueNdx + numEasyRandomCases <= numValues); 21402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int caseNdx = 0; caseNdx < numEasyRandomCases; caseNdx++) 21412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 21432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in = rnd.getFloat(ranges[precision].x(), ranges[precision].y()); 21452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka float in0; 21462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka int in1; 21472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka frexp(in, &in0, &in1); 21492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[valueNdx*scalarSize + compNdx] = in0; 21512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((int*)values[1])[valueNdx*scalarSize + compNdx] = in1; 21522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka valueNdx += 1; 21552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numHardRandomCases = numValues-valueNdx; 21602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(numHardRandomCases >= 0 && valueNdx + numHardRandomCases <= numValues); 21612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int caseNdx = 0; caseNdx < numHardRandomCases; caseNdx++) 21632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 21652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int fpExp = rnd.getInt(-126, 127); 21672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int sign = rnd.getBool() ? -1 : +1; 21682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 mantissa = (1u<<23) | (rnd.getUint32() & ((1u<<23)-1)); 21692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int in1 = rnd.getInt(de::max(-126, -126-fpExp), de::min(127, 127-fpExp)); 21702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = tcu::Float32::construct(sign, fpExp, mantissa).asFloat(); 21712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(de::inRange(in1, -126, 127)); // See Khronos bug 11180 21732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(de::inRange(in1+fpExp, -126, 127)); 21742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out = ldexp(in0, in1); 21762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_ASSERT(!tcu::Float32(out).isInf() && !tcu::Float32(out).isDenorm()); 21782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka DE_UNREF(out); 21792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[0])[valueNdx*scalarSize + compNdx] = in0; 21812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((int*)values[1])[valueNdx*scalarSize + compNdx] = in1; 21822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka valueNdx += 1; 21852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 21882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 21902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 21912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 21922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 21932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 21942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int mantissaBits = getMinMantissaBits(precision); 21962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 maxUlpDiff = getMaxUlpDiffFromBits(mantissaBits); 21972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 21982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 21992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float in0 = ((const float*)inputs[0])[compNdx]; 22012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int in1 = ((const int*)inputs[1])[compNdx]; 22022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float out0 = ((const float*)outputs[0])[compNdx]; 22032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float refOut0 = ldexp(in0, in1); 22042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 ulpDiff = getUlpDiffIgnoreZeroSign(out0, refOut0); 22052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int inExp = tcu::Float32(in0).exponent(); 22072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (ulpDiff > maxUlpDiff) 22092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << HexFloat(refOut0) << ", (exp = " << inExp << ") with ULP threshold " 22112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka << tcu::toHex(maxUlpDiff) << ", got ULP diff " << tcu::toHex(ulpDiff); 22122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 22132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 22172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 22192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass LdexpCase : public CommonFunctionCase 22212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 22222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 22232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka LdexpCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 22242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "ldexp", shaderType) 22252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int vecSize = glu::getDataTypeScalarSize(baseType); 22272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType intType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 22282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in0", glu::VarType(baseType, precision))); 22302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("in1", glu::VarType(intType, glu::PRECISION_HIGHP))); 22312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("out0", glu::VarType(baseType, glu::PRECISION_HIGHP))); 22322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "out0 = ldexp(in0, in1);"; 22332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 22362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2237b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new LdexpCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 22382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 22402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FmaCaseInstance : public CommonFunctionTestInstance 22422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 22432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 2244b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos FmaCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name) 2245b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos : CommonFunctionTestInstance (context, shaderType, spec, numValues, name) 22462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka void getInputValues (int numValues, void* const* values) const 22502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const Vec2 ranges[] = 22522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-2.0f, 2.0f), // lowp 22542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-127.f, 127.f), // mediump 22552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka Vec2(-1e7f, 1e7f) // highp 22562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 22572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka de::Random rnd (deStringHash(m_name) ^ 0xac23fu); 22592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 22602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 22612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 22622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float specialCases[][3] = 22632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // a b c 22652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 0.0f, 0.0f, 0.0f }, 22662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 0.0f, 1.0f, 0.0f }, 22672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 0.0f, 0.0f, -1.0f }, 22682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1.0f, 1.0f, 0.0f }, 22692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1.0f, 1.0f, 1.0f }, 22702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { -1.0f, 1.0f, 0.0f }, 22712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1.0f, -1.0f, 0.0f }, 22722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { -1.0f, -1.0f, 0.0f }, 22732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { -0.0f, 1.0f, 0.0f }, 22742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 1.0f, -0.0f, 0.0f } 22752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 22762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numSpecialCases = DE_LENGTH_OF_ARRAY(specialCases); 22772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Special cases 22792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int caseNdx = 0; caseNdx < numSpecialCases; caseNdx++) 22802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int inputNdx = 0; inputNdx < 3; inputNdx++) 22822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 22842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ((float*)values[inputNdx])[caseNdx*scalarSize + scalarNdx] = specialCases[caseNdx][inputNdx]; 22852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22872f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Random cases. 22892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 22902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int numScalars = (numValues-numSpecialCases)*scalarSize; 22912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int offs = scalarSize*numSpecialCases; 22922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22932f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int inputNdx = 0; inputNdx < 3; inputNdx++) 22942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka fillRandomScalars(rnd, ranges[precision].x(), ranges[precision].y(), (float*)values[inputNdx] + offs, numScalars); 22952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 22962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 22972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Make sure the values are representable in the target format 22982f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int inputNdx = 0; inputNdx < 3; inputNdx++) 22992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int caseNdx = 0; caseNdx < numValues; ++caseNdx) 23012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 23032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka float* const valuePtr = &((float*)values[inputNdx])[caseNdx * scalarSize + scalarNdx]; 23052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka *valuePtr = makeFloatRepresentable(*valuePtr, precision); 23072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka static tcu::Interval fma (glu::Precision precision, float a, float b, float c) 23132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::FloatFormat formats[] = 23152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // minExp maxExp mantissa exact, subnormals infinities NaN 23172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::FloatFormat(0, 0, 7, false, tcu::YES, tcu::MAYBE, tcu::MAYBE), 23182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::FloatFormat(-13, 13, 9, false, tcu::MAYBE, tcu::MAYBE, tcu::MAYBE), 23192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::FloatFormat(-126, 127, 23, true, tcu::MAYBE, tcu::YES, tcu::MAYBE) 23202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 23212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::FloatFormat& format = de::getSizedArrayElement<glu::PRECISION_LAST>(formats, precision); 23222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Interval ia = format.convert(a); 23232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Interval ib = format.convert(b); 23242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Interval ic = format.convert(c); 23252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Interval prod0; 23262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Interval prod1; 23272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Interval prod2; 23282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Interval prod3; 23292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Interval prod; 23302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::Interval res; 23312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TCU_SET_INTERVAL(prod0, tmp, tmp = ia.lo() * ib.lo()); 23332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TCU_SET_INTERVAL(prod1, tmp, tmp = ia.lo() * ib.hi()); 23342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TCU_SET_INTERVAL(prod2, tmp, tmp = ia.hi() * ib.lo()); 23352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TCU_SET_INTERVAL(prod3, tmp, tmp = ia.hi() * ib.hi()); 23362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka prod = format.convert(format.roundOut(prod0 | prod1 | prod2 | prod3, ia.isFinite() && ib.isFinite())); 23382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TCU_SET_INTERVAL_BOUNDS(res, tmp, 23402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tmp = prod.lo() + ic.lo(), 23412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tmp = prod.hi() + ic.hi()); 23422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return format.convert(format.roundOut(res, prod.isFinite() && ic.isFinite())); 23442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka bool compare (const void* const* inputs, const void* const* outputs) 23472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType type = m_spec.inputs[0].varType.getBasicType(); 23492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::Precision precision = m_spec.inputs[0].varType.getPrecision(); 23502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const int scalarSize = glu::getDataTypeScalarSize(type); 23512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int compNdx = 0; compNdx < scalarSize; compNdx++) 23532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float a = ((const float*)inputs[0])[compNdx]; 23552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float b = ((const float*)inputs[1])[compNdx]; 23562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float c = ((const float*)inputs[2])[compNdx]; 23572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const float res = ((const float*)outputs[0])[compNdx]; 23582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const tcu::Interval ref = fma(precision, a, b, c); 23592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (!ref.contains(res)) 23612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_failMsg << "Expected [" << compNdx << "] = " << ref; 23632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return false; 23642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka return true; 23682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 23702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23712f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkaclass FmaCase : public CommonFunctionCase 23722f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 23732f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkapublic: 23742f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FmaCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType) 23752f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : CommonFunctionCase (testCtx, getCommonFuncCaseName(baseType, precision, shaderType).c_str(), "fma", shaderType) 23762f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 23772f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("a", glu::VarType(baseType, precision))); 23782f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("b", glu::VarType(baseType, precision))); 23792f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.inputs.push_back(Symbol("c", glu::VarType(baseType, precision))); 23802f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.outputs.push_back(Symbol("res", glu::VarType(baseType, precision))); 23812f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.source = "res = fma(a, b, c);"; 23822f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka m_spec.globalDeclarations = "#extension GL_EXT_gpu_shader5 : require\n"; 23832f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23842f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23852f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TestInstance* createInstance (Context& ctx) const 23862f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 2387b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos return new FmaCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName()); 23882f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 23892f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka}; 23902f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23912f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} // anonymous 23922f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23932f7ef42cc1930880dc119fd9659d673a2f15474eRobert SipkaShaderCommonFunctionTests::ShaderCommonFunctionTests (tcu::TestContext& testCtx) 23942f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka : tcu::TestCaseGroup (testCtx, "common", "Common function tests") 23952f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 23962f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 23972f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 23982f7ef42cc1930880dc119fd9659d673a2f15474eRobert SipkaShaderCommonFunctionTests::~ShaderCommonFunctionTests (void) 23992f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 24002f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 24012f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24022f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipkavoid ShaderCommonFunctionTests::init (void) 24032f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka{ 24042f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka enum 24052f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 24062f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka VS = (1<<glu::SHADERTYPE_VERTEX), 24072f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TC = (1<<glu::SHADERTYPE_TESSELLATION_CONTROL), 24082f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka TE = (1<<glu::SHADERTYPE_TESSELLATION_EVALUATION), 24092f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka GS = (1<<glu::SHADERTYPE_GEOMETRY), 24102f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka FS = (1<<glu::SHADERTYPE_FRAGMENT), 24112f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka CS = (1<<glu::SHADERTYPE_COMPUTE), 24122f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24132f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka ALL_SHADERS = VS|TC|TE|GS|FS|CS, 24142f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka NEW_SHADERS = TC|TE|GS|CS, 24152f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka }; 24162f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24172f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // Float? Int? Uint? Shaders 24182f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<AbsCase> (this, "abs", true, true, false, ALL_SHADERS); 24192f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<SignCase> (this, "sign", true, true, false, ALL_SHADERS); 24202f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<FloorCase> (this, "floor", true, false, false, ALL_SHADERS); 24212f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<TruncCase> (this, "trunc", true, false, false, ALL_SHADERS); 24222f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<RoundCase> (this, "round", true, false, false, ALL_SHADERS); 24232f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<RoundEvenCase> (this, "roundeven", true, false, false, ALL_SHADERS); 24242f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<CeilCase> (this, "ceil", true, false, false, ALL_SHADERS); 24252f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<FractCase> (this, "fract", true, false, false, ALL_SHADERS); 24262f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // mod 24272f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<ModfCase> (this, "modf", true, false, false, ALL_SHADERS); 24282f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // min 24292f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // max 24302f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // clamp 24312f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // mix 24322f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // step 24332f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // smoothstep 24342f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<IsnanCase> (this, "isnan", true, false, false, ALL_SHADERS); 24352f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<IsinfCase> (this, "isinf", true, false, false, ALL_SHADERS); 24362f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<FloatBitsToIntCase> (this, "floatbitstoint", true, false, false, ALL_SHADERS); 24372f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<FloatBitsToUintCase> (this, "floatbitstouint", true, false, false, ALL_SHADERS); 24382f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24392f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<FrexpCase> (this, "frexp", true, false, false, ALL_SHADERS); 24402f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<LdexpCase> (this, "ldexp", true, false, false, ALL_SHADERS); 24412f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addFunctionCases<FmaCase> (this, "fma", true, false, false, ALL_SHADERS); 24422f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24432f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka // (u)intBitsToFloat() 24442f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 24452f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const deUint32 shaderBits = NEW_SHADERS; 24462f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::TestCaseGroup* intGroup = new tcu::TestCaseGroup(m_testCtx, "intbitstofloat", "intBitsToFloat() Tests"); 24472f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka tcu::TestCaseGroup* uintGroup = new tcu::TestCaseGroup(m_testCtx, "uintbitstofloat", "uintBitsToFloat() Tests"); 24482f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24492f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addChild(intGroup); 24502f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka addChild(uintGroup); 24512f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24522f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int vecSize = 1; vecSize < 4; vecSize++) 24532f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 24542f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType intType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 24552f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka const glu::DataType uintType = vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT; 24562f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24572f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++) 24582f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 24592f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka if (shaderBits & (1<<shaderType)) 24602f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka { 24612f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka intGroup->addChild(new BitsToFloatCase(getTestContext(), intType, glu::ShaderType(shaderType))); 24622f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka uintGroup->addChild(new BitsToFloatCase(getTestContext(), uintType, glu::ShaderType(shaderType))); 24632f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 24642f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 24652f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 24662f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka } 24672f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} 24682f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka 24692f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} // shaderexecutor 24702f7ef42cc1930880dc119fd9659d673a2f15474eRobert Sipka} // vkt 2471