1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Floating-point packing and unpacking function tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es31fShaderPackingFunctionTests.hpp"
25 #include "glsShaderExecUtil.hpp"
26 #include "tcuTestLog.hpp"
27 #include "tcuFormatUtil.hpp"
28 #include "tcuFloat.hpp"
29 #include "deRandom.hpp"
42 using namespace gls::ShaderExecUtil;
47 inline deUint32 getUlpDiff (float a, float b)
49 const deUint32 aBits = tcu::Float32(a).bits();
50 const deUint32 bBits = tcu::Float32(b).bits();
51 return aBits > bBits ? aBits - bBits : bBits - aBits;
57 HexFloat (const float value_) : value(value_) {}
60 std::ostream& operator<< (std::ostream& str, const HexFloat& v)
62 return str << v.value << " / " << tcu::toHex(tcu::Float32(v.value).bits());
67 // ShaderPackingFunctionCase
69 class ShaderPackingFunctionCase : public TestCase
72 ShaderPackingFunctionCase (Context& context, const char* name, const char* description, glu::ShaderType shaderType);
73 ~ShaderPackingFunctionCase (void);
79 glu::ShaderType m_shaderType;
81 ShaderExecutor* m_executor;
84 ShaderPackingFunctionCase (const ShaderPackingFunctionCase& other);
85 ShaderPackingFunctionCase& operator= (const ShaderPackingFunctionCase& other);
88 ShaderPackingFunctionCase::ShaderPackingFunctionCase (Context& context, const char* name, const char* description, glu::ShaderType shaderType)
89 : TestCase (context, name, description)
90 , m_shaderType (shaderType)
91 , m_executor (DE_NULL)
93 m_spec.version = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
96 ShaderPackingFunctionCase::~ShaderPackingFunctionCase (void)
98 ShaderPackingFunctionCase::deinit();
101 void ShaderPackingFunctionCase::init (void)
103 DE_ASSERT(!m_executor);
105 m_executor = createExecutor(m_context.getRenderContext(), m_shaderType, m_spec);
106 m_testCtx.getLog() << m_executor;
108 if (!m_executor->isOk())
109 throw tcu::TestError("Compile failed");
112 void ShaderPackingFunctionCase::deinit (void)
115 m_executor = DE_NULL;
120 static const char* getPrecisionPostfix (glu::Precision precision)
122 static const char* s_postfix[] =
128 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_postfix) == glu::PRECISION_LAST);
129 DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
130 return s_postfix[precision];
133 static const char* getShaderTypePostfix (glu::ShaderType shaderType)
135 static const char* s_postfix[] =
144 DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
145 return s_postfix[shaderType];
148 class PackSnorm2x16Case : public ShaderPackingFunctionCase
151 PackSnorm2x16Case (Context& context, glu::ShaderType shaderType, glu::Precision precision)
152 : ShaderPackingFunctionCase (context, (string("packsnorm2x16") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packSnorm2x16", shaderType)
153 , m_precision (precision)
155 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, precision)));
156 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
158 m_spec.source = "out0 = packSnorm2x16(in0);";
161 IterateResult iterate (void)
163 de::Random rnd (deStringHash(getName()) ^ 0x776002);
164 std::vector<tcu::Vec2> inputs;
165 std::vector<deUint32> outputs;
166 const int maxDiff = m_precision == glu::PRECISION_HIGHP ? 1 : // Rounding only.
167 m_precision == glu::PRECISION_MEDIUMP ? 33 : // (2^-10) * (2^15) + 1
168 m_precision == glu::PRECISION_LOWP ? 129 : 0; // (2^-8) * (2^15) + 1
170 // Special values to check.
171 inputs.push_back(tcu::Vec2(0.0f, 0.0f));
172 inputs.push_back(tcu::Vec2(-1.0f, 1.0f));
173 inputs.push_back(tcu::Vec2(0.5f, -0.5f));
174 inputs.push_back(tcu::Vec2(-1.5f, 1.5f));
175 inputs.push_back(tcu::Vec2(0.25f, -0.75f));
177 // Random values, mostly in range.
178 for (int ndx = 0; ndx < 15; ndx++)
180 const float x = rnd.getFloat()*2.5f - 1.25f;
181 const float y = rnd.getFloat()*2.5f - 1.25f;
182 inputs.push_back(tcu::Vec2(x, y));
185 // Large random values.
186 for (int ndx = 0; ndx < 80; ndx++)
188 const float x = rnd.getFloat()*1e6f - 0.5e6f;
189 const float y = rnd.getFloat()*1e6f - 0.5e6f;
190 inputs.push_back(tcu::Vec2(x, y));
193 outputs.resize(inputs.size());
195 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
198 const void* in = &inputs[0];
199 void* out = &outputs[0];
201 m_executor->useProgram();
202 m_executor->execute((int)inputs.size(), &in, &out);
207 const int numValues = (int)inputs.size();
208 const int maxPrints = 10;
211 for (int valNdx = 0; valNdx < numValues; valNdx++)
213 const deUint16 ref0 = (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), -1.0f, 1.0f) * 32767.0f), -(1<<15), (1<<15)-1);
214 const deUint16 ref1 = (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), -1.0f, 1.0f) * 32767.0f), -(1<<15), (1<<15)-1);
215 const deUint32 ref = (ref1 << 16) | ref0;
216 const deUint32 res = outputs[valNdx];
217 const deUint16 res0 = (deUint16)(res & 0xffff);
218 const deUint16 res1 = (deUint16)(res >> 16);
219 const int diff0 = de::abs((int)ref0 - (int)res0);
220 const int diff1 = de::abs((int)ref1 - (int)res1);
222 if (diff0 > maxDiff || diff1 > maxDiff)
224 if (numFailed < maxPrints)
226 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
227 << ", expected packSnorm2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
228 << ", got " << tcu::toHex(res)
229 << "\n diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
230 << TestLog::EndMessage;
232 else if (numFailed == maxPrints)
233 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
239 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
241 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
242 numFailed == 0 ? "Pass" : "Result comparison failed");
249 glu::Precision m_precision;
252 class UnpackSnorm2x16Case : public ShaderPackingFunctionCase
255 UnpackSnorm2x16Case (Context& context, glu::ShaderType shaderType)
256 : ShaderPackingFunctionCase(context, (string("unpacksnorm2x16") + getShaderTypePostfix(shaderType)).c_str(), "unpackSnorm2x16", shaderType)
258 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
259 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
261 m_spec.source = "out0 = unpackSnorm2x16(in0);";
264 IterateResult iterate (void)
266 const deUint32 maxDiff = 1; // Rounding error.
267 de::Random rnd (deStringHash(getName()) ^ 0x776002);
268 std::vector<deUint32> inputs;
269 std::vector<tcu::Vec2> outputs;
271 inputs.push_back(0x00000000u);
272 inputs.push_back(0x7fff8000u);
273 inputs.push_back(0x80007fffu);
274 inputs.push_back(0xffffffffu);
275 inputs.push_back(0x0001fffeu);
278 for (int ndx = 0; ndx < 95; ndx++)
279 inputs.push_back(rnd.getUint32());
281 outputs.resize(inputs.size());
283 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
286 const void* in = &inputs[0];
287 void* out = &outputs[0];
289 m_executor->useProgram();
290 m_executor->execute((int)inputs.size(), &in, &out);
295 const int numValues = (int)inputs.size();
296 const int maxPrints = 10;
299 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
301 const deInt16 in0 = (deInt16)(deUint16)(inputs[valNdx] & 0xffff);
302 const deInt16 in1 = (deInt16)(deUint16)(inputs[valNdx] >> 16);
303 const float ref0 = de::clamp(float(in0) / 32767.f, -1.0f, 1.0f);
304 const float ref1 = de::clamp(float(in1) / 32767.f, -1.0f, 1.0f);
305 const float res0 = outputs[valNdx].x();
306 const float res1 = outputs[valNdx].y();
308 const deUint32 diff0 = getUlpDiff(ref0, res0);
309 const deUint32 diff1 = getUlpDiff(ref1, res1);
311 if (diff0 > maxDiff || diff1 > maxDiff)
313 if (numFailed < maxPrints)
315 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
316 << " expected unpackSnorm2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
317 << "vec2(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ")"
318 << ", got vec2(" << HexFloat(res0) << ", " << HexFloat(res1) << ")"
319 << "\n ULP diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
320 << TestLog::EndMessage;
322 else if (numFailed == maxPrints)
323 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
329 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
331 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
332 numFailed == 0 ? "Pass" : "Result comparison failed");
339 class PackUnorm2x16Case : public ShaderPackingFunctionCase
342 PackUnorm2x16Case (Context& context, glu::ShaderType shaderType, glu::Precision precision)
343 : ShaderPackingFunctionCase (context, (string("packunorm2x16") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packUnorm2x16", shaderType)
344 , m_precision (precision)
346 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, precision)));
347 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
349 m_spec.source = "out0 = packUnorm2x16(in0);";
352 IterateResult iterate (void)
354 de::Random rnd (deStringHash(getName()) ^ 0x776002);
355 std::vector<tcu::Vec2> inputs;
356 std::vector<deUint32> outputs;
357 const int maxDiff = m_precision == glu::PRECISION_HIGHP ? 1 : // Rounding only.
358 m_precision == glu::PRECISION_MEDIUMP ? 65 : // (2^-10) * (2^16) + 1
359 m_precision == glu::PRECISION_LOWP ? 257 : 0; // (2^-8) * (2^16) + 1
361 // Special values to check.
362 inputs.push_back(tcu::Vec2(0.0f, 0.0f));
363 inputs.push_back(tcu::Vec2(0.5f, 1.0f));
364 inputs.push_back(tcu::Vec2(1.0f, 0.5f));
365 inputs.push_back(tcu::Vec2(-0.5f, 1.5f));
366 inputs.push_back(tcu::Vec2(0.25f, 0.75f));
368 // Random values, mostly in range.
369 for (int ndx = 0; ndx < 15; ndx++)
371 const float x = rnd.getFloat()*1.25f;
372 const float y = rnd.getFloat()*1.25f;
373 inputs.push_back(tcu::Vec2(x, y));
376 // Large random values.
377 for (int ndx = 0; ndx < 80; ndx++)
379 const float x = rnd.getFloat()*1e6f - 1e5f;
380 const float y = rnd.getFloat()*1e6f - 1e5f;
381 inputs.push_back(tcu::Vec2(x, y));
384 outputs.resize(inputs.size());
386 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
389 const void* in = &inputs[0];
390 void* out = &outputs[0];
392 m_executor->useProgram();
393 m_executor->execute((int)inputs.size(), &in, &out);
398 const int numValues = (int)inputs.size();
399 const int maxPrints = 10;
402 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
404 const deUint16 ref0 = (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), 0.0f, 1.0f) * 65535.0f), 0, (1<<16)-1);
405 const deUint16 ref1 = (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), 0.0f, 1.0f) * 65535.0f), 0, (1<<16)-1);
406 const deUint32 ref = (ref1 << 16) | ref0;
407 const deUint32 res = outputs[valNdx];
408 const deUint16 res0 = (deUint16)(res & 0xffff);
409 const deUint16 res1 = (deUint16)(res >> 16);
410 const int diff0 = de::abs((int)ref0 - (int)res0);
411 const int diff1 = de::abs((int)ref1 - (int)res1);
413 if (diff0 > maxDiff || diff1 > maxDiff)
415 if (numFailed < maxPrints)
417 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
418 << ", expected packUnorm2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
419 << ", got " << tcu::toHex(res)
420 << "\n diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
421 << TestLog::EndMessage;
423 else if (numFailed == maxPrints)
424 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
430 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
432 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
433 numFailed == 0 ? "Pass" : "Result comparison failed");
440 glu::Precision m_precision;
443 class UnpackUnorm2x16Case : public ShaderPackingFunctionCase
446 UnpackUnorm2x16Case (Context& context, glu::ShaderType shaderType)
447 : ShaderPackingFunctionCase(context, (string("unpackunorm2x16") + getShaderTypePostfix(shaderType)).c_str(), "unpackUnorm2x16", shaderType)
449 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
450 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
452 m_spec.source = "out0 = unpackUnorm2x16(in0);";
455 IterateResult iterate (void)
457 const deUint32 maxDiff = 1; // Rounding error.
458 de::Random rnd (deStringHash(getName()) ^ 0x776002);
459 std::vector<deUint32> inputs;
460 std::vector<tcu::Vec2> outputs;
462 inputs.push_back(0x00000000u);
463 inputs.push_back(0x7fff8000u);
464 inputs.push_back(0x80007fffu);
465 inputs.push_back(0xffffffffu);
466 inputs.push_back(0x0001fffeu);
469 for (int ndx = 0; ndx < 95; ndx++)
470 inputs.push_back(rnd.getUint32());
472 outputs.resize(inputs.size());
474 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
477 const void* in = &inputs[0];
478 void* out = &outputs[0];
480 m_executor->useProgram();
481 m_executor->execute((int)inputs.size(), &in, &out);
486 const int numValues = (int)inputs.size();
487 const int maxPrints = 10;
490 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
492 const deUint16 in0 = (deUint16)(inputs[valNdx] & 0xffff);
493 const deUint16 in1 = (deUint16)(inputs[valNdx] >> 16);
494 const float ref0 = float(in0) / 65535.0f;
495 const float ref1 = float(in1) / 65535.0f;
496 const float res0 = outputs[valNdx].x();
497 const float res1 = outputs[valNdx].y();
499 const deUint32 diff0 = getUlpDiff(ref0, res0);
500 const deUint32 diff1 = getUlpDiff(ref1, res1);
502 if (diff0 > maxDiff || diff1 > maxDiff)
504 if (numFailed < maxPrints)
506 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
507 << " expected unpackUnorm2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
508 << "vec2(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ")"
509 << ", got vec2(" << HexFloat(res0) << ", " << HexFloat(res1) << ")"
510 << "\n ULP diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
511 << TestLog::EndMessage;
513 else if (numFailed == maxPrints)
514 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
520 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
522 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
523 numFailed == 0 ? "Pass" : "Result comparison failed");
530 class PackHalf2x16Case : public ShaderPackingFunctionCase
533 PackHalf2x16Case (Context& context, glu::ShaderType shaderType)
534 : ShaderPackingFunctionCase(context, (string("packhalf2x16") + getShaderTypePostfix(shaderType)).c_str(), "packHalf2x16", shaderType)
536 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
537 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
539 m_spec.source = "out0 = packHalf2x16(in0);";
542 IterateResult iterate (void)
544 const int maxDiff = 0; // Values can be represented exactly in mediump.
545 de::Random rnd (deStringHash(getName()) ^ 0x776002);
546 std::vector<tcu::Vec2> inputs;
547 std::vector<deUint32> outputs;
549 // Special values to check.
550 inputs.push_back(tcu::Vec2(0.0f, 0.0f));
551 inputs.push_back(tcu::Vec2(0.5f, 1.0f));
552 inputs.push_back(tcu::Vec2(1.0f, 0.5f));
553 inputs.push_back(tcu::Vec2(-0.5f, 1.5f));
554 inputs.push_back(tcu::Vec2(0.25f, 0.75f));
558 const int minExp = -14;
559 const int maxExp = 15;
561 for (int ndx = 0; ndx < 95; ndx++)
564 for (int c = 0; c < 2; c++)
566 const int s = rnd.getBool() ? 1 : -1;
567 const int exp = rnd.getInt(minExp, maxExp);
568 const deUint32 mantissa = rnd.getUint32() & ((1<<23)-1);
570 v[c] = tcu::Float32::construct(s, exp ? exp : 1 /* avoid denormals */, (1u<<23) | mantissa).asFloat();
576 // Convert input values to fp16 and back to make sure they can be represented exactly in mediump.
577 for (std::vector<tcu::Vec2>::iterator inVal = inputs.begin(); inVal != inputs.end(); ++inVal)
578 *inVal = tcu::Vec2(tcu::Float16(inVal->x()).asFloat(), tcu::Float16(inVal->y()).asFloat());
580 outputs.resize(inputs.size());
582 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
585 const void* in = &inputs[0];
586 void* out = &outputs[0];
588 m_executor->useProgram();
589 m_executor->execute((int)inputs.size(), &in, &out);
594 const int numValues = (int)inputs.size();
595 const int maxPrints = 10;
598 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
600 const deUint16 ref0 = (deUint16)tcu::Float16(inputs[valNdx].x()).bits();
601 const deUint16 ref1 = (deUint16)tcu::Float16(inputs[valNdx].y()).bits();
602 const deUint32 ref = (ref1 << 16) | ref0;
603 const deUint32 res = outputs[valNdx];
604 const deUint16 res0 = (deUint16)(res & 0xffff);
605 const deUint16 res1 = (deUint16)(res >> 16);
606 const int diff0 = de::abs((int)ref0 - (int)res0);
607 const int diff1 = de::abs((int)ref1 - (int)res1);
609 if (diff0 > maxDiff || diff1 > maxDiff)
611 if (numFailed < maxPrints)
613 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
614 << ", expected packHalf2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
615 << ", got " << tcu::toHex(res)
616 << "\n diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
617 << TestLog::EndMessage;
619 else if (numFailed == maxPrints)
620 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
626 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
628 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
629 numFailed == 0 ? "Pass" : "Result comparison failed");
636 class UnpackHalf2x16Case : public ShaderPackingFunctionCase
639 UnpackHalf2x16Case (Context& context, glu::ShaderType shaderType)
640 : ShaderPackingFunctionCase(context, (string("unpackhalf2x16") + getShaderTypePostfix(shaderType)).c_str(), "unpackHalf2x16", shaderType)
642 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
643 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_MEDIUMP)));
645 m_spec.source = "out0 = unpackHalf2x16(in0);";
648 IterateResult iterate (void)
650 const int maxDiff = 0; // All bits must be accurate.
651 de::Random rnd (deStringHash(getName()) ^ 0x776002);
652 std::vector<deUint32> inputs;
653 std::vector<tcu::Vec2> outputs;
656 inputs.push_back((tcu::Float16( 0.0f).bits() << 16) | tcu::Float16( 1.0f).bits());
657 inputs.push_back((tcu::Float16( 1.0f).bits() << 16) | tcu::Float16( 0.0f).bits());
658 inputs.push_back((tcu::Float16(-1.0f).bits() << 16) | tcu::Float16( 0.5f).bits());
659 inputs.push_back((tcu::Float16( 0.5f).bits() << 16) | tcu::Float16(-0.5f).bits());
661 // Construct random values.
663 const int minExp = -14;
664 const int maxExp = 15;
665 const int mantBits = 10;
667 for (int ndx = 0; ndx < 96; ndx++)
670 for (int c = 0; c < 2; c++)
672 const int s = rnd.getBool() ? 1 : -1;
673 const int exp = rnd.getInt(minExp, maxExp);
674 const deUint32 mantissa = rnd.getUint32() & ((1<<mantBits)-1);
675 const deUint16 value = tcu::Float16::construct(s, exp ? exp : 1 /* avoid denorm */, (deUint16)((1u<<10) | mantissa)).bits();
677 inVal |= value << (16*c);
679 inputs.push_back(inVal);
683 outputs.resize(inputs.size());
685 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
688 const void* in = &inputs[0];
689 void* out = &outputs[0];
691 m_executor->useProgram();
692 m_executor->execute((int)inputs.size(), &in, &out);
697 const int numValues = (int)inputs.size();
698 const int maxPrints = 10;
701 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
703 const deUint16 in0 = (deUint16)(inputs[valNdx] & 0xffff);
704 const deUint16 in1 = (deUint16)(inputs[valNdx] >> 16);
705 const float ref0 = tcu::Float16(in0).asFloat();
706 const float ref1 = tcu::Float16(in1).asFloat();
707 const float res0 = outputs[valNdx].x();
708 const float res1 = outputs[valNdx].y();
710 const deUint32 refBits0 = tcu::Float32(ref0).bits();
711 const deUint32 refBits1 = tcu::Float32(ref1).bits();
712 const deUint32 resBits0 = tcu::Float32(res0).bits();
713 const deUint32 resBits1 = tcu::Float32(res1).bits();
715 const int diff0 = de::abs((int)refBits0 - (int)resBits0);
716 const int diff1 = de::abs((int)refBits1 - (int)resBits1);
718 if (diff0 > maxDiff || diff1 > maxDiff)
720 if (numFailed < maxPrints)
722 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
723 << " expected unpackHalf2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
724 << "vec2(" << ref0 << " / " << tcu::toHex(refBits0) << ", " << ref1 << " / " << tcu::toHex(refBits1) << ")"
725 << ", got vec2(" << res0 << " / " << tcu::toHex(resBits0) << ", " << res1 << " / " << tcu::toHex(resBits1) << ")"
726 << "\n ULP diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
727 << TestLog::EndMessage;
729 else if (numFailed == maxPrints)
730 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
736 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
738 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
739 numFailed == 0 ? "Pass" : "Result comparison failed");
746 class PackSnorm4x8Case : public ShaderPackingFunctionCase
749 PackSnorm4x8Case (Context& context, glu::ShaderType shaderType, glu::Precision precision)
750 : ShaderPackingFunctionCase (context, (string("packsnorm4x8") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packSnorm4x8", shaderType)
751 , m_precision (precision)
753 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC4, precision)));
754 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
756 m_spec.source = "out0 = packSnorm4x8(in0);";
759 IterateResult iterate (void)
761 de::Random rnd (deStringHash(getName()) ^ 0x42f2c0);
762 std::vector<tcu::Vec4> inputs;
763 std::vector<deUint32> outputs;
764 const int maxDiff = m_precision == glu::PRECISION_HIGHP ? 1 : // Rounding only.
765 m_precision == glu::PRECISION_MEDIUMP ? 1 : // (2^-10) * (2^7) + 1
766 m_precision == glu::PRECISION_LOWP ? 2 : 0; // (2^-8) * (2^7) + 1
768 // Special values to check.
769 inputs.push_back(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
770 inputs.push_back(tcu::Vec4(-1.0f, 1.0f, -1.0f, 1.0f));
771 inputs.push_back(tcu::Vec4(0.5f, -0.5f, -0.5f, 0.5f));
772 inputs.push_back(tcu::Vec4(-1.5f, 1.5f, -1.5f, 1.5f));
773 inputs.push_back(tcu::Vec4(0.25f, -0.75f, -0.25f, 0.75f));
775 // Random values, mostly in range.
776 for (int ndx = 0; ndx < 15; ndx++)
778 const float x = rnd.getFloat()*2.5f - 1.25f;
779 const float y = rnd.getFloat()*2.5f - 1.25f;
780 const float z = rnd.getFloat()*2.5f - 1.25f;
781 const float w = rnd.getFloat()*2.5f - 1.25f;
782 inputs.push_back(tcu::Vec4(x, y, z, w));
785 // Large random values.
786 for (int ndx = 0; ndx < 80; ndx++)
788 const float x = rnd.getFloat()*1e6f - 0.5e6f;
789 const float y = rnd.getFloat()*1e6f - 0.5e6f;
790 const float z = rnd.getFloat()*1e6f - 0.5e6f;
791 const float w = rnd.getFloat()*1e6f - 0.5e6f;
792 inputs.push_back(tcu::Vec4(x, y, z, w));
795 outputs.resize(inputs.size());
797 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
800 const void* in = &inputs[0];
801 void* out = &outputs[0];
803 m_executor->useProgram();
804 m_executor->execute((int)inputs.size(), &in, &out);
809 const int numValues = (int)inputs.size();
810 const int maxPrints = 10;
813 for (int valNdx = 0; valNdx < numValues; valNdx++)
815 const deUint16 ref0 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
816 const deUint16 ref1 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
817 const deUint16 ref2 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].z(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
818 const deUint16 ref3 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].w(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
819 const deUint32 ref = (deUint32(ref3) << 24) | (deUint32(ref2) << 16) | (deUint32(ref1) << 8) | deUint32(ref0);
820 const deUint32 res = outputs[valNdx];
821 const deUint16 res0 = (deUint8)(res & 0xff);
822 const deUint16 res1 = (deUint8)((res >> 8) & 0xff);
823 const deUint16 res2 = (deUint8)((res >> 16) & 0xff);
824 const deUint16 res3 = (deUint8)((res >> 24) & 0xff);
825 const int diff0 = de::abs((int)ref0 - (int)res0);
826 const int diff1 = de::abs((int)ref1 - (int)res1);
827 const int diff2 = de::abs((int)ref2 - (int)res2);
828 const int diff3 = de::abs((int)ref3 - (int)res3);
830 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
832 if (numFailed < maxPrints)
834 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
835 << ", expected packSnorm4x8(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
836 << ", got " << tcu::toHex(res)
837 << "\n diffs = " << tcu::IVec4(diff0, diff1, diff2, diff3) << ", max diff = " << maxDiff
838 << TestLog::EndMessage;
840 else if (numFailed == maxPrints)
841 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
847 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
849 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
850 numFailed == 0 ? "Pass" : "Result comparison failed");
857 glu::Precision m_precision;
860 class UnpackSnorm4x8Case : public ShaderPackingFunctionCase
863 UnpackSnorm4x8Case (Context& context, glu::ShaderType shaderType)
864 : ShaderPackingFunctionCase(context, (string("unpacksnorm4x8") + getShaderTypePostfix(shaderType)).c_str(), "unpackSnorm4x8", shaderType)
866 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
867 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
869 m_spec.source = "out0 = unpackSnorm4x8(in0);";
872 IterateResult iterate (void)
874 const deUint32 maxDiff = 1; // Rounding error.
875 de::Random rnd (deStringHash(getName()) ^ 0x776002);
876 std::vector<deUint32> inputs;
877 std::vector<tcu::Vec4> outputs;
879 inputs.push_back(0x00000000u);
880 inputs.push_back(0x7fff8000u);
881 inputs.push_back(0x80007fffu);
882 inputs.push_back(0xffffffffu);
883 inputs.push_back(0x0001fffeu);
886 for (int ndx = 0; ndx < 95; ndx++)
887 inputs.push_back(rnd.getUint32());
889 outputs.resize(inputs.size());
891 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
894 const void* in = &inputs[0];
895 void* out = &outputs[0];
897 m_executor->useProgram();
898 m_executor->execute((int)inputs.size(), &in, &out);
903 const int numValues = (int)inputs.size();
904 const int maxPrints = 10;
907 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
909 const deInt8 in0 = (deInt8)(deUint8)(inputs[valNdx] & 0xff);
910 const deInt8 in1 = (deInt8)(deUint8)((inputs[valNdx] >> 8) & 0xff);
911 const deInt8 in2 = (deInt8)(deUint8)((inputs[valNdx] >> 16) & 0xff);
912 const deInt8 in3 = (deInt8)(deUint8)(inputs[valNdx] >> 24);
913 const float ref0 = de::clamp(float(in0) / 127.f, -1.0f, 1.0f);
914 const float ref1 = de::clamp(float(in1) / 127.f, -1.0f, 1.0f);
915 const float ref2 = de::clamp(float(in2) / 127.f, -1.0f, 1.0f);
916 const float ref3 = de::clamp(float(in3) / 127.f, -1.0f, 1.0f);
917 const float res0 = outputs[valNdx].x();
918 const float res1 = outputs[valNdx].y();
919 const float res2 = outputs[valNdx].z();
920 const float res3 = outputs[valNdx].w();
922 const deUint32 diff0 = getUlpDiff(ref0, res0);
923 const deUint32 diff1 = getUlpDiff(ref1, res1);
924 const deUint32 diff2 = getUlpDiff(ref2, res2);
925 const deUint32 diff3 = getUlpDiff(ref3, res3);
927 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
929 if (numFailed < maxPrints)
931 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
932 << " expected unpackSnorm4x8(" << tcu::toHex(inputs[valNdx]) << ") = "
933 << "vec4(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ", " << HexFloat(ref2) << ", " << HexFloat(ref3) << ")"
934 << ", got vec4(" << HexFloat(res0) << ", " << HexFloat(res1) << ", " << HexFloat(res2) << ", " << HexFloat(res3) << ")"
935 << "\n ULP diffs = (" << diff0 << ", " << diff1 << ", " << diff2 << ", " << diff3 << "), max diff = " << maxDiff
936 << TestLog::EndMessage;
938 else if (numFailed == maxPrints)
939 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
945 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
947 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
948 numFailed == 0 ? "Pass" : "Result comparison failed");
955 class PackUnorm4x8Case : public ShaderPackingFunctionCase
958 PackUnorm4x8Case (Context& context, glu::ShaderType shaderType, glu::Precision precision)
959 : ShaderPackingFunctionCase (context, (string("packunorm4x8") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packUnorm4x8", shaderType)
960 , m_precision (precision)
962 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC4, precision)));
963 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
965 m_spec.source = "out0 = packUnorm4x8(in0);";
968 IterateResult iterate (void)
970 de::Random rnd (deStringHash(getName()) ^ 0x776002);
971 std::vector<tcu::Vec4> inputs;
972 std::vector<deUint32> outputs;
973 const int maxDiff = m_precision == glu::PRECISION_HIGHP ? 1 : // Rounding only.
974 m_precision == glu::PRECISION_MEDIUMP ? 1 : // (2^-10) * (2^8) + 1
975 m_precision == glu::PRECISION_LOWP ? 2 : 0; // (2^-8) * (2^8) + 1
977 // Special values to check.
978 inputs.push_back(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
979 inputs.push_back(tcu::Vec4(-1.0f, 1.0f, -1.0f, 1.0f));
980 inputs.push_back(tcu::Vec4(0.5f, -0.5f, -0.5f, 0.5f));
981 inputs.push_back(tcu::Vec4(-1.5f, 1.5f, -1.5f, 1.5f));
982 inputs.push_back(tcu::Vec4(0.25f, -0.75f, -0.25f, 0.75f));
984 // Random values, mostly in range.
985 for (int ndx = 0; ndx < 15; ndx++)
987 const float x = rnd.getFloat()*1.25f - 0.125f;
988 const float y = rnd.getFloat()*1.25f - 0.125f;
989 const float z = rnd.getFloat()*1.25f - 0.125f;
990 const float w = rnd.getFloat()*1.25f - 0.125f;
991 inputs.push_back(tcu::Vec4(x, y, z, w));
994 // Large random values.
995 for (int ndx = 0; ndx < 80; ndx++)
997 const float x = rnd.getFloat()*1e6f - 1e5f;
998 const float y = rnd.getFloat()*1e6f - 1e5f;
999 const float z = rnd.getFloat()*1e6f - 1e5f;
1000 const float w = rnd.getFloat()*1e6f - 1e5f;
1001 inputs.push_back(tcu::Vec4(x, y, z, w));
1004 outputs.resize(inputs.size());
1006 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
1009 const void* in = &inputs[0];
1010 void* out = &outputs[0];
1012 m_executor->useProgram();
1013 m_executor->execute((int)inputs.size(), &in, &out);
1018 const int numValues = (int)inputs.size();
1019 const int maxPrints = 10;
1022 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
1024 const deUint16 ref0 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
1025 const deUint16 ref1 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
1026 const deUint16 ref2 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].z(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
1027 const deUint16 ref3 = (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].w(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
1028 const deUint32 ref = (deUint32(ref3) << 24) | (deUint32(ref2) << 16) | (deUint32(ref1) << 8) | deUint32(ref0);
1029 const deUint32 res = outputs[valNdx];
1030 const deUint16 res0 = (deUint8)(res & 0xff);
1031 const deUint16 res1 = (deUint8)((res >> 8) & 0xff);
1032 const deUint16 res2 = (deUint8)((res >> 16) & 0xff);
1033 const deUint16 res3 = (deUint8)((res >> 24) & 0xff);
1034 const int diff0 = de::abs((int)ref0 - (int)res0);
1035 const int diff1 = de::abs((int)ref1 - (int)res1);
1036 const int diff2 = de::abs((int)ref2 - (int)res2);
1037 const int diff3 = de::abs((int)ref3 - (int)res3);
1039 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
1041 if (numFailed < maxPrints)
1043 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
1044 << ", expected packUnorm4x8(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
1045 << ", got " << tcu::toHex(res)
1046 << "\n diffs = " << tcu::IVec4(diff0, diff1, diff2, diff3) << ", max diff = " << maxDiff
1047 << TestLog::EndMessage;
1049 else if (numFailed == maxPrints)
1050 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
1056 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
1058 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1059 numFailed == 0 ? "Pass" : "Result comparison failed");
1066 glu::Precision m_precision;
1069 class UnpackUnorm4x8Case : public ShaderPackingFunctionCase
1072 UnpackUnorm4x8Case (Context& context, glu::ShaderType shaderType)
1073 : ShaderPackingFunctionCase(context, (string("unpackunorm4x8") + getShaderTypePostfix(shaderType)).c_str(), "unpackUnorm4x8", shaderType)
1075 m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
1076 m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
1078 m_spec.source = "out0 = unpackUnorm4x8(in0);";
1081 IterateResult iterate (void)
1083 const deUint32 maxDiff = 1; // Rounding error.
1084 de::Random rnd (deStringHash(getName()) ^ 0x776002);
1085 std::vector<deUint32> inputs;
1086 std::vector<tcu::Vec4> outputs;
1088 inputs.push_back(0x00000000u);
1089 inputs.push_back(0x7fff8000u);
1090 inputs.push_back(0x80007fffu);
1091 inputs.push_back(0xffffffffu);
1092 inputs.push_back(0x0001fffeu);
1095 for (int ndx = 0; ndx < 95; ndx++)
1096 inputs.push_back(rnd.getUint32());
1098 outputs.resize(inputs.size());
1100 m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;
1103 const void* in = &inputs[0];
1104 void* out = &outputs[0];
1106 m_executor->useProgram();
1107 m_executor->execute((int)inputs.size(), &in, &out);
1112 const int numValues = (int)inputs.size();
1113 const int maxPrints = 10;
1116 for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
1118 const deUint8 in0 = (deUint8)(inputs[valNdx] & 0xff);
1119 const deUint8 in1 = (deUint8)((inputs[valNdx] >> 8) & 0xff);
1120 const deUint8 in2 = (deUint8)((inputs[valNdx] >> 16) & 0xff);
1121 const deUint8 in3 = (deUint8)(inputs[valNdx] >> 24);
1122 const float ref0 = de::clamp(float(in0) / 255.f, 0.0f, 1.0f);
1123 const float ref1 = de::clamp(float(in1) / 255.f, 0.0f, 1.0f);
1124 const float ref2 = de::clamp(float(in2) / 255.f, 0.0f, 1.0f);
1125 const float ref3 = de::clamp(float(in3) / 255.f, 0.0f, 1.0f);
1126 const float res0 = outputs[valNdx].x();
1127 const float res1 = outputs[valNdx].y();
1128 const float res2 = outputs[valNdx].z();
1129 const float res3 = outputs[valNdx].w();
1131 const deUint32 diff0 = getUlpDiff(ref0, res0);
1132 const deUint32 diff1 = getUlpDiff(ref1, res1);
1133 const deUint32 diff2 = getUlpDiff(ref2, res2);
1134 const deUint32 diff3 = getUlpDiff(ref3, res3);
1136 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
1138 if (numFailed < maxPrints)
1140 m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
1141 << " expected unpackUnorm4x8(" << tcu::toHex(inputs[valNdx]) << ") = "
1142 << "vec4(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ", " << HexFloat(ref2) << ", " << HexFloat(ref3) << ")"
1143 << ", got vec4(" << HexFloat(res0) << ", " << HexFloat(res1) << ", " << HexFloat(res2) << ", " << HexFloat(res3) << ")"
1144 << "\n ULP diffs = (" << diff0 << ", " << diff1 << ", " << diff2 << ", " << diff3 << "), max diff = " << maxDiff
1145 << TestLog::EndMessage;
1147 else if (numFailed == maxPrints)
1148 m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
1154 m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;
1156 m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1157 numFailed == 0 ? "Pass" : "Result comparison failed");
1164 ShaderPackingFunctionTests::ShaderPackingFunctionTests (Context& context)
1165 : TestCaseGroup(context, "pack_unpack", "Floating-point pack and unpack function tests")
1169 ShaderPackingFunctionTests::~ShaderPackingFunctionTests (void)
1173 void ShaderPackingFunctionTests::init (void)
1175 // New built-in functions in GLES 3.1
1177 const glu::ShaderType allShaderTypes[] =
1179 glu::SHADERTYPE_VERTEX,
1180 glu::SHADERTYPE_TESSELLATION_CONTROL,
1181 glu::SHADERTYPE_TESSELLATION_EVALUATION,
1182 glu::SHADERTYPE_GEOMETRY,
1183 glu::SHADERTYPE_FRAGMENT,
1184 glu::SHADERTYPE_COMPUTE
1188 for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1190 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1191 addChild(new PackSnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1195 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1196 addChild(new UnpackSnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx]));
1199 for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1201 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1202 addChild(new PackUnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1206 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1207 addChild(new UnpackUnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx]));
1210 // GLES 3 functions in new shader types.
1212 const glu::ShaderType newShaderTypes[] =
1214 glu::SHADERTYPE_GEOMETRY,
1215 glu::SHADERTYPE_COMPUTE
1219 for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1221 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1222 addChild(new PackSnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1226 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1227 addChild(new UnpackSnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx]));
1230 for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1232 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1233 addChild(new PackUnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1237 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1238 addChild(new UnpackUnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx]));
1241 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1242 addChild(new PackHalf2x16Case(m_context, newShaderTypes[shaderTypeNdx]));
1245 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1246 addChild(new UnpackHalf2x16Case(m_context, newShaderTypes[shaderTypeNdx]));