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 m_executor->setShaderSources(programCollection);
327 virtual TestInstance* createInstance (Context& context) const = 0;
328 virtual void init (void);
331 IntegerFunctionCase (const IntegerFunctionCase& other);
332 IntegerFunctionCase& operator= (const IntegerFunctionCase& other);
334 const glu::ShaderType m_shaderType;
338 de::MovePtr<ShaderExecutor> m_executor;
340 const int m_numValues;
343 IntegerFunctionCase::IntegerFunctionCase (tcu::TestContext& testCtx, const char* name, const char* description, glu::ShaderType shaderType)
344 : TestCase (testCtx, name, description)
345 , m_shaderType (shaderType)
346 , m_executor (DE_NULL)
351 IntegerFunctionCase::~IntegerFunctionCase (void)
355 void IntegerFunctionCase::init (void)
357 DE_ASSERT(!m_executor);
359 m_executor = de::MovePtr<ShaderExecutor>(createExecutor(m_shaderType, m_spec));
360 m_testCtx.getLog() << *m_executor;
363 // IntegerFunctionTestInstance
365 class IntegerFunctionTestInstance : public TestInstance
368 IntegerFunctionTestInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
369 : TestInstance (context)
370 , m_shaderType (shaderType)
372 , m_numValues (numValues)
374 , m_executor (executor)
377 virtual tcu::TestStatus iterate (void);
379 virtual bool compare (const void* const* inputs, const void* const* outputs) = 0;
381 virtual void getInputValues (int numValues, void* const* values) const = 0;
383 const glu::ShaderType m_shaderType;
387 const int m_numValues;
391 std::ostringstream m_failMsg; //!< Comparison failure help message.
393 ShaderExecutor& m_executor;
396 tcu::TestStatus IntegerFunctionTestInstance::iterate (void)
398 const int numInputScalars = computeTotalScalarSize(m_spec.inputs);
399 const int numOutputScalars = computeTotalScalarSize(m_spec.outputs);
400 vector<deUint32> inputData (numInputScalars * m_numValues);
401 vector<deUint32> outputData (numOutputScalars * m_numValues);
402 const vector<void*> inputPointers = getInputOutputPointers(m_spec.inputs, inputData, m_numValues);
403 const vector<void*> outputPointers = getInputOutputPointers(m_spec.outputs, outputData, m_numValues);
405 // Initialize input data.
406 getInputValues(m_numValues, &inputPointers[0]);
409 m_executor.execute(m_context, m_numValues, &inputPointers[0], &outputPointers[0]);
413 const vector<int> inScalarSizes = getScalarSizes(m_spec.inputs);
414 const vector<int> outScalarSizes = getScalarSizes(m_spec.outputs);
415 vector<void*> curInputPtr (inputPointers.size());
416 vector<void*> curOutputPtr (outputPointers.size());
418 tcu::TestContext& testCtx = m_context.getTestContext();
419 for (int valNdx = 0; valNdx < m_numValues; valNdx++)
421 // Set up pointers for comparison.
422 for (int inNdx = 0; inNdx < (int)curInputPtr.size(); ++inNdx)
423 curInputPtr[inNdx] = (deUint32*)inputPointers[inNdx] + inScalarSizes[inNdx]*valNdx;
425 for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); ++outNdx)
426 curOutputPtr[outNdx] = (deUint32*)outputPointers[outNdx] + outScalarSizes[outNdx]*valNdx;
428 if (!compare(&curInputPtr[0], &curOutputPtr[0]))
430 // \todo [2013-08-08 pyry] We probably want to log reference value as well?
432 testCtx.getLog() << TestLog::Message << "ERROR: comparison failed for value " << valNdx << ":\n " << m_failMsg.str() << TestLog::EndMessage;
434 testCtx.getLog() << TestLog::Message << " inputs:" << TestLog::EndMessage;
435 for (int inNdx = 0; inNdx < (int)curInputPtr.size(); inNdx++)
436 testCtx.getLog() << TestLog::Message << " " << m_spec.inputs[inNdx].name << " = "
437 << VarValue(m_spec.inputs[inNdx].varType, curInputPtr[inNdx])
438 << TestLog::EndMessage;
440 testCtx.getLog() << TestLog::Message << " outputs:" << TestLog::EndMessage;
441 for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); outNdx++)
442 testCtx.getLog() << TestLog::Message << " " << m_spec.outputs[outNdx].name << " = "
443 << VarValue(m_spec.outputs[outNdx].varType, curOutputPtr[outNdx])
444 << TestLog::EndMessage;
452 testCtx.getLog() << TestLog::Message << (m_numValues - numFailed) << " / " << m_numValues << " values passed" << TestLog::EndMessage;
455 return tcu::TestStatus::pass("Pass");
457 return tcu::TestStatus::fail("Result comparison failed");
463 class UaddCarryCaseInstance : public IntegerFunctionTestInstance
466 UaddCarryCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
467 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
471 void getInputValues (int numValues, void* const* values) const
473 de::Random rnd (deStringHash(m_name) ^ 0x235facu);
474 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
475 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
476 const int scalarSize = glu::getDataTypeScalarSize(type);
477 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
478 const deUint32 integerMask = getLowBitMask(integerLength);
479 const bool isSigned = glu::isDataTypeIntOrIVec(type);
480 deUint32* in0 = (deUint32*)values[0];
481 deUint32* in1 = (deUint32*)values[1];
489 { 0x00000000u, 0x00000000u },
490 { 0xfffffffeu, 0x00000001u },
491 { 0x00000001u, 0xfffffffeu },
492 { 0xffffffffu, 0x00000001u },
493 { 0x00000001u, 0xffffffffu },
494 { 0xfffffffeu, 0x00000002u },
495 { 0x00000002u, 0xfffffffeu },
496 { 0xffffffffu, 0xffffffffu }
499 // generate integers with proper bit count
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] = easyCases[easyCaseNdx].x & integerMask;
505 in1[easyCaseNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y & integerMask;
512 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
514 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
516 in0[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in0[easyCaseNdx*scalarSize + compNdx], integerLength);
517 in1[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in1[easyCaseNdx*scalarSize + compNdx], integerLength);
522 generateRandomInputData(rnd, m_shaderType, type, precision, in0, numValues - DE_LENGTH_OF_ARRAY(easyCases));
523 generateRandomInputData(rnd, m_shaderType, type, precision, in1, numValues - DE_LENGTH_OF_ARRAY(easyCases));
526 bool compare (const void* const* inputs, const void* const* outputs)
528 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
529 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
530 const int scalarSize = glu::getDataTypeScalarSize(type);
531 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
532 const deUint32 mask0 = getLowBitMask(integerLength);
534 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
536 const deUint32 in0 = ((const deUint32*)inputs[0])[compNdx];
537 const deUint32 in1 = ((const deUint32*)inputs[1])[compNdx];
538 const deUint32 out0 = ((const deUint32*)outputs[0])[compNdx];
539 const deUint32 out1 = ((const deUint32*)outputs[1])[compNdx];
540 const deUint32 ref0 = in0+in1;
541 const deUint32 ref1 = (deUint64(in0)+deUint64(in1)) > 0xffffffffu ? 1u : 0u;
543 if (((out0&mask0) != (ref0&mask0)) || out1 != ref1)
545 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
554 class UaddCarryCase : public IntegerFunctionCase
557 UaddCarryCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
558 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "uaddCarry", shaderType)
560 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
561 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
562 m_spec.outputs.push_back(Symbol("sum", glu::VarType(baseType, precision)));
563 m_spec.outputs.push_back(Symbol("carry", glu::VarType(baseType, glu::PRECISION_LOWP)));
564 m_spec.source = "sum = uaddCarry(x, y, carry);";
568 TestInstance* createInstance (Context& ctx) const
570 return new UaddCarryCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
574 class UsubBorrowCaseInstance : public IntegerFunctionTestInstance
577 UsubBorrowCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
578 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
582 void getInputValues (int numValues, void* const* values) const
584 de::Random rnd (deStringHash(m_name) ^ 0x235facu);
585 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
586 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
587 const int scalarSize = glu::getDataTypeScalarSize(type);
588 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
589 const deUint32 integerMask = getLowBitMask(integerLength);
590 const bool isSigned = glu::isDataTypeIntOrIVec(type);
591 deUint32* in0 = (deUint32*)values[0];
592 deUint32* in1 = (deUint32*)values[1];
600 { 0x00000000u, 0x00000000u },
601 { 0x00000001u, 0x00000001u },
602 { 0x00000001u, 0x00000002u },
603 { 0x00000001u, 0xffffffffu },
604 { 0xfffffffeu, 0xffffffffu },
605 { 0xffffffffu, 0xffffffffu },
608 // generate integers with proper bit count
609 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
611 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
613 in0[easyCaseNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x & integerMask;
614 in1[easyCaseNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y & integerMask;
621 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
623 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
625 in0[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in0[easyCaseNdx*scalarSize + compNdx], integerLength);
626 in1[easyCaseNdx*scalarSize + compNdx] = extendSignTo32(in1[easyCaseNdx*scalarSize + compNdx], integerLength);
631 generateRandomInputData(rnd, m_shaderType, type, precision, in0, numValues - DE_LENGTH_OF_ARRAY(easyCases));
632 generateRandomInputData(rnd, m_shaderType, type, precision, in1, numValues - DE_LENGTH_OF_ARRAY(easyCases));
635 bool compare (const void* const* inputs, const void* const* outputs)
637 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
638 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
639 const int scalarSize = glu::getDataTypeScalarSize(type);
640 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
641 const deUint32 mask0 = getLowBitMask(integerLength);
643 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
645 const deUint32 in0 = ((const deUint32*)inputs[0])[compNdx];
646 const deUint32 in1 = ((const deUint32*)inputs[1])[compNdx];
647 const deUint32 out0 = ((const deUint32*)outputs[0])[compNdx];
648 const deUint32 out1 = ((const deUint32*)outputs[1])[compNdx];
649 const deUint32 ref0 = in0-in1;
650 const deUint32 ref1 = in0 >= in1 ? 0u : 1u;
652 if (((out0&mask0) != (ref0&mask0)) || out1 != ref1)
654 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
663 class UsubBorrowCase : public IntegerFunctionCase
666 UsubBorrowCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
667 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "usubBorrow", shaderType)
669 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
670 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
671 m_spec.outputs.push_back(Symbol("diff", glu::VarType(baseType, precision)));
672 m_spec.outputs.push_back(Symbol("carry", glu::VarType(baseType, glu::PRECISION_LOWP)));
673 m_spec.source = "diff = usubBorrow(x, y, carry);";
677 TestInstance* createInstance (Context& ctx) const
679 return new UsubBorrowCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
683 class UmulExtendedCaseInstance : public IntegerFunctionTestInstance
686 UmulExtendedCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
687 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
691 void getInputValues (int numValues, void* const* values) const
693 de::Random rnd (deStringHash(m_name) ^ 0x235facu);
694 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
695 // const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
696 const int scalarSize = glu::getDataTypeScalarSize(type);
697 deUint32* in0 = (deUint32*)values[0];
698 deUint32* in1 = (deUint32*)values[1];
707 { 0x00000000u, 0x00000000u },
708 { 0xffffffffu, 0x00000001u },
709 { 0xffffffffu, 0x00000002u },
710 { 0x00000001u, 0xffffffffu },
711 { 0x00000002u, 0xffffffffu },
712 { 0xffffffffu, 0xffffffffu },
715 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
717 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
719 in0[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x;
720 in1[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y;
726 while (valueNdx < numValues)
728 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
730 const deUint32 base0 = rnd.getUint32();
731 const deUint32 base1 = rnd.getUint32();
732 const int adj0 = rnd.getInt(0, 20);
733 const int adj1 = rnd.getInt(0, 20);
734 in0[valueNdx*scalarSize + compNdx] = base0 >> adj0;
735 in1[valueNdx*scalarSize + compNdx] = base1 >> adj1;
742 bool compare (const void* const* inputs, const void* const* outputs)
744 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
745 const int scalarSize = glu::getDataTypeScalarSize(type);
747 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
749 const deUint32 in0 = ((const deUint32*)inputs[0])[compNdx];
750 const deUint32 in1 = ((const deUint32*)inputs[1])[compNdx];
751 const deUint32 out0 = ((const deUint32*)outputs[0])[compNdx];
752 const deUint32 out1 = ((const deUint32*)outputs[1])[compNdx];
753 const deUint64 mul64 = deUint64(in0)*deUint64(in1);
754 const deUint32 ref0 = deUint32(mul64 >> 32);
755 const deUint32 ref1 = deUint32(mul64 & 0xffffffffu);
757 if (out0 != ref0 || out1 != ref1)
759 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
768 class UmulExtendedCase : public IntegerFunctionCase
771 UmulExtendedCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
772 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "umulExtended", shaderType)
774 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
775 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
776 m_spec.outputs.push_back(Symbol("msb", glu::VarType(baseType, precision)));
777 m_spec.outputs.push_back(Symbol("lsb", glu::VarType(baseType, precision)));
778 m_spec.source = "umulExtended(x, y, msb, lsb);";
782 TestInstance* createInstance (Context& ctx) const
784 return new UmulExtendedCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
788 class ImulExtendedCaseInstance : public IntegerFunctionTestInstance
791 ImulExtendedCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
792 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
796 void getInputValues (int numValues, void* const* values) const
798 de::Random rnd (deStringHash(m_name) ^ 0x224fa1u);
799 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
800 // const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
801 const int scalarSize = glu::getDataTypeScalarSize(type);
802 deUint32* in0 = (deUint32*)values[0];
803 deUint32* in1 = (deUint32*)values[1];
812 { 0x00000000u, 0x00000000u },
813 { 0xffffffffu, 0x00000002u },
814 { 0x7fffffffu, 0x00000001u },
815 { 0x7fffffffu, 0x00000002u },
816 { 0x7fffffffu, 0x7fffffffu },
817 { 0xffffffffu, 0xffffffffu },
818 { 0x7fffffffu, 0xfffffffeu },
821 for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
823 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
825 in0[valueNdx*scalarSize + compNdx] = (deInt32)easyCases[easyCaseNdx].x;
826 in1[valueNdx*scalarSize + compNdx] = (deInt32)easyCases[easyCaseNdx].y;
832 while (valueNdx < numValues)
834 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
836 const deInt32 base0 = (deInt32)rnd.getUint32();
837 const deInt32 base1 = (deInt32)rnd.getUint32();
838 const int adj0 = rnd.getInt(0, 20);
839 const int adj1 = rnd.getInt(0, 20);
840 in0[valueNdx*scalarSize + compNdx] = base0 >> adj0;
841 in1[valueNdx*scalarSize + compNdx] = base1 >> adj1;
848 bool compare (const void* const* inputs, const void* const* outputs)
850 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
851 const int scalarSize = glu::getDataTypeScalarSize(type);
853 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
855 const deInt32 in0 = ((const deInt32*)inputs[0])[compNdx];
856 const deInt32 in1 = ((const deInt32*)inputs[1])[compNdx];
857 const deInt32 out0 = ((const deInt32*)outputs[0])[compNdx];
858 const deInt32 out1 = ((const deInt32*)outputs[1])[compNdx];
859 const deInt64 mul64 = deInt64(in0)*deInt64(in1);
860 const deInt32 ref0 = deInt32(mul64 >> 32);
861 const deInt32 ref1 = deInt32(mul64 & 0xffffffffu);
863 if (out0 != ref0 || out1 != ref1)
865 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
874 class ImulExtendedCase : public IntegerFunctionCase
877 ImulExtendedCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
878 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "imulExtended", shaderType)
880 m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
881 m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
882 m_spec.outputs.push_back(Symbol("msb", glu::VarType(baseType, precision)));
883 m_spec.outputs.push_back(Symbol("lsb", glu::VarType(baseType, precision)));
884 m_spec.source = "imulExtended(x, y, msb, lsb);";
888 TestInstance* createInstance (Context& ctx) const
890 return new ImulExtendedCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
894 class BitfieldExtractCaseInstance : public IntegerFunctionTestInstance
897 BitfieldExtractCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
898 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
902 void getInputValues (int numValues, void* const* values) const
904 de::Random rnd (deStringHash(m_name) ^ 0xa113fca2u);
905 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
906 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
907 const bool ignoreSign = precision != glu::PRECISION_HIGHP && glu::isDataTypeIntOrIVec(type);
908 const int numBits = getShaderUintBitCount(m_shaderType, precision) - (ignoreSign ? 1 : 0);
909 deUint32* inValue = (deUint32*)values[0];
910 int* inOffset = (int*)values[1];
911 int* inBits = (int*)values[2];
913 for (int valueNdx = 0; valueNdx < numValues; ++valueNdx)
915 const int bits = rnd.getInt(0, numBits);
916 const int offset = rnd.getInt(0, numBits-bits);
918 inOffset[valueNdx] = offset;
919 inBits[valueNdx] = bits;
922 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
925 bool compare (const void* const* inputs, const void* const* outputs)
927 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
928 const bool isSigned = glu::isDataTypeIntOrIVec(type);
929 const int scalarSize = glu::getDataTypeScalarSize(type);
930 const int offset = *((const int*)inputs[1]);
931 const int bits = *((const int*)inputs[2]);
933 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
935 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
936 const deUint32 out = ((const deUint32*)outputs[0])[compNdx];
937 const deUint32 valMask = (bits == 32 ? ~0u : ((1u<<bits)-1u));
938 const deUint32 baseVal = (offset == 32) ? (0) : ((value >> offset) & valMask);
939 const deUint32 ref = baseVal | ((isSigned && (baseVal & (1<<(bits-1)))) ? ~valMask : 0u);
943 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
952 class BitfieldExtractCase : public IntegerFunctionCase
955 BitfieldExtractCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
956 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldExtract", shaderType)
958 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
959 m_spec.inputs.push_back(Symbol("offset", glu::VarType(glu::TYPE_INT, precision)));
960 m_spec.inputs.push_back(Symbol("bits", glu::VarType(glu::TYPE_INT, precision)));
961 m_spec.outputs.push_back(Symbol("extracted", glu::VarType(baseType, precision)));
962 m_spec.source = "extracted = bitfieldExtract(value, offset, bits);";
966 TestInstance* createInstance (Context& ctx) const
968 return new BitfieldExtractCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
972 class BitfieldInsertCaseInstance : public IntegerFunctionTestInstance
975 BitfieldInsertCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
976 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
980 void getInputValues (int numValues, void* const* values) const
982 de::Random rnd (deStringHash(m_name) ^ 0x12c2acff);
983 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
984 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
985 const int numBits = getShaderUintBitCount(m_shaderType, precision);
986 deUint32* inBase = (deUint32*)values[0];
987 deUint32* inInsert = (deUint32*)values[1];
988 int* inOffset = (int*)values[2];
989 int* inBits = (int*)values[3];
991 for (int valueNdx = 0; valueNdx < numValues; ++valueNdx)
993 const int bits = rnd.getInt(0, numBits);
994 const int offset = rnd.getInt(0, numBits-bits);
996 inOffset[valueNdx] = offset;
997 inBits[valueNdx] = bits;
1000 generateRandomInputData(rnd, m_shaderType, type, precision, inBase, numValues);
1001 generateRandomInputData(rnd, m_shaderType, type, precision, inInsert, numValues);
1004 bool compare (const void* const* inputs, const void* const* outputs)
1006 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1007 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1008 const int scalarSize = glu::getDataTypeScalarSize(type);
1009 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1010 const deUint32 cmpMask = getLowBitMask(integerLength);
1011 const int offset = *((const int*)inputs[2]);
1012 const int bits = *((const int*)inputs[3]);
1014 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1016 const deUint32 base = ((const deUint32*)inputs[0])[compNdx];
1017 const deUint32 insert = ((const deUint32*)inputs[1])[compNdx];
1018 const deInt32 out = ((const deUint32*)outputs[0])[compNdx];
1020 const deUint32 mask = bits == 32 ? ~0u : (1u<<bits)-1;
1021 const deUint32 ref = (base & ~(mask<<offset)) | ((insert & mask)<<offset);
1023 if ((out&cmpMask) != (ref&cmpMask))
1025 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
1034 class BitfieldInsertCase : public IntegerFunctionCase
1037 BitfieldInsertCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1038 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldInsert", shaderType)
1040 m_spec.inputs.push_back(Symbol("base", glu::VarType(baseType, precision)));
1041 m_spec.inputs.push_back(Symbol("insert", glu::VarType(baseType, precision)));
1042 m_spec.inputs.push_back(Symbol("offset", glu::VarType(glu::TYPE_INT, precision)));
1043 m_spec.inputs.push_back(Symbol("bits", glu::VarType(glu::TYPE_INT, precision)));
1044 m_spec.outputs.push_back(Symbol("result", glu::VarType(baseType, precision)));
1045 m_spec.source = "result = bitfieldInsert(base, insert, offset, bits);";
1049 TestInstance* createInstance (Context& ctx) const
1051 return new BitfieldInsertCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
1055 class BitfieldReverseCaseInstance : public IntegerFunctionTestInstance
1058 BitfieldReverseCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
1059 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
1063 void getInputValues (int numValues, void* const* values) const
1065 de::Random rnd (deStringHash(m_name) ^ 0xff23a4);
1066 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1067 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1068 deUint32* inValue = (deUint32*)values[0];
1070 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1073 bool compare (const void* const* inputs, const void* const* outputs)
1075 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1076 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1077 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1078 const int scalarSize = glu::getDataTypeScalarSize(type);
1079 const deUint32 cmpMask = reverseBits(getLowBitMask(integerLength));
1081 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1083 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1084 const deInt32 out = ((const deUint32*)outputs[0])[compNdx];
1085 const deUint32 ref = reverseBits(value);
1087 if ((out&cmpMask) != (ref&cmpMask))
1089 m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
1098 class BitfieldReverseCase : public IntegerFunctionCase
1101 BitfieldReverseCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1102 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldReverse", shaderType)
1104 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1105 m_spec.outputs.push_back(Symbol("result", glu::VarType(baseType, glu::PRECISION_HIGHP)));
1106 m_spec.source = "result = bitfieldReverse(value);";
1110 TestInstance* createInstance (Context& ctx) const
1112 return new BitfieldReverseCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
1116 class BitCountCaseInstance : public IntegerFunctionTestInstance
1119 BitCountCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
1120 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
1124 void getInputValues (int numValues, void* const* values) const
1126 de::Random rnd (deStringHash(m_name) ^ 0xab2cca4);
1127 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1128 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1129 deUint32* inValue = (deUint32*)values[0];
1131 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1134 bool compare (const void* const* inputs, const void* const* outputs)
1136 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1137 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1138 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1139 const int scalarSize = glu::getDataTypeScalarSize(type);
1140 const deUint32 countMask = getLowBitMask(integerLength);
1142 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1144 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1145 const int out = ((const int*)outputs[0])[compNdx];
1146 const int minRef = dePop32(value&countMask);
1147 const int maxRef = dePop32(value);
1149 if (!de::inRange(out, minRef, maxRef))
1151 m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
1160 class BitCountCase : public IntegerFunctionCase
1163 BitCountCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1164 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitCount", shaderType)
1166 const int vecSize = glu::getDataTypeScalarSize(baseType);
1167 const glu::DataType intType = vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
1169 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1170 m_spec.outputs.push_back(Symbol("count", glu::VarType(intType, glu::PRECISION_MEDIUMP)));
1171 m_spec.source = "count = bitCount(value);";
1175 TestInstance* createInstance (Context& ctx) const
1177 return new BitCountCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
1181 class FindLSBCaseInstance : public IntegerFunctionTestInstance
1184 FindLSBCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
1185 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
1189 void getInputValues (int numValues, void* const* values) const
1191 de::Random rnd (deStringHash(m_name) ^ 0x9923c2af);
1192 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1193 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1194 deUint32* inValue = (deUint32*)values[0];
1196 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1199 bool compare (const void* const* inputs, const void* const* outputs)
1201 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1202 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1203 const int scalarSize = glu::getDataTypeScalarSize(type);
1204 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1205 const deUint32 mask = getLowBitMask(integerLength);
1207 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1209 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1210 const int out = ((const int*)outputs[0])[compNdx];
1211 const int minRef = findLSB(value&mask);
1212 const int maxRef = findLSB(value);
1214 if (!de::inRange(out, minRef, maxRef))
1216 m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
1225 class FindLSBCase : public IntegerFunctionCase
1228 FindLSBCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1229 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "findLSB", shaderType)
1231 const int vecSize = glu::getDataTypeScalarSize(baseType);
1232 const glu::DataType intType = vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
1234 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1235 m_spec.outputs.push_back(Symbol("lsb", glu::VarType(intType, glu::PRECISION_LOWP)));
1236 m_spec.source = "lsb = findLSB(value);";
1240 TestInstance* createInstance (Context& ctx) const
1242 return new FindLSBCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
1246 class findMSBCaseInstance : public IntegerFunctionTestInstance
1249 findMSBCaseInstance (Context& context, glu::ShaderType shaderType, ShaderSpec spec, ShaderExecutor& executor, int numValues, const char* name)
1250 : IntegerFunctionTestInstance (context, shaderType, spec, executor, numValues, name)
1254 void getInputValues (int numValues, void* const* values) const
1256 de::Random rnd (deStringHash(m_name) ^ 0x742ac4e);
1257 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1258 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1259 deUint32* inValue = (deUint32*)values[0];
1261 generateRandomInputData(rnd, m_shaderType, type, precision, inValue, numValues);
1264 bool compare (const void* const* inputs, const void* const* outputs)
1266 const glu::DataType type = m_spec.inputs[0].varType.getBasicType();
1267 const glu::Precision precision = m_spec.inputs[0].varType.getPrecision();
1268 const bool isSigned = glu::isDataTypeIntOrIVec(type);
1269 const int scalarSize = glu::getDataTypeScalarSize(type);
1270 const int integerLength = getShaderUintBitCount(m_shaderType, precision);
1272 for (int compNdx = 0; compNdx < scalarSize; compNdx++)
1274 const deUint32 value = ((const deUint32*)inputs[0])[compNdx];
1275 const int out = ((const deInt32*)outputs[0])[compNdx];
1276 const int minRef = isSigned ? findMSB(toPrecision(deInt32(value), integerLength)) : findMSB(toPrecision(value, integerLength));
1277 const int maxRef = isSigned ? findMSB(deInt32(value)) : findMSB(value);
1279 if (!de::inRange(out, minRef, maxRef))
1281 m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
1290 class findMSBCase : public IntegerFunctionCase
1293 findMSBCase (tcu::TestContext& testCtx, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
1294 : IntegerFunctionCase (testCtx, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "findMSB", shaderType)
1296 const int vecSize = glu::getDataTypeScalarSize(baseType);
1297 const glu::DataType intType = vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
1299 m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
1300 m_spec.outputs.push_back(Symbol("msb", glu::VarType(intType, glu::PRECISION_LOWP)));
1301 m_spec.source = "msb = findMSB(value);";
1305 TestInstance* createInstance (Context& ctx) const
1307 return new findMSBCaseInstance(ctx, m_shaderType, m_spec, *m_executor, m_numValues, getName());
1311 ShaderIntegerFunctionTests::ShaderIntegerFunctionTests (tcu::TestContext& testCtx)
1312 : tcu::TestCaseGroup (testCtx, "integer", "Integer function tests")
1316 ShaderIntegerFunctionTests::~ShaderIntegerFunctionTests (void)
1320 void ShaderIntegerFunctionTests::init (void)
1324 VS = (1<<glu::SHADERTYPE_VERTEX),
1325 FS = (1<<glu::SHADERTYPE_FRAGMENT),
1326 CS = (1<<glu::SHADERTYPE_COMPUTE),
1327 GS = (1<<glu::SHADERTYPE_GEOMETRY),
1328 TC = (1<<glu::SHADERTYPE_TESSELLATION_CONTROL),
1329 TE = (1<<glu::SHADERTYPE_TESSELLATION_EVALUATION),
1331 ALL_SHADERS = VS|TC|TE|GS|FS|CS
1334 // Int? Uint? AllPrec? Shaders
1335 addFunctionCases<UaddCarryCase> (this, "uaddcarry", false, true, true, ALL_SHADERS);
1336 addFunctionCases<UsubBorrowCase> (this, "usubborrow", false, true, true, ALL_SHADERS);
1337 addFunctionCases<UmulExtendedCase> (this, "umulextended", false, true, false, ALL_SHADERS);
1338 addFunctionCases<ImulExtendedCase> (this, "imulextended", true, false, false, ALL_SHADERS);
1339 addFunctionCases<BitfieldExtractCase> (this, "bitfieldextract", true, true, true, ALL_SHADERS);
1340 addFunctionCases<BitfieldInsertCase> (this, "bitfieldinsert", true, true, true, ALL_SHADERS);
1341 addFunctionCases<BitfieldReverseCase> (this, "bitfieldreverse", true, true, true, ALL_SHADERS);
1342 addFunctionCases<BitCountCase> (this, "bitcount", true, true, true, ALL_SHADERS);
1343 addFunctionCases<FindLSBCase> (this, "findlsb", true, true, true, ALL_SHADERS);
1344 addFunctionCases<findMSBCase> (this, "findMSB", true, true, true, ALL_SHADERS);