1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Integer built-in function tests.
24 *//*--------------------------------------------------------------------*/
26 #include "vktShaderIntegerFunctionTests.hpp"
27 #include "vktShaderExecutor.hpp"
28 #include "tcuTestLog.hpp"
29 #include "tcuFormatUtil.hpp"
30 #include "tcuFloat.hpp"
31 #include "deRandom.hpp"
35 #include "deSharedPtr.hpp"
41 namespace shaderexecutor
63 HexFloat (const float value_) : value(value_) {}
66 std::ostream& operator<< (std::ostream& str, const HexFloat& v)
68 return str << v.value << " / " << tcu::toHex(tcu::Float32(v.value).bits());
73 const glu::VarType& type;
76 VarValue (const glu::VarType& type_, const void* value_) : type(type_), value(value_) {}
79 std::ostream& operator<< (std::ostream& str, const VarValue& varValue)
81 DE_ASSERT(varValue.type.isBasicType());
83 const glu::DataType basicType = varValue.type.getBasicType();
84 const glu::DataType scalarType = glu::getDataTypeScalarType(basicType);
85 const int numComponents = glu::getDataTypeScalarSize(basicType);
87 if (numComponents > 1)
88 str << glu::getDataTypeName(basicType) << "(";
90 for (int compNdx = 0; compNdx < numComponents; compNdx++)
97 case glu::TYPE_FLOAT: str << HexFloat(((const float*)varValue.value)[compNdx]); break;
98 case glu::TYPE_INT: str << ((const deInt32*)varValue.value)[compNdx]; break;
99 case glu::TYPE_UINT: str << tcu::toHex(((const deUint32*)varValue.value)[compNdx]); break;
100 case glu::TYPE_BOOL: str << (((const deUint32*)varValue.value)[compNdx] != 0 ? "true" : "false"); break;
107 if (numComponents > 1)
113 inline int getShaderUintBitCount (glu::ShaderType shaderType, glu::Precision precision)
115 // \todo [2013-10-31 pyry] Query from GL for vertex and fragment shaders.
116 DE_UNREF(shaderType);
117 const int bitCounts[] = { 9, 16, 32 };
118 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(bitCounts) == glu::PRECISION_LAST);
119 return bitCounts[precision];
122 static inline deUint32 extendSignTo32 (deUint32 integer, deUint32 integerLength)
124 DE_ASSERT(integerLength > 0 && integerLength <= 32);
126 return deUint32(0 - deInt32((integer & (1 << (integerLength - 1))) << 1)) | integer;
129 static inline deUint32 getLowBitMask (int integerLength)
131 DE_ASSERT(integerLength >= 0 && integerLength <= 32);
133 // \note: shifting more or equal to 32 => undefined behavior. Avoid it by shifting in two parts (1 << (num-1) << 1)
134 if (integerLength == 0u)
136 return ((1u << ((deUint32)integerLength - 1u)) << 1u) - 1u;
139 static void generateRandomInputData (de::Random& rnd, glu::ShaderType shaderType, glu::DataType dataType, glu::Precision precision, deUint32* dst, int numValues)
141 const int scalarSize = glu::getDataTypeScalarSize(dataType);
142 const deUint32 integerLength = (deUint32)getShaderUintBitCount(shaderType, precision);
143 const deUint32 integerMask = getLowBitMask(integerLength);
144 const bool isUnsigned = glu::isDataTypeUintOrUVec(dataType);
148 for (int valueNdx = 0; valueNdx < numValues; ++valueNdx)
149 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
150 dst[valueNdx*scalarSize + compNdx] = rnd.getUint32() & integerMask;
154 for (int valueNdx = 0; valueNdx < numValues; ++valueNdx)
155 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
156 dst[valueNdx*scalarSize + compNdx] = extendSignTo32(rnd.getUint32() & integerMask, integerLength);
160 static vector<int> getScalarSizes (const vector<Symbol>& symbols)
162 vector<int> sizes(symbols.size());
163 for (int ndx = 0; ndx < (int)symbols.size(); ++ndx)
164 sizes[ndx] = symbols[ndx].varType.getScalarSize();
168 static int computeTotalScalarSize (const vector<Symbol>& symbols)
171 for (vector<Symbol>::const_iterator sym = symbols.begin(); sym != symbols.end(); ++sym)
172 totalSize += sym->varType.getScalarSize();
176 static vector<void*> getInputOutputPointers (const vector<Symbol>& symbols, vector<deUint32>& data, const int numValues)
178 vector<void*> pointers (symbols.size());
179 int curScalarOffset = 0;
181 for (int varNdx = 0; varNdx < (int)symbols.size(); ++varNdx)
183 const Symbol& var = symbols[varNdx];
184 const int scalarSize = var.varType.getScalarSize();
186 // Uses planar layout as input/output specs do not support strides.
187 pointers[varNdx] = &data[curScalarOffset];
188 curScalarOffset += scalarSize*numValues;
191 DE_ASSERT(curScalarOffset == (int)data.size());
196 static const char* getPrecisionPostfix (glu::Precision precision)
198 static const char* s_postfix[] =
204 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_postfix) == glu::PRECISION_LAST);
205 DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
206 return s_postfix[precision];
209 static const char* getShaderTypePostfix (glu::ShaderType shaderType)
211 static const char* s_postfix[] =
220 DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
221 return s_postfix[shaderType];
224 static std::string getIntegerFuncCaseName (glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
226 return string(glu::getDataTypeName(baseType)) + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType);
229 static inline deUint32 reverseBits (deUint32 v)
231 v = (((v & 0xaaaaaaaa) >> 1) | ((v & 0x55555555) << 1));
232 v = (((v & 0xcccccccc) >> 2) | ((v & 0x33333333) << 2));
233 v = (((v & 0xf0f0f0f0) >> 4) | ((v & 0x0f0f0f0f) << 4));
234 v = (((v & 0xff00ff00) >> 8) | ((v & 0x00ff00ff) << 8));
235 return((v >> 16) | (v << 16));
238 static int findLSB (deUint32 value)
240 for (int i = 0; i < 32; i++)
248 static int findMSB (deInt32 value)
251 return 31 - deClz32((deUint32)value);
253 return 31 - deClz32(~(deUint32)value);
258 static int findMSB (deUint32 value)
261 return 31 - deClz32(value);
266 static deUint32 toPrecision (deUint32 value, int numIntegerBits)
268 return value & getLowBitMask(numIntegerBits);
271 static deInt32 toPrecision (deInt32 value, int numIntegerBits)
273 return (deInt32)extendSignTo32((deUint32)value & getLowBitMask(numIntegerBits), numIntegerBits);
276 template<class TestClass>
277 static void addFunctionCases (tcu::TestCaseGroup* parent, const char* functionName, bool intTypes, bool uintTypes, bool allPrec, deUint32 shaderBits)
279 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(parent->getTestContext(), functionName, functionName);
281 parent->addChild(group);
282 const glu::DataType scalarTypes[] =
288 for (int scalarTypeNdx = 0; scalarTypeNdx < DE_LENGTH_OF_ARRAY(scalarTypes); scalarTypeNdx++)
290 const glu::DataType scalarType = scalarTypes[scalarTypeNdx];
292 if ((!intTypes && scalarType == glu::TYPE_INT) || (!uintTypes && scalarType == glu::TYPE_UINT))
295 for (int vecSize = 1; vecSize <= 4; vecSize++)
297 for (int prec = glu::PRECISION_MEDIUMP; prec <= glu::PRECISION_HIGHP; prec++)
299 if (prec != glu::PRECISION_HIGHP && !allPrec)
302 for (int shaderTypeNdx = 0; shaderTypeNdx < glu::SHADERTYPE_LAST; shaderTypeNdx++)
304 if (shaderBits & (1<<shaderTypeNdx))
305 group->addChild(new TestClass(parent->getTestContext(), glu::DataType(scalarType + vecSize - 1), glu::Precision(prec), glu::ShaderType(shaderTypeNdx)));
314 // IntegerFunctionCase
316 class IntegerFunctionCase : public TestCase
319 IntegerFunctionCase (tcu::TestContext& testCtx, const char* name, const char* description, glu::ShaderType shaderType);
320 ~IntegerFunctionCase (void);
322 virtual void initPrograms (vk::SourceCollections& programCollection) const
324 generateSources(m_shaderType, m_spec, programCollection);
327 virtual TestInstance* createInstance (Context& context) const = 0;
330 IntegerFunctionCase (const IntegerFunctionCase& other);
331 IntegerFunctionCase& operator= (const IntegerFunctionCase& other);
333 const glu::ShaderType m_shaderType;
337 const int m_numValues;
340 IntegerFunctionCase::IntegerFunctionCase (tcu::TestContext& testCtx, const char* name, const char* description, glu::ShaderType shaderType)
341 : TestCase (testCtx, name, description)
342 , m_shaderType (shaderType)
347 IntegerFunctionCase::~IntegerFunctionCase (void)
351 // IntegerFunctionTestInstance
353 class IntegerFunctionTestInstance : public TestInstance
356 IntegerFunctionTestInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
357 : TestInstance (context)
358 , m_shaderType (shaderType)
360 , m_numValues (numValues)
362 , m_executor (createExecutor(context, m_shaderType, m_spec))
365 virtual tcu::TestStatus iterate (void);
367 virtual bool compare (const void* const* inputs, const void* const* outputs) = 0;
369 virtual void getInputValues (int numValues, void* const* values) const = 0;
371 const glu::ShaderType m_shaderType;
375 const int m_numValues;
379 std::ostringstream m_failMsg; //!< Comparison failure help message.
381 de::UniquePtr<ShaderExecutor> m_executor;
384 tcu::TestStatus IntegerFunctionTestInstance::iterate (void)
386 const int numInputScalars = computeTotalScalarSize(m_spec.inputs);
387 const int numOutputScalars = computeTotalScalarSize(m_spec.outputs);
388 vector<deUint32> inputData (numInputScalars * m_numValues);
389 vector<deUint32> outputData (numOutputScalars * m_numValues);
390 const vector<void*> inputPointers = getInputOutputPointers(m_spec.inputs, inputData, m_numValues);
391 const vector<void*> outputPointers = getInputOutputPointers(m_spec.outputs, outputData, m_numValues);
393 // Initialize input data.
394 getInputValues(m_numValues, &inputPointers[0]);
397 m_executor->execute(m_numValues, &inputPointers[0], &outputPointers[0]);
401 const vector<int> inScalarSizes = getScalarSizes(m_spec.inputs);
402 const vector<int> outScalarSizes = getScalarSizes(m_spec.outputs);
403 vector<void*> curInputPtr (inputPointers.size());
404 vector<void*> curOutputPtr (outputPointers.size());
406 tcu::TestContext& testCtx = m_context.getTestContext();
407 for (int valNdx = 0; valNdx < m_numValues; valNdx++)
409 // Set up pointers for comparison.
410 for (int inNdx = 0; inNdx < (int)curInputPtr.size(); ++inNdx)
411 curInputPtr[inNdx] = (deUint32*)inputPointers[inNdx] + inScalarSizes[inNdx]*valNdx;
413 for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); ++outNdx)
414 curOutputPtr[outNdx] = (deUint32*)outputPointers[outNdx] + outScalarSizes[outNdx]*valNdx;
416 if (!compare(&curInputPtr[0], &curOutputPtr[0]))
418 // \todo [2013-08-08 pyry] We probably want to log reference value as well?
420 testCtx.getLog() << TestLog::Message << "ERROR: comparison failed for value " << valNdx << ":\n " << m_failMsg.str() << TestLog::EndMessage;
422 testCtx.getLog() << TestLog::Message << " inputs:" << TestLog::EndMessage;
423 for (int inNdx = 0; inNdx < (int)curInputPtr.size(); inNdx++)
424 testCtx.getLog() << TestLog::Message << " " << m_spec.inputs[inNdx].name << " = "
425 << VarValue(m_spec.inputs[inNdx].varType, curInputPtr[inNdx])
426 << TestLog::EndMessage;
428 testCtx.getLog() << TestLog::Message << " outputs:" << TestLog::EndMessage;
429 for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); outNdx++)
430 testCtx.getLog() << TestLog::Message << " " << m_spec.outputs[outNdx].name << " = "
431 << VarValue(m_spec.outputs[outNdx].varType, curOutputPtr[outNdx])
432 << TestLog::EndMessage;
440 testCtx.getLog() << TestLog::Message << (m_numValues - numFailed) << " / " << m_numValues << " values passed" << TestLog::EndMessage;
443 return tcu::TestStatus::pass("Pass");
445 return tcu::TestStatus::fail("Result comparison failed");
451 class UaddCarryCaseInstance : public IntegerFunctionTestInstance
454 UaddCarryCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
455 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
459 void getInputValues (int numValues, void* const* values) const
461 de::Random rnd (deStringHash(m_name) ^ 0x235facu);
462 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
463 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
464 const int scalarSize = glu::getDataTypeScalarSize(type);
465 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
466 const deUint32 integerMask = getLowBitMask(integerLength);
467 const bool isSigned = glu::isDataTypeIntOrIVec(type);
468 deUint32* in0 = (deUint32*)values[0];
469 deUint32* in1 = (deUint32*)values[1];
477 { 0x00000000u, 0x00000000u },
478 { 0xfffffffeu, 0x00000001u },
479 { 0x00000001u, 0xfffffffeu },
480 { 0xffffffffu, 0x00000001u },
481 { 0x00000001u, 0xffffffffu },
482 { 0xfffffffeu, 0x00000002u },
483 { 0x00000002u, 0xfffffffeu },
484 { 0xffffffffu, 0xffffffffu }
487 // generate integers with proper bit count
488 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
490 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
492 in0[easyCaseNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x & integerMask;
493 in1[easyCaseNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y & integerMask;
500 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
502 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
504 in0[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in0[easyCaseNdx*scalarSize + compNdx], integerLength);
505 in1[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in1[easyCaseNdx*scalarSize + compNdx], integerLength);
510 generateRandomInputData(rnd, m_shaderType, type, precision, in0, numValues - DE_LENGTH_OF_ARRAY(easyCases));
511 generateRandomInputData(rnd, m_shaderType, type, precision, in1, numValues - DE_LENGTH_OF_ARRAY(easyCases));
514 bool compare (const void* const* inputs, const void* const* outputs)
516 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
517 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
518 const int scalarSize = glu::getDataTypeScalarSize(type);
519 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
520 const deUint32 mask0 = getLowBitMask(integerLength);
522 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
524 const deUint32 in0 = ((const deUint32*)inputs[0])[compNdx];
525 const deUint32 in1 = ((const deUint32*)inputs[1])[compNdx];
526 const deUint32 out0 = ((const deUint32*)outputs[0])[compNdx];
527 const deUint32 out1 = ((const deUint32*)outputs[1])[compNdx];
528 const deUint32 ref0 = in0+in1;
529 const deUint32 ref1 = (deUint64(in0)+deUint64(in1)) > 0xffffffffu ? 1u : 0u;
531 if (((out0&mask0) != (ref0&mask0)) || out1 != ref1)
533 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
542 class UaddCarryCase : public IntegerFunctionCase
545 UaddCarryCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
546 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "uaddCarry", shaderType)
548 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
549 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
550 m_spec.outputs.push_back(Symbol("sum", glu::VarType(baseType, precision)));
551 m_spec.outputs.push_back(Symbol("carry", glu::VarType(baseType, glu::PRECISION_LOWP)));
552 m_spec.source = "sum = uaddCarry(x, y, carry);";
555 TestInstance* createInstance (Context& ctx) const
557 return new UaddCarryCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
561 class UsubBorrowCaseInstance : public IntegerFunctionTestInstance
564 UsubBorrowCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
565 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
569 void getInputValues (int numValues, void* const* values) const
571 de::Random rnd (deStringHash(m_name) ^ 0x235facu);
572 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
573 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
574 const int scalarSize = glu::getDataTypeScalarSize(type);
575 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
576 const deUint32 integerMask = getLowBitMask(integerLength);
577 const bool isSigned = glu::isDataTypeIntOrIVec(type);
578 deUint32* in0 = (deUint32*)values[0];
579 deUint32* in1 = (deUint32*)values[1];
587 { 0x00000000u, 0x00000000u },
588 { 0x00000001u, 0x00000001u },
589 { 0x00000001u, 0x00000002u },
590 { 0x00000001u, 0xffffffffu },
591 { 0xfffffffeu, 0xffffffffu },
592 { 0xffffffffu, 0xffffffffu },
595 // generate integers with proper bit count
596 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
598 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
600 in0[easyCaseNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x & integerMask;
601 in1[easyCaseNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y & integerMask;
608 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
610 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
612 in0[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in0[easyCaseNdx*scalarSize + compNdx], integerLength);
613 in1[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in1[easyCaseNdx*scalarSize + compNdx], integerLength);
618 generateRandomInputData(rnd, m_shaderType, type, precision, in0, numValues - DE_LENGTH_OF_ARRAY(easyCases));
619 generateRandomInputData(rnd, m_shaderType, type, precision, in1, numValues - DE_LENGTH_OF_ARRAY(easyCases));
622 bool compare (const void* const* inputs, const void* const* outputs)
624 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
625 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
626 const int scalarSize = glu::getDataTypeScalarSize(type);
627 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
628 const deUint32 mask0 = getLowBitMask(integerLength);
630 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
632 const deUint32 in0 = ((const deUint32*)inputs[0])[compNdx];
633 const deUint32 in1 = ((const deUint32*)inputs[1])[compNdx];
634 const deUint32 out0 = ((const deUint32*)outputs[0])[compNdx];
635 const deUint32 out1 = ((const deUint32*)outputs[1])[compNdx];
636 const deUint32 ref0 = in0-in1;
637 const deUint32 ref1 = in0 >= in1 ? 0u : 1u;
639 if (((out0&mask0) != (ref0&mask0)) || out1 != ref1)
641 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
650 class UsubBorrowCase : public IntegerFunctionCase
653 UsubBorrowCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
654 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "usubBorrow", shaderType)
656 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
657 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
658 m_spec.outputs.push_back(Symbol("diff", glu::VarType(baseType, precision)));
659 m_spec.outputs.push_back(Symbol("carry", glu::VarType(baseType, glu::PRECISION_LOWP)));
660 m_spec.source = "diff = usubBorrow(x, y, carry);";
663 TestInstance* createInstance (Context& ctx) const
665 return new UsubBorrowCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
669 class UmulExtendedCaseInstance : public IntegerFunctionTestInstance
672 UmulExtendedCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
673 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
677 void getInputValues (int numValues, void* const* values) const
679 de::Random rnd (deStringHash(m_name) ^ 0x235facu);
680 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
681 // const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
682 const int scalarSize = glu::getDataTypeScalarSize(type);
683 deUint32* in0 = (deUint32*)values[0];
684 deUint32* in1 = (deUint32*)values[1];
693 { 0x00000000u, 0x00000000u },
694 { 0xffffffffu, 0x00000001u },
695 { 0xffffffffu, 0x00000002u },
696 { 0x00000001u, 0xffffffffu },
697 { 0x00000002u, 0xffffffffu },
698 { 0xffffffffu, 0xffffffffu },
701 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
703 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
705 in0[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x;
706 in1[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y;
712 while (valueNdx < numValues)
714 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
716 const deUint32 base0 = rnd.getUint32();
717 const deUint32 base1 = rnd.getUint32();
718 const int adj0 = rnd.getInt(0, 20);
719 const int adj1 = rnd.getInt(0, 20);
720 in0[valueNdx*scalarSize + compNdx] = base0 >> adj0;
721 in1[valueNdx*scalarSize + compNdx] = base1 >> adj1;
728 bool compare (const void* const* inputs, const void* const* outputs)
730 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
731 const int scalarSize = glu::getDataTypeScalarSize(type);
733 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
735 const deUint32 in0 = ((const deUint32*)inputs[0])[compNdx];
736 const deUint32 in1 = ((const deUint32*)inputs[1])[compNdx];
737 const deUint32 out0 = ((const deUint32*)outputs[0])[compNdx];
738 const deUint32 out1 = ((const deUint32*)outputs[1])[compNdx];
739 const deUint64 mul64 = deUint64(in0)*deUint64(in1);
740 const deUint32 ref0 = deUint32(mul64 >> 32);
741 const deUint32 ref1 = deUint32(mul64 & 0xffffffffu);
743 if (out0 != ref0 || out1 != ref1)
745 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
754 class UmulExtendedCase : public IntegerFunctionCase
757 UmulExtendedCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
758 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "umulExtended", shaderType)
760 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
761 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
762 m_spec.outputs.push_back(Symbol("msb", glu::VarType(baseType, precision)));
763 m_spec.outputs.push_back(Symbol("lsb", glu::VarType(baseType, precision)));
764 m_spec.source = "umulExtended(x, y, msb, lsb);";
767 TestInstance* createInstance (Context& ctx) const
769 return new UmulExtendedCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
773 class ImulExtendedCaseInstance : public IntegerFunctionTestInstance
776 ImulExtendedCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
777 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
781 void getInputValues (int numValues, void* const* values) const
783 de::Random rnd (deStringHash(m_name) ^ 0x224fa1u);
784 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
785 // const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
786 const int scalarSize = glu::getDataTypeScalarSize(type);
787 deUint32* in0 = (deUint32*)values[0];
788 deUint32* in1 = (deUint32*)values[1];
797 { 0x00000000u, 0x00000000u },
798 { 0xffffffffu, 0x00000002u },
799 { 0x7fffffffu, 0x00000001u },
800 { 0x7fffffffu, 0x00000002u },
801 { 0x7fffffffu, 0x7fffffffu },
802 { 0xffffffffu, 0xffffffffu },
803 { 0x7fffffffu, 0xfffffffeu },
806 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
808 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
810 in0[valueNdx*scalarSize + compNdx] = (deInt32)easyCases[easyCaseNdx].x;
811 in1[valueNdx*scalarSize + compNdx] = (deInt32)easyCases[easyCaseNdx].y;
817 while (valueNdx < numValues)
819 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
821 const deInt32 base0 = (deInt32)rnd.getUint32();
822 const deInt32 base1 = (deInt32)rnd.getUint32();
823 const int adj0 = rnd.getInt(0, 20);
824 const int adj1 = rnd.getInt(0, 20);
825 in0[valueNdx*scalarSize + compNdx] = base0 >> adj0;
826 in1[valueNdx*scalarSize + compNdx] = base1 >> adj1;
833 bool compare (const void* const* inputs, const void* const* outputs)
835 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
836 const int scalarSize = glu::getDataTypeScalarSize(type);
838 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
840 const deInt32 in0 = ((const deInt32*)inputs[0])[compNdx];
841 const deInt32 in1 = ((const deInt32*)inputs[1])[compNdx];
842 const deInt32 out0 = ((const deInt32*)outputs[0])[compNdx];
843 const deInt32 out1 = ((const deInt32*)outputs[1])[compNdx];
844 const deInt64 mul64 = deInt64(in0)*deInt64(in1);
845 const deInt32 ref0 = deInt32(mul64 >> 32);
846 const deInt32 ref1 = deInt32(mul64 & 0xffffffffu);
848 if (out0 != ref0 || out1 != ref1)
850 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
859 class ImulExtendedCase : public IntegerFunctionCase
862 ImulExtendedCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
863 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "imulExtended", shaderType)
865 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
866 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
867 m_spec.outputs.push_back(Symbol("msb", glu::VarType(baseType, precision)));
868 m_spec.outputs.push_back(Symbol("lsb", glu::VarType(baseType, precision)));
869 m_spec.source = "imulExtended(x, y, msb, lsb);";
872 TestInstance* createInstance (Context& ctx) const
874 return new ImulExtendedCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
878 class BitfieldExtractCaseInstance : public IntegerFunctionTestInstance
881 BitfieldExtractCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
882 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
886 void getInputValues (int numValues, void* const* values) const
888 de::Random rnd (deStringHash(m_name) ^ 0xa113fca2u);
889 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
890 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
891 const bool ignoreSign = precision != glu::PRECISION_HIGHP && glu::isDataTypeIntOrIVec(type);
892 const int numBits = getShaderUintBitCount(m_shaderType, precision) - (ignoreSign ? 1 : 0);
893 deUint32* inValue = (deUint32*)values[0];
894 int* inOffset = (int*)values[1];
895 int* inBits = (int*)values[2];
897 for (int valueNdx = 0; valueNdx < numValues; ++valueNdx)
899 const int bits = rnd.getInt(0, numBits);
900 const int offset = rnd.getInt(0, numBits-bits);
902 inOffset[valueNdx] = offset;
903 inBits[valueNdx] = bits;
906 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
909 bool compare (const void* const* inputs, const void* const* outputs)
911 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
912 const bool isSigned = glu::isDataTypeIntOrIVec(type);
913 const int scalarSize = glu::getDataTypeScalarSize(type);
914 const int offset = *((const int*)inputs[1]);
915 const int bits = *((const int*)inputs[2]);
917 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
919 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
920 const deUint32 out = ((const deUint32*)outputs[0])[compNdx];
921 const deUint32 valMask = (bits == 32 ? ~0u : ((1u<<bits)-1u));
922 const deUint32 baseVal = (offset == 32) ? (0) : ((value >> offset) & valMask);
923 const deUint32 ref = baseVal | ((isSigned && (baseVal & (1<<(bits-1)))) ? ~valMask : 0u);
927 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
936 class BitfieldExtractCase : public IntegerFunctionCase
939 BitfieldExtractCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
940 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldExtract", shaderType)
942 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
943 m_spec.inputs.push_back(Symbol("offset", glu::VarType(glu::TYPE_INT, precision)));
944 m_spec.inputs.push_back(Symbol("bits", glu::VarType(glu::TYPE_INT, precision)));
945 m_spec.outputs.push_back(Symbol("extracted", glu::VarType(baseType, precision)));
946 m_spec.source = "extracted = bitfieldExtract(value, offset, bits);";
949 TestInstance* createInstance (Context& ctx) const
951 return new BitfieldExtractCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
955 class BitfieldInsertCaseInstance : public IntegerFunctionTestInstance
958 BitfieldInsertCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
959 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
963 void getInputValues (int numValues, void* const* values) const
965 de::Random rnd (deStringHash(m_name) ^ 0x12c2acff);
966 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
967 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
968 const int numBits = getShaderUintBitCount(m_shaderType, precision);
969 deUint32* inBase = (deUint32*)values[0];
970 deUint32* inInsert = (deUint32*)values[1];
971 int* inOffset = (int*)values[2];
972 int* inBits = (int*)values[3];
974 for (int valueNdx = 0; valueNdx < numValues; ++valueNdx)
976 const int bits = rnd.getInt(0, numBits);
977 const int offset = rnd.getInt(0, numBits-bits);
979 inOffset[valueNdx] = offset;
980 inBits[valueNdx] = bits;
983 generateRandomInputData(rnd, m_shaderType, type, precision, inBase, numValues);
984 generateRandomInputData(rnd, m_shaderType, type, precision, inInsert, numValues);
987 bool compare (const void* const* inputs, const void* const* outputs)
989 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
990 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
991 const int scalarSize = glu::getDataTypeScalarSize(type);
992 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
993 const deUint32 cmpMask = getLowBitMask(integerLength);
994 const int offset = *((const int*)inputs[2]);
995 const int bits = *((const int*)inputs[3]);
997 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
999 const deUint32 base = ((const deUint32*)inputs[0])[compNdx];
1000 const deUint32 insert = ((const deUint32*)inputs[1])[compNdx];
1001 const deInt32 out = ((const deUint32*)outputs[0])[compNdx];
1003 const deUint32 mask = bits == 32 ? ~0u : (1u<<bits)-1;
1004 const deUint32 ref = (base & ~(mask<<offset)) | ((insert & mask)<<offset);
1006 if ((out&cmpMask) != (ref&cmpMask))
1008 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
1017 class BitfieldInsertCase : public IntegerFunctionCase
1020 BitfieldInsertCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1021 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldInsert", shaderType)
1023 m_spec.inputs.push_back(Symbol("base", glu::VarType(baseType, precision)));
1024 m_spec.inputs.push_back(Symbol("insert", glu::VarType(baseType, precision)));
1025 m_spec.inputs.push_back(Symbol("offset", glu::VarType(glu::TYPE_INT, precision)));
1026 m_spec.inputs.push_back(Symbol("bits", glu::VarType(glu::TYPE_INT, precision)));
1027 m_spec.outputs.push_back(Symbol("result", glu::VarType(baseType, precision)));
1028 m_spec.source = "result = bitfieldInsert(base, insert, offset, bits);";
1031 TestInstance* createInstance (Context& ctx) const
1033 return new BitfieldInsertCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
1037 class BitfieldReverseCaseInstance : public IntegerFunctionTestInstance
1040 BitfieldReverseCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
1041 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
1045 void getInputValues (int numValues, void* const* values) const
1047 de::Random rnd (deStringHash(m_name) ^ 0xff23a4);
1048 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1049 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1050 deUint32* inValue = (deUint32*)values[0];
1052 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1055 bool compare (const void* const* inputs, const void* const* outputs)
1057 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1058 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1059 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1060 const int scalarSize = glu::getDataTypeScalarSize(type);
1061 const deUint32 cmpMask = reverseBits(getLowBitMask(integerLength));
1063 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1065 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1066 const deInt32 out = ((const deUint32*)outputs[0])[compNdx];
1067 const deUint32 ref = reverseBits(value);
1069 if ((out&cmpMask) != (ref&cmpMask))
1071 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
1080 class BitfieldReverseCase : public IntegerFunctionCase
1083 BitfieldReverseCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1084 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldReverse", shaderType)
1086 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1087 m_spec.outputs.push_back(Symbol("result", glu::VarType(baseType, glu::PRECISION_HIGHP)));
1088 m_spec.source = "result = bitfieldReverse(value);";
1091 TestInstance* createInstance (Context& ctx) const
1093 return new BitfieldReverseCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
1097 class BitCountCaseInstance : public IntegerFunctionTestInstance
1100 BitCountCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
1101 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
1105 void getInputValues (int numValues, void* const* values) const
1107 de::Random rnd (deStringHash(m_name) ^ 0xab2cca4);
1108 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1109 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1110 deUint32* inValue = (deUint32*)values[0];
1112 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1115 bool compare (const void* const* inputs, const void* const* outputs)
1117 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1118 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1119 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1120 const int scalarSize = glu::getDataTypeScalarSize(type);
1121 const deUint32 countMask = getLowBitMask(integerLength);
1123 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1125 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1126 const int out = ((const int*)outputs[0])[compNdx];
1127 const int minRef = dePop32(value&countMask);
1128 const int maxRef = dePop32(value);
1130 if (!de::inRange(out, minRef, maxRef))
1132 m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
1141 class BitCountCase : public IntegerFunctionCase
1144 BitCountCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1145 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitCount", shaderType)
1147 const int vecSize = glu::getDataTypeScalarSize(baseType);
1148 const glu::DataType intType = vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
1150 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1151 m_spec.outputs.push_back(Symbol("count", glu::VarType(intType, glu::PRECISION_MEDIUMP)));
1152 m_spec.source = "count = bitCount(value);";
1155 TestInstance* createInstance (Context& ctx) const
1157 return new BitCountCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
1161 class FindLSBCaseInstance : public IntegerFunctionTestInstance
1164 FindLSBCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
1165 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
1169 void getInputValues (int numValues, void* const* values) const
1171 de::Random rnd (deStringHash(m_name) ^ 0x9923c2af);
1172 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1173 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1174 deUint32* inValue = (deUint32*)values[0];
1176 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1179 bool compare (const void* const* inputs, const void* const* outputs)
1181 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1182 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1183 const int scalarSize = glu::getDataTypeScalarSize(type);
1184 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1185 const deUint32 mask = getLowBitMask(integerLength);
1187 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1189 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1190 const int out = ((const int*)outputs[0])[compNdx];
1191 const int minRef = findLSB(value&mask);
1192 const int maxRef = findLSB(value);
1194 if (!de::inRange(out, minRef, maxRef))
1196 m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
1205 class FindLSBCase : public IntegerFunctionCase
1208 FindLSBCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1209 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "findLSB", shaderType)
1211 const int vecSize = glu::getDataTypeScalarSize(baseType);
1212 const glu::DataType intType = vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
1214 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1215 m_spec.outputs.push_back(Symbol("lsb", glu::VarType(intType, glu::PRECISION_LOWP)));
1216 m_spec.source = "lsb = findLSB(value);";
1219 TestInstance* createInstance (Context& ctx) const
1221 return new FindLSBCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
1225 class findMSBCaseInstance : public IntegerFunctionTestInstance
1228 findMSBCaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, int numValues, const char* name)
1229 : IntegerFunctionTestInstance (context, shaderType, spec, numValues, name)
1233 void getInputValues (int numValues, void* const* values) const
1235 de::Random rnd (deStringHash(m_name) ^ 0x742ac4e);
1236 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1237 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1238 deUint32* inValue = (deUint32*)values[0];
1240 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1243 bool compare (const void* const* inputs, const void* const* outputs)
1245 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1246 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1247 const bool isSigned = glu::isDataTypeIntOrIVec(type);
1248 const int scalarSize = glu::getDataTypeScalarSize(type);
1249 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1251 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1253 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1254 const int out = ((const deInt32*)outputs[0])[compNdx];
1255 const int minRef = isSigned ? findMSB(toPrecision(deInt32(value), integerLength)) : findMSB(toPrecision(value, integerLength));
1256 const int maxRef = isSigned ? findMSB(deInt32(value)) : findMSB(value);
1258 if (!de::inRange(out, minRef, maxRef))
1260 m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
1269 class findMSBCase : public IntegerFunctionCase
1272 findMSBCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1273 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "findMSB", shaderType)
1275 const int vecSize = glu::getDataTypeScalarSize(baseType);
1276 const glu::DataType intType = vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
1278 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1279 m_spec.outputs.push_back(Symbol("msb", glu::VarType(intType, glu::PRECISION_LOWP)));
1280 m_spec.source = "msb = findMSB(value);";
1283 TestInstance* createInstance (Context& ctx) const
1285 return new findMSBCaseInstance(ctx, m_shaderType, m_spec, m_numValues, getName());
1289 ShaderIntegerFunctionTests::ShaderIntegerFunctionTests (tcu::TestContext& testCtx)
1290 : tcu::TestCaseGroup (testCtx, "integer", "Integer function tests")
1294 ShaderIntegerFunctionTests::~ShaderIntegerFunctionTests (void)
1298 void ShaderIntegerFunctionTests::init (void)
1302 VS = (1<<glu::SHADERTYPE_VERTEX),
1303 FS = (1<<glu::SHADERTYPE_FRAGMENT),
1304 CS = (1<<glu::SHADERTYPE_COMPUTE),
1305 GS = (1<<glu::SHADERTYPE_GEOMETRY),
1306 TC = (1<<glu::SHADERTYPE_TESSELLATION_CONTROL),
1307 TE = (1<<glu::SHADERTYPE_TESSELLATION_EVALUATION),
1309 ALL_SHADERS = VS|TC|TE|GS|FS|CS
1312 // Int? Uint? AllPrec? Shaders
1313 addFunctionCases<UaddCarryCase> (this, "uaddcarry", false, true, true, ALL_SHADERS);
1314 addFunctionCases<UsubBorrowCase> (this, "usubborrow", false, true, true, ALL_SHADERS);
1315 addFunctionCases<UmulExtendedCase> (this, "umulextended", false, true, false, ALL_SHADERS);
1316 addFunctionCases<ImulExtendedCase> (this, "imulextended", true, false, false, ALL_SHADERS);
1317 addFunctionCases<BitfieldExtractCase> (this, "bitfieldextract", true, true, true, ALL_SHADERS);
1318 addFunctionCases<BitfieldInsertCase> (this, "bitfieldinsert", true, true, true, ALL_SHADERS);
1319 addFunctionCases<BitfieldReverseCase> (this, "bitfieldreverse", true, true, true, ALL_SHADERS);
1320 addFunctionCases<BitCountCase> (this, "bitcount", true, true, true, ALL_SHADERS);
1321 addFunctionCases<FindLSBCase> (this, "findlsb", true, true, true, ALL_SHADERS);
1322 addFunctionCases<findMSBCase> (this, "findMSB", true, true, true, ALL_SHADERS);