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 Basic Compute Shader Tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es31fAtomicCounterTests.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "gluObjectWrapper.hpp"
28 #include "gluRenderContext.hpp"
30 #include "glwFunctions.hpp"
31 #include "glwEnums.hpp"
33 #include "tcuTestLog.hpp"
35 #include "deStringUtil.hpp"
36 #include "deRandom.hpp"
57 class AtomicCounterTest : public TestCase
62 OPERATION_INC = (1<<0),
63 OPERATION_DEC = (1<<1),
64 OPERATION_GET = (1<<2)
72 OFFSETTYPE_FIRST_AUTO,
73 OFFSETTYPE_DEFAULT_AUTO,
74 OFFSETTYPE_RESET_DEFAULT,
76 OFFSETTYPE_INVALID_OVERLAPPING,
77 OFFSETTYPE_INVALID_DEFAULT
82 BINDINGTYPE_BASIC = 0,
84 BINDINGTYPE_INVALID_DEFAULT
90 : atomicCounterCount (0)
91 , operations ((Operation)0)
95 , offsetType (OFFSETTYPE_NONE)
96 , bindingType (BINDINGTYPE_BASIC)
100 int atomicCounterCount;
101 Operation operations;
105 OffsetType offsetType;
106 BindingType bindingType;
109 AtomicCounterTest (Context& context, const char* name, const char* description, const TestSpec& spec);
110 ~AtomicCounterTest (void);
114 IterateResult iterate (void);
117 const TestSpec m_spec;
119 bool checkAndLogCounterValues (TestLog& log, const vector<deUint32>& counters) const;
120 bool checkAndLogCallValues (TestLog& log, const vector<deUint32>& increments, const vector<deUint32>& decrements, const vector<deUint32>& preGets, const vector<deUint32>& postGets, const vector<deUint32>& gets) const;
121 void splitBuffer (const vector<deUint32>& buffer, vector<deUint32>& increments, vector<deUint32>& decrements, vector<deUint32>& preGets, vector<deUint32>& postGets, vector<deUint32>& gets) const;
122 deUint32 getInitialValue (void) const { return m_spec.callCount * m_spec.threadCount + 1; }
124 static string generateShaderSource (const TestSpec& spec);
125 static void getCountersValues (vector<deUint32>& counterValues, const vector<deUint32>& values, int ndx, int counterCount);
126 static bool checkRange (TestLog& log, const vector<deUint32>& values, const vector<deUint32>& min, const vector<deUint32>& max);
127 static bool checkUniquenessAndLinearity (TestLog& log, const vector<deUint32>& values);
128 static bool checkPath (const vector<deUint32>& increments, const vector<deUint32>& decrements, int initialValue, const TestSpec& spec);
130 int getOperationCount (void) const;
132 AtomicCounterTest& operator= (const AtomicCounterTest&);
133 AtomicCounterTest (const AtomicCounterTest&);
136 int AtomicCounterTest::getOperationCount (void) const
140 if (m_spec.operations & OPERATION_INC)
143 if (m_spec.operations & OPERATION_DEC)
146 if (m_spec.operations == OPERATION_GET)
148 else if (m_spec.operations & OPERATION_GET)
154 AtomicCounterTest::AtomicCounterTest (Context& context, const char* name, const char* description, const TestSpec& spec)
155 : TestCase (context, name, description)
160 AtomicCounterTest::~AtomicCounterTest (void)
164 void AtomicCounterTest::init (void)
168 void AtomicCounterTest::deinit (void)
172 string AtomicCounterTest::generateShaderSource (const TestSpec& spec)
174 std::ostringstream src;
177 << "#version 310 es\n"
178 << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
181 bool wroteLayout = false;
183 switch (spec.bindingType)
185 case BINDINGTYPE_INVALID_DEFAULT:
186 src << "layout(binding=10000";
195 switch (spec.offsetType)
197 case OFFSETTYPE_DEFAULT_AUTO:
199 src << "layout(binding=1, ";
207 case OFFSETTYPE_RESET_DEFAULT:
208 DE_ASSERT(spec.atomicCounterCount > 2);
211 src << "layout(binding=1, ";
215 src << "offset=" << (4 * spec.atomicCounterCount/2);
219 case OFFSETTYPE_INVALID_DEFAULT:
221 src << "layout(binding=1, ";
235 src << ") uniform atomic_uint;\n";
239 << "layout(binding = 1, std430) buffer Output {\n";
241 if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
242 src << " uint preGet[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
244 if ((spec.operations & OPERATION_INC) != 0)
245 src << " uint increment[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
247 if ((spec.operations & OPERATION_DEC) != 0)
248 src << " uint decrement[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
250 if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
251 src << " uint postGet[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
253 if (spec.operations == OPERATION_GET)
254 src << " uint get[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
256 src << "} sb_in;\n\n";
258 for (int counterNdx = 0; counterNdx < spec.atomicCounterCount; counterNdx++)
260 bool layoutStarted = false;
262 if (spec.offsetType == OFFSETTYPE_RESET_DEFAULT && counterNdx == spec.atomicCounterCount/2)
263 src << "layout(binding=1, offset=0) uniform atomic_uint;\n";
265 switch (spec.bindingType)
267 case BINDINGTYPE_BASIC:
268 layoutStarted = true;
269 src << "layout(binding=1";
272 case BINDINGTYPE_INVALID:
273 layoutStarted = true;
274 src << "layout(binding=10000";
277 case BINDINGTYPE_INVALID_DEFAULT:
285 switch (spec.offsetType)
287 case OFFSETTYPE_NONE:
291 src << "uniform atomic_uint counter" << counterNdx << ";\n";
295 case OFFSETTYPE_BASIC:
301 src << "offset=" << (counterNdx * 4) << ") uniform atomic_uint counter" << counterNdx << ";\n";
305 case OFFSETTYPE_INVALID_DEFAULT:
309 src << "uniform atomic_uint counter" << counterNdx << ";\n";
313 case OFFSETTYPE_INVALID:
319 src << "offset=" << (1 + counterNdx * 2) << ") uniform atomic_uint counter" << counterNdx << ";\n";
323 case OFFSETTYPE_INVALID_OVERLAPPING:
329 src << "offset=0) uniform atomic_uint counter" << counterNdx << ";\n";
333 case OFFSETTYPE_REVERSE:
339 src << "offset=" << (spec.atomicCounterCount - counterNdx - 1) * 4 << ") uniform atomic_uint counter" << (spec.atomicCounterCount - counterNdx - 1) << ";\n";
343 case OFFSETTYPE_FIRST_AUTO:
344 DE_ASSERT(spec.atomicCounterCount > 2);
346 if (counterNdx + 1 == spec.atomicCounterCount)
353 src << "offset=0) uniform atomic_uint counter0;\n";
355 else if (counterNdx == 0)
362 src << "offset=4) uniform atomic_uint counter1;\n";
369 src << "uniform atomic_uint counter" << (counterNdx + 1) << ";\n";
374 case OFFSETTYPE_DEFAULT_AUTO:
375 if (counterNdx + 1 == spec.atomicCounterCount)
382 src << "offset=0) uniform atomic_uint counter0;\n";
389 src << "uniform atomic_uint counter" << (counterNdx + 1) << ";\n";
394 case OFFSETTYPE_RESET_DEFAULT:
398 if (counterNdx < spec.atomicCounterCount/2)
399 src << "uniform atomic_uint counter" << (counterNdx + spec.atomicCounterCount/2) << ";\n";
401 src << "uniform atomic_uint counter" << (counterNdx - spec.atomicCounterCount/2) << ";\n";
412 << "void main (void)\n"
415 if (spec.callCount > 1)
416 src << "\tfor (uint i = 0u; i < " << spec.callCount << "u; i++)\n";
420 << "\t\tuint id = (gl_GlobalInvocationID.x";
422 if (spec.callCount > 1)
423 src << " * "<< spec.callCount << "u";
425 if (spec.callCount > 1)
430 if (spec.atomicCounterCount > 1)
431 src << " * " << spec.atomicCounterCount << "u";
435 for (int counterNdx = 0; counterNdx < spec.atomicCounterCount; counterNdx++)
437 if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
438 src << "\t\tsb_in.preGet[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n";
440 if (spec.useBranches && ((spec.operations & (OPERATION_INC|OPERATION_DEC)) == (OPERATION_INC|OPERATION_DEC)))
443 << "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
445 << "\t\t\tsb_in.increment[id + " << counterNdx << "u] = atomicCounterIncrement(counter" << counterNdx << ");\n"
446 << "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = uint(-1);\n"
450 << "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = atomicCounterDecrement(counter" << counterNdx << ") + 1u;\n"
451 << "\t\t\tsb_in.increment[id + " << counterNdx << "u] = uint(-1);\n"
456 if ((spec.operations & OPERATION_INC) != 0)
458 if (spec.useBranches)
461 << "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
463 << "\t\t\tsb_in.increment[id + " << counterNdx << "u] = atomicCounterIncrement(counter" << counterNdx << ");\n"
467 << "\t\t\tsb_in.increment[id + " << counterNdx << "u] = uint(-1);\n"
472 src << "\t\tsb_in.increment[id + " << counterNdx << "u] = atomicCounterIncrement(counter" << counterNdx << ");\n";
475 if ((spec.operations & OPERATION_DEC) != 0)
477 if (spec.useBranches)
480 << "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
482 << "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = atomicCounterDecrement(counter" << counterNdx << ") + 1u;\n"
486 << "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = uint(-1);\n"
491 src << "\t\tsb_in.decrement[id + " << counterNdx << "u] = atomicCounterDecrement(counter" << counterNdx << ") + 1u;\n";
495 if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
496 src << "\t\tsb_in.postGet[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n";
498 if ((spec.operations == OPERATION_GET) != 0)
500 if (spec.useBranches)
503 << "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
505 << "\t\t\tsb_in.get[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n"
509 << "\t\t\tsb_in.get[id + " << counterNdx << "u] = uint(-1);\n"
513 src << "\t\tsb_in.get[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n";
524 bool AtomicCounterTest::checkAndLogCounterValues (TestLog& log, const vector<deUint32>& counters) const
526 tcu::ScopedLogSection counterSection (log, "Counter info", "Show initial value, current value and expected value of each counter.");
529 // Check that atomic counters have sensible results
530 for (int counterNdx = 0; counterNdx < (int)counters.size(); counterNdx++)
532 const deUint32 value = counters[counterNdx];
533 const deUint32 initialValue = getInitialValue();
534 deUint32 expectedValue = (deUint32)-1;
536 if ((m_spec.operations & OPERATION_INC) != 0 && (m_spec.operations & OPERATION_DEC) == 0)
537 expectedValue = initialValue + (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount - m_spec.threadCount*m_spec.callCount/2 : m_spec.threadCount*m_spec.callCount);
539 if ((m_spec.operations & OPERATION_INC) == 0 && (m_spec.operations & OPERATION_DEC) != 0)
540 expectedValue = initialValue - (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount - m_spec.threadCount*m_spec.callCount/2 : m_spec.threadCount*m_spec.callCount);
542 if ((m_spec.operations & OPERATION_INC) != 0 && (m_spec.operations & OPERATION_DEC) != 0)
543 expectedValue = initialValue + (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount - m_spec.threadCount*m_spec.callCount/2 : 0) - (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount/2 : 0);
545 if ((m_spec.operations & OPERATION_INC) == 0 && (m_spec.operations & OPERATION_DEC) == 0)
546 expectedValue = initialValue;
548 log << TestLog::Message << "atomic_uint counter" << counterNdx << " initial value: " << initialValue << ", value: " << value << ", expected: " << expectedValue << (value == expectedValue ? "" : ", failed!") << TestLog::EndMessage;
550 if (value != expectedValue)
557 void AtomicCounterTest::splitBuffer (const vector<deUint32>& buffer, vector<deUint32>& increments, vector<deUint32>& decrements, vector<deUint32>& preGets, vector<deUint32>& postGets, vector<deUint32>& gets) const
559 const int bufferValueCount = m_spec.callCount * m_spec.threadCount * m_spec.atomicCounterCount;
561 int firstPreGet = -1;
562 int firstPostGet = -1;
573 if (m_spec.operations == OPERATION_GET)
575 else if (m_spec.operations == OPERATION_INC)
577 else if (m_spec.operations == OPERATION_DEC)
579 else if (m_spec.operations == (OPERATION_GET|OPERATION_INC))
582 firstInc = bufferValueCount;
583 firstPostGet = bufferValueCount * 2;
585 else if (m_spec.operations == (OPERATION_GET|OPERATION_DEC))
588 firstDec = bufferValueCount;
589 firstPostGet = bufferValueCount * 2;
591 else if (m_spec.operations == (OPERATION_GET|OPERATION_DEC|OPERATION_INC))
594 firstInc = bufferValueCount;
595 firstDec = bufferValueCount * 2;
596 firstPostGet = bufferValueCount * 3;
598 else if (m_spec.operations == (OPERATION_DEC|OPERATION_INC))
601 firstDec = bufferValueCount;
606 for (int threadNdx = 0; threadNdx < m_spec.threadCount; threadNdx++)
608 for (int callNdx = 0; callNdx < m_spec.callCount; callNdx++)
610 for (int counterNdx = 0; counterNdx < m_spec.atomicCounterCount; counterNdx++)
612 const int id = ((threadNdx * m_spec.callCount) + callNdx) * m_spec.atomicCounterCount + counterNdx;
615 increments.push_back(buffer[firstInc + id]);
618 decrements.push_back(buffer[firstDec + id]);
620 if (firstPreGet != -1)
621 preGets.push_back(buffer[firstPreGet + id]);
623 if (firstPostGet != -1)
624 postGets.push_back(buffer[firstPostGet + id]);
627 gets.push_back(buffer[firstGet + id]);
633 void AtomicCounterTest::getCountersValues (vector<deUint32>& counterValues, const vector<deUint32>& values, int ndx, int counterCount)
635 counterValues.resize(values.size()/counterCount, 0);
637 DE_ASSERT(values.size() % counterCount == 0);
639 for (int valueNdx = 0; valueNdx < (int)counterValues.size(); valueNdx++)
640 counterValues[valueNdx] = values[valueNdx * counterCount + ndx];
643 bool AtomicCounterTest::checkRange (TestLog& log, const vector<deUint32>& values, const vector<deUint32>& min, const vector<deUint32>& max)
647 DE_ASSERT(values.size() == min.size());
648 DE_ASSERT(values.size() == max.size());
650 for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
652 if (values[valueNdx] != (deUint32)-1)
654 if (!deInRange32(values[valueNdx], min[valueNdx], max[valueNdx]))
656 if (failedCount < 20)
657 log << TestLog::Message << "Value " << values[valueNdx] << " not in range [" << min[valueNdx] << ", " << max[valueNdx] << "]." << TestLog::EndMessage;
663 if (failedCount > 20)
664 log << TestLog::Message << "Number of values not in range: " << failedCount << ", displaying first 20 values." << TestLog::EndMessage;
666 return failedCount == 0;
669 bool AtomicCounterTest::checkUniquenessAndLinearity (TestLog& log, const vector<deUint32>& values)
671 vector<deUint32> counts;
673 deUint32 minValue = (deUint32)-1;
674 deUint32 maxValue = 0;
676 DE_ASSERT(!values.empty());
678 for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
680 if (values[valueNdx] != (deUint32)-1)
682 minValue = std::min(minValue, values[valueNdx]);
683 maxValue = std::max(maxValue, values[valueNdx]);
687 counts.resize(maxValue - minValue + 1, 0);
689 for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
691 if (values[valueNdx] != (deUint32)-1)
692 counts[values[valueNdx] - minValue]++;
695 for (int countNdx = 0; countNdx < (int)counts.size(); countNdx++)
697 if (counts[countNdx] != 1)
699 if (failedCount < 20)
700 log << TestLog::Message << "Value " << (minValue + countNdx) << " is not unique. Returned " << counts[countNdx] << " times." << TestLog::EndMessage;
706 if (failedCount > 20)
707 log << TestLog::Message << "Number of values not unique: " << failedCount << ", displaying first 20 values." << TestLog::EndMessage;
709 return failedCount == 0;
712 bool AtomicCounterTest::checkPath (const vector<deUint32>& increments, const vector<deUint32>& decrements, int initialValue, const TestSpec& spec)
714 const deUint32 lastValue = initialValue + (spec.useBranches ? spec.threadCount*spec.callCount - spec.threadCount*spec.callCount/2 : 0) - (spec.useBranches ? spec.threadCount*spec.callCount/2 : 0);
717 vector<deUint32> incrementCounts;
718 vector<deUint32> decrementCounts;
720 deUint32 minValue = 0xFFFFFFFFu;
721 deUint32 maxValue = 0;
723 for (int valueNdx = 0; valueNdx < (int)increments.size(); valueNdx++)
725 if (increments[valueNdx] != (deUint32)-1)
727 minValue = std::min(minValue, increments[valueNdx]);
728 maxValue = std::max(maxValue, increments[valueNdx]);
732 for (int valueNdx = 0; valueNdx < (int)decrements.size(); valueNdx++)
734 if (decrements[valueNdx] != (deUint32)-1)
736 minValue = std::min(minValue, decrements[valueNdx]);
737 maxValue = std::max(maxValue, decrements[valueNdx]);
741 minValue = std::min(minValue, (deUint32)initialValue);
742 maxValue = std::max(maxValue, (deUint32)initialValue);
744 incrementCounts.resize(maxValue - minValue + 1, 0);
745 decrementCounts.resize(maxValue - minValue + 1, 0);
747 for (int valueNdx = 0; valueNdx < (int)increments.size(); valueNdx++)
749 if (increments[valueNdx] != (deUint32)-1)
750 incrementCounts[increments[valueNdx] - minValue]++;
753 for (int valueNdx = 0; valueNdx < (int)decrements.size(); valueNdx++)
755 if (decrements[valueNdx] != (deUint32)-1)
756 decrementCounts[decrements[valueNdx] - minValue]++;
759 int pos = initialValue - minValue;
761 while (incrementCounts[pos] + decrementCounts[pos] != 0)
763 if (incrementCounts[pos] > 0 && pos >= (int)(lastValue - minValue))
765 // If can increment and incrementation would move us away from result value, increment
766 incrementCounts[pos]--;
769 else if (decrementCounts[pos] > 0)
772 decrementCounts[pos]--;
775 else if (incrementCounts[pos] > 0)
777 // If increment moves closer to result value and can't decrement, increment
778 incrementCounts[pos]--;
784 if (pos < 0 || pos >= (int)incrementCounts.size())
788 if (minValue + pos != lastValue)
791 for (int valueNdx = 0; valueNdx < (int)incrementCounts.size(); valueNdx++)
793 if (incrementCounts[valueNdx] != 0)
797 for (int valueNdx = 0; valueNdx < (int)decrementCounts.size(); valueNdx++)
799 if (decrementCounts[valueNdx] != 0)
806 bool AtomicCounterTest::checkAndLogCallValues (TestLog& log, const vector<deUint32>& increments, const vector<deUint32>& decrements, const vector<deUint32>& preGets, const vector<deUint32>& postGets, const vector<deUint32>& gets) const
810 for (int counterNdx = 0; counterNdx < m_spec.atomicCounterCount; counterNdx++)
812 vector<deUint32> counterIncrements;
813 vector<deUint32> counterDecrements;
814 vector<deUint32> counterPreGets;
815 vector<deUint32> counterPostGets;
816 vector<deUint32> counterGets;
818 getCountersValues(counterIncrements, increments, counterNdx, m_spec.atomicCounterCount);
819 getCountersValues(counterDecrements, decrements, counterNdx, m_spec.atomicCounterCount);
820 getCountersValues(counterPreGets, preGets, counterNdx, m_spec.atomicCounterCount);
821 getCountersValues(counterPostGets, postGets, counterNdx, m_spec.atomicCounterCount);
822 getCountersValues(counterGets, gets, counterNdx, m_spec.atomicCounterCount);
824 if (m_spec.operations == OPERATION_GET)
826 tcu::ScopedLogSection valueCheck(log, ("counter" + de::toString(counterNdx) + " value check").c_str(), ("Check that counter" + de::toString(counterNdx) + " values haven't changed.").c_str());
827 int changedValues = 0;
829 for (int valueNdx = 0; valueNdx < (int)gets.size(); valueNdx++)
831 if ((!m_spec.useBranches || gets[valueNdx] != (deUint32)-1) && gets[valueNdx] != getInitialValue())
833 if (changedValues < 20)
834 log << TestLog::Message << "atomicCounter(counter" << counterNdx << ") returned " << gets[valueNdx] << " expected " << getInitialValue() << TestLog::EndMessage;
840 if (changedValues == 0)
841 log << TestLog::Message << "All values returned by atomicCounter(counter" << counterNdx << ") match initial value " << getInitialValue() << "." << TestLog::EndMessage;
842 else if (changedValues > 20)
843 log << TestLog::Message << "Total number of invalid values returned by atomicCounter(counter" << counterNdx << ") " << changedValues << " displaying first 20 values." << TestLog::EndMessage;
845 else if ((m_spec.operations & (OPERATION_INC|OPERATION_DEC)) == (OPERATION_INC|OPERATION_DEC))
847 tcu::ScopedLogSection valueCheck(log, ("counter" + de::toString(counterNdx) + " path check").c_str(), ("Check that there is order in which counter" + de::toString(counterNdx) + " increments and decrements could have happened.").c_str());
848 if (!checkPath(counterIncrements, counterDecrements, getInitialValue(), m_spec))
851 log << TestLog::Message << "No possible order of calls to atomicCounterIncrement(counter" << counterNdx << ") and atomicCounterDecrement(counter" << counterNdx << ") found." << TestLog::EndMessage;
854 log << TestLog::Message << "Found possible order of calls to atomicCounterIncrement(counter" << counterNdx << ") and atomicCounterDecrement(counter" << counterNdx << ")." << TestLog::EndMessage;
856 else if ((m_spec.operations & OPERATION_INC) != 0)
859 tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check uniqueness and linearity").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only unique and linear values.").c_str());
861 if (!checkUniquenessAndLinearity(log, counterIncrements))
864 log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned non unique values." << TestLog::EndMessage;
867 log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned only unique values." << TestLog::EndMessage;
870 if (isOk && ((m_spec.operations & OPERATION_GET) != 0))
872 tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check range").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only values values between previous and next atomicCounter(counter" + de::toString(counterNdx) + ").").c_str());
874 if (!checkRange(log, counterIncrements, counterPreGets, counterPostGets))
877 log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned value that is not between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
880 log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned only values between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
883 else if ((m_spec.operations & OPERATION_DEC) != 0)
886 tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check uniqueness and linearity").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only unique and linear values.").c_str());
888 if (!checkUniquenessAndLinearity(log, counterDecrements))
891 log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned non unique values." << TestLog::EndMessage;
894 log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned only unique values." << TestLog::EndMessage;
897 if (isOk && ((m_spec.operations & OPERATION_GET) != 0))
899 tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check range").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only values values between previous and next atomicCounter(counter" + de::toString(counterNdx) + ".").c_str());
901 if (!checkRange(log, counterDecrements, counterPostGets, counterPreGets))
904 log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned value that is not between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
907 log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned only values between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
915 TestCase::IterateResult AtomicCounterTest::iterate (void)
917 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
918 TestLog& log = m_testCtx.getLog();
919 const glu::Buffer counterBuffer (m_context.getRenderContext());
920 const glu::Buffer outputBuffer (m_context.getRenderContext());
921 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ShaderSource(glu::SHADERTYPE_COMPUTE, generateShaderSource(m_spec)));
923 const deInt32 counterBufferSize = m_spec.atomicCounterCount * 4;
924 const deInt32 ssoSize = m_spec.atomicCounterCount * m_spec.callCount * m_spec.threadCount * 4 * getOperationCount();
928 if (m_spec.offsetType == OFFSETTYPE_INVALID || m_spec.offsetType == OFFSETTYPE_INVALID_DEFAULT || m_spec.bindingType == BINDINGTYPE_INVALID || m_spec.bindingType == BINDINGTYPE_INVALID_DEFAULT || m_spec.offsetType == OFFSETTYPE_INVALID_OVERLAPPING)
932 log << TestLog::Message << "Expected program to fail, but compilation passed." << TestLog::EndMessage;
933 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile succeeded");
938 log << TestLog::Message << "Compilation failed as expected." << TestLog::EndMessage;
939 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Compile failed");
943 else if (!program.isOk())
945 log << TestLog::Message << "Compile failed." << TestLog::EndMessage;
946 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
950 gl.useProgram(program.getProgram());
951 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
953 // Create output buffer
954 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
955 gl.bufferData(GL_SHADER_STORAGE_BUFFER, ssoSize, NULL, GL_STATIC_DRAW);
956 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create output buffer");
958 // Create atomic counter buffer
960 vector<deUint32> data(m_spec.atomicCounterCount, getInitialValue());
961 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *counterBuffer);
962 gl.bufferData(GL_SHADER_STORAGE_BUFFER, counterBufferSize, &(data[0]), GL_STATIC_DRAW);
963 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create buffer for atomic counters");
966 // Bind output buffer
967 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, *outputBuffer);
968 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup output buffer");
970 // Bind atomic counter buffer
971 gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 1, *counterBuffer);
972 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup atomic counter buffer");
975 gl.dispatchCompute(m_spec.threadCount, 1, 1);
976 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
979 GLU_EXPECT_NO_ERROR(gl.getError(), "glFinish()");
981 vector<deUint32> output(ssoSize/4, 0);
982 vector<deUint32> counters(m_spec.atomicCounterCount, 0);
984 // Read back output buffer
986 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
987 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
989 void* ptr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)(output.size() * sizeof(deUint32)), GL_MAP_READ_BIT);
990 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
992 deMemcpy(&(output[0]), ptr, (int)output.size() * sizeof(deUint32));
994 if (!gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER))
996 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()");
997 TCU_CHECK_MSG(false, "Mapped buffer corrupted");
1000 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1001 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1004 // Read back counter buffer
1006 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *counterBuffer);
1007 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1009 void* ptr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)(counters.size() * sizeof(deUint32)), GL_MAP_READ_BIT);
1010 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
1012 deMemcpy(&(counters[0]), ptr, (int)counters.size() * sizeof(deUint32));
1014 if (!gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER))
1016 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()");
1017 TCU_CHECK_MSG(false, "Mapped buffer corrupted");
1020 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1021 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1026 if (!checkAndLogCounterValues(log, counters))
1030 vector<deUint32> increments;
1031 vector<deUint32> decrements;
1032 vector<deUint32> preGets;
1033 vector<deUint32> postGets;
1034 vector<deUint32> gets;
1036 splitBuffer(output, increments, decrements, preGets, postGets, gets);
1038 if (!checkAndLogCallValues(log, increments, decrements, preGets, postGets, gets))
1043 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1045 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1050 string specToTestName (const AtomicCounterTest::TestSpec& spec)
1052 std::ostringstream stream;
1054 stream << spec.atomicCounterCount << (spec.atomicCounterCount == 1 ? "_counter" : "_counters");
1055 stream << "_" << spec.callCount << (spec.callCount == 1 ? "_call" : "_calls");
1056 stream << "_" << spec.threadCount << (spec.threadCount == 1 ? "_thread" : "_threads");
1058 return stream.str();
1061 string specToTestDescription (const AtomicCounterTest::TestSpec& spec)
1063 std::ostringstream stream;
1064 bool firstOperation = 0;
1069 if ((spec.operations & AtomicCounterTest::OPERATION_GET) != 0)
1071 stream << "atomicCounter()";
1072 firstOperation = false;
1075 if ((spec.operations & AtomicCounterTest::OPERATION_INC) != 0)
1077 if (!firstOperation)
1080 stream << " atomicCounterIncrement()";
1081 firstOperation = false;
1084 if ((spec.operations & AtomicCounterTest::OPERATION_DEC) != 0)
1086 if (!firstOperation)
1089 stream << " atomicCounterDecrement()";
1090 firstOperation = false;
1093 stream << " calls with ";
1095 if (spec.useBranches)
1096 stream << " branches, ";
1098 stream << spec.atomicCounterCount << " atomic counters, " << spec.callCount << " calls and " << spec.threadCount << " threads.";
1100 return stream.str();
1103 string operationToName (const AtomicCounterTest::Operation& operations, bool useBranch)
1105 std::ostringstream stream;
1108 if ((operations & AtomicCounterTest::OPERATION_GET) != 0)
1114 if ((operations & AtomicCounterTest::OPERATION_INC) != 0)
1123 if ((operations & AtomicCounterTest::OPERATION_DEC) != 0)
1133 stream << "_branch";
1135 return stream.str();
1138 string operationToDescription (const AtomicCounterTest::Operation& operations, bool useBranch)
1140 std::ostringstream stream;
1141 bool firstOperation = 0;
1146 if ((operations & AtomicCounterTest::OPERATION_GET) != 0)
1148 stream << "atomicCounter()";
1149 firstOperation = false;
1152 if ((operations & AtomicCounterTest::OPERATION_INC) != 0)
1154 if (!firstOperation)
1157 stream << " atomicCounterIncrement()";
1158 firstOperation = false;
1161 if ((operations & AtomicCounterTest::OPERATION_DEC) != 0)
1163 if (!firstOperation)
1166 stream << " atomicCounterDecrement()";
1167 firstOperation = false;
1172 stream << " calls with branches.";
1176 return stream.str();
1179 string layoutTypesToName (const AtomicCounterTest::BindingType& bindingType, const AtomicCounterTest::OffsetType& offsetType)
1181 std::ostringstream stream;
1183 switch (bindingType)
1185 case AtomicCounterTest::BINDINGTYPE_BASIC:
1189 case AtomicCounterTest::BINDINGTYPE_INVALID:
1190 stream << "invalid_binding";
1197 if (bindingType != AtomicCounterTest::BINDINGTYPE_BASIC && offsetType != AtomicCounterTest::OFFSETTYPE_NONE)
1202 case AtomicCounterTest::OFFSETTYPE_BASIC:
1203 stream << "basic_offset";
1206 case AtomicCounterTest::OFFSETTYPE_REVERSE:
1207 stream << "reverse_offset";
1210 case AtomicCounterTest::OFFSETTYPE_INVALID:
1211 stream << "invalid_offset";
1214 case AtomicCounterTest::OFFSETTYPE_FIRST_AUTO:
1215 stream << "first_offset_set";
1218 case AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO:
1219 stream << "default_offset_set";
1222 case AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT:
1223 stream << "reset_default_offset";
1226 case AtomicCounterTest::OFFSETTYPE_NONE:
1234 return stream.str();
1237 string layoutTypesToDesc (const AtomicCounterTest::BindingType& bindingType, const AtomicCounterTest::OffsetType& offsetType)
1239 std::ostringstream stream;
1241 switch (bindingType)
1243 case AtomicCounterTest::BINDINGTYPE_BASIC:
1244 stream << "Test using atomic counters with explicit layout bindings and";
1247 case AtomicCounterTest::BINDINGTYPE_INVALID:
1248 stream << "Test using atomic counters with invalid explicit layout bindings and";
1251 case AtomicCounterTest::BINDINGTYPE_INVALID_DEFAULT:
1252 stream << "Test using atomic counters with invalid default layout binding and";
1261 case AtomicCounterTest::OFFSETTYPE_NONE:
1262 stream << " no explicit offsets.";
1265 case AtomicCounterTest::OFFSETTYPE_BASIC:
1266 stream << "explicit continuos offsets.";
1269 case AtomicCounterTest::OFFSETTYPE_REVERSE:
1270 stream << "reversed explicit offsets.";
1273 case AtomicCounterTest::OFFSETTYPE_INVALID:
1274 stream << "invalid explicit offsets.";
1277 case AtomicCounterTest::OFFSETTYPE_FIRST_AUTO:
1278 stream << "only first counter with explicit offset.";
1281 case AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO:
1282 stream << "default offset.";
1285 case AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT:
1286 stream << "default offset specified twice.";
1293 return stream.str();
1298 AtomicCounterTests::AtomicCounterTests (Context& context)
1299 : TestCaseGroup(context, "atomic_counter", "Atomic counter tests")
1301 // Runtime use tests
1303 const int counterCounts[] =
1308 const int callCounts[] =
1313 const int threadCounts[] =
1318 const AtomicCounterTest::Operation operations[] =
1320 AtomicCounterTest::OPERATION_GET,
1321 AtomicCounterTest::OPERATION_INC,
1322 AtomicCounterTest::OPERATION_DEC,
1324 (AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_GET),
1325 (AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_DEC|AtomicCounterTest::OPERATION_GET),
1327 (AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_DEC),
1328 (AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_DEC|AtomicCounterTest::OPERATION_GET)
1331 for (int operationNdx = 0; operationNdx < DE_LENGTH_OF_ARRAY(operations); operationNdx++)
1333 const AtomicCounterTest::Operation operation = operations[operationNdx];
1335 for (int branch = 0; branch < 2; branch++)
1337 const bool useBranch = (branch == 1);
1339 TestCaseGroup* operationGroup = new TestCaseGroup(m_context, operationToName(operation, useBranch).c_str(), operationToDescription(operation, useBranch).c_str());
1341 for (int counterCountNdx = 0; counterCountNdx < DE_LENGTH_OF_ARRAY(counterCounts); counterCountNdx++)
1343 const int counterCount = counterCounts[counterCountNdx];
1345 for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); callCountNdx++)
1347 const int callCount = callCounts[callCountNdx];
1349 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
1351 const int threadCount = threadCounts[threadCountNdx];
1353 if (threadCount * callCount * counterCount > 10000)
1356 if (useBranch && threadCount * callCount == 1)
1359 AtomicCounterTest::TestSpec spec;
1361 spec.atomicCounterCount = counterCount;
1362 spec.operations = operation;
1363 spec.callCount = callCount;
1364 spec.useBranches = useBranch;
1365 spec.threadCount = threadCount;
1366 spec.bindingType = AtomicCounterTest::BINDINGTYPE_BASIC;
1367 spec.offsetType = AtomicCounterTest::OFFSETTYPE_NONE;
1369 operationGroup->addChild(new AtomicCounterTest(m_context, specToTestName(spec).c_str(), specToTestDescription(spec).c_str(), spec));
1374 addChild(operationGroup);
1380 TestCaseGroup* layoutGroup = new TestCaseGroup(m_context, "layout", "Layout qualifier tests.");
1382 const int counterCounts[] = { 1, 8 };
1383 const int callCounts[] = { 1, 5 };
1384 const int threadCounts[] = { 1, 1000 };
1386 const AtomicCounterTest::Operation operations[] =
1388 (AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_GET),
1389 (AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_DEC|AtomicCounterTest::OPERATION_GET),
1390 (AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_DEC)
1393 const AtomicCounterTest::OffsetType offsetTypes[] =
1395 AtomicCounterTest::OFFSETTYPE_REVERSE,
1396 AtomicCounterTest::OFFSETTYPE_FIRST_AUTO,
1397 AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO,
1398 AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT
1401 for (int offsetTypeNdx = 0; offsetTypeNdx < DE_LENGTH_OF_ARRAY(offsetTypes); offsetTypeNdx++)
1403 const AtomicCounterTest::OffsetType offsetType = offsetTypes[offsetTypeNdx];
1405 TestCaseGroup* layoutQualifierGroup = new TestCaseGroup(m_context, layoutTypesToName(AtomicCounterTest::BINDINGTYPE_BASIC, offsetType).c_str(), layoutTypesToDesc(AtomicCounterTest::BINDINGTYPE_BASIC, offsetType).c_str());
1407 for (int operationNdx = 0; operationNdx < DE_LENGTH_OF_ARRAY(operations); operationNdx++)
1409 const AtomicCounterTest::Operation operation = operations[operationNdx];
1411 TestCaseGroup* operationGroup = new TestCaseGroup(m_context, operationToName(operation, false).c_str(), operationToDescription(operation, false).c_str());
1413 for (int counterCountNdx = 0; counterCountNdx < DE_LENGTH_OF_ARRAY(counterCounts); counterCountNdx++)
1415 const int counterCount = counterCounts[counterCountNdx];
1417 if (offsetType == AtomicCounterTest::OFFSETTYPE_FIRST_AUTO && counterCount < 3)
1420 if (offsetType == AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO && counterCount < 2)
1423 if (offsetType == AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT && counterCount < 2)
1426 if (offsetType == AtomicCounterTest::OFFSETTYPE_REVERSE && counterCount < 2)
1429 for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); callCountNdx++)
1431 const int callCount = callCounts[callCountNdx];
1433 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
1435 const int threadCount = threadCounts[threadCountNdx];
1437 AtomicCounterTest::TestSpec spec;
1439 spec.atomicCounterCount = counterCount;
1440 spec.operations = operation;
1441 spec.callCount = callCount;
1442 spec.useBranches = false;
1443 spec.threadCount = threadCount;
1444 spec.bindingType = AtomicCounterTest::BINDINGTYPE_BASIC;
1445 spec.offsetType = offsetType;
1447 operationGroup->addChild(new AtomicCounterTest(m_context, specToTestName(spec).c_str(), specToTestDescription(spec).c_str(), spec));
1451 layoutQualifierGroup->addChild(operationGroup);
1453 layoutGroup->addChild(layoutQualifierGroup);
1457 TestCaseGroup* invalidGroup = new TestCaseGroup(m_context, "invalid", "Test invalid layouts");
1460 AtomicCounterTest::TestSpec spec;
1462 spec.atomicCounterCount = 1;
1463 spec.operations = AtomicCounterTest::OPERATION_INC;
1465 spec.useBranches = false;
1466 spec.threadCount = 1;
1467 spec.bindingType = AtomicCounterTest::BINDINGTYPE_INVALID;
1468 spec.offsetType = AtomicCounterTest::OFFSETTYPE_NONE;
1470 invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_binding", "Test layout qualifiers with invalid binding.", spec));
1474 AtomicCounterTest::TestSpec spec;
1476 spec.atomicCounterCount = 1;
1477 spec.operations = AtomicCounterTest::OPERATION_INC;
1479 spec.useBranches = false;
1480 spec.threadCount = 1;
1481 spec.bindingType = AtomicCounterTest::BINDINGTYPE_INVALID_DEFAULT;
1482 spec.offsetType = AtomicCounterTest::OFFSETTYPE_NONE;
1484 invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_default_binding", "Test layout qualifiers with invalid default binding.", spec));
1488 AtomicCounterTest::TestSpec spec;
1490 spec.atomicCounterCount = 1;
1491 spec.operations = AtomicCounterTest::OPERATION_INC;
1493 spec.useBranches = false;
1494 spec.threadCount = 1;
1495 spec.bindingType = AtomicCounterTest::BINDINGTYPE_BASIC;
1496 spec.offsetType = AtomicCounterTest::OFFSETTYPE_INVALID;
1498 invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_offset_align", "Test layout qualifiers with invalid alignment offset.", spec));
1502 AtomicCounterTest::TestSpec spec;
1504 spec.atomicCounterCount = 2;
1505 spec.operations = AtomicCounterTest::OPERATION_INC;
1507 spec.useBranches = false;
1508 spec.threadCount = 1;
1509 spec.bindingType = AtomicCounterTest::BINDINGTYPE_BASIC;
1510 spec.offsetType = AtomicCounterTest::OFFSETTYPE_INVALID_OVERLAPPING;
1512 invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_offset_overlap", "Test layout qualifiers with invalid overlapping offset.", spec));
1516 AtomicCounterTest::TestSpec spec;
1518 spec.atomicCounterCount = 1;
1519 spec.operations = AtomicCounterTest::OPERATION_INC;
1521 spec.useBranches = false;
1522 spec.threadCount = 1;
1523 spec.bindingType = AtomicCounterTest::BINDINGTYPE_BASIC;
1524 spec.offsetType = AtomicCounterTest::OFFSETTYPE_INVALID_DEFAULT;
1526 invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_default_offset", "Test layout qualifiers with invalid default offset.", spec));
1529 layoutGroup->addChild(invalidGroup);
1532 addChild(layoutGroup);
1536 AtomicCounterTests::~AtomicCounterTests (void)
1540 void AtomicCounterTests::init (void)