1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 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 Buffer data upload tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es2fBufferWriteTests.hpp"
25 #include "es2fBufferTestUtil.hpp"
26 #include "tcuTestLog.hpp"
27 #include "gluStrUtil.hpp"
30 #include "deRandom.hpp"
31 #include "deStringUtil.hpp"
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
52 using namespace BufferTestUtil;
63 DataStoreSpec (deUint32 target_, deUint32 usage_, int size_)
75 struct DataStoreSpecVecBuilder
77 std::vector<DataStoreSpec>& list;
79 DataStoreSpecVecBuilder (std::vector<DataStoreSpec>& list_)
84 DataStoreSpecVecBuilder& operator<< (const DataStoreSpec& spec)
91 struct RangeVecBuilder
93 std::vector<tcu::IVec2>& list;
95 RangeVecBuilder (std::vector<tcu::IVec2>& list_)
100 RangeVecBuilder& operator<< (const tcu::IVec2& vec)
107 template<typename Iterator>
108 static bool isRangeListValid (Iterator begin, Iterator end)
113 tcu::IVec2 prev = *begin;
116 for (; begin != end; ++begin)
118 tcu::IVec2 cur = *begin;
119 if (cur.x() <= prev.x() || cur.x() <= prev.x()+prev.y())
128 inline bool rangesIntersect (const tcu::IVec2& a, const tcu::IVec2& b)
130 return de::inRange(a.x(), b.x(), b.x()+b.y()) || de::inRange(a.x()+a.y(), b.x(), b.x()+b.y()) ||
131 de::inRange(b.x(), a.x(), a.x()+a.y()) || de::inRange(b.x()+b.y(), a.x(), a.x()+a.y());
134 inline tcu::IVec2 unionRanges (const tcu::IVec2& a, const tcu::IVec2& b)
136 DE_ASSERT(rangesIntersect(a, b));
138 int start = de::min(a.x(), b.x());
139 int end = de::max(a.x()+a.y(), b.x()+b.y());
141 return tcu::IVec2(start, end-start);
144 //! Updates range list (start, len) with a new range.
145 std::vector<tcu::IVec2> addRangeToList (const std::vector<tcu::IVec2>& oldList, const tcu::IVec2& newRange)
147 DE_ASSERT(newRange.y() > 0);
149 std::vector<tcu::IVec2> newList;
150 std::vector<tcu::IVec2>::const_iterator oldListIter = oldList.begin();
152 // Append ranges that end before the new range.
153 for (; oldListIter != oldList.end() && oldListIter->x()+oldListIter->y() < newRange.x(); ++oldListIter)
154 newList.push_back(*oldListIter);
156 // Join any ranges that intersect new range
158 tcu::IVec2 curRange = newRange;
159 while (oldListIter != oldList.end() && rangesIntersect(curRange, *oldListIter))
161 curRange = unionRanges(curRange, *oldListIter);
165 newList.push_back(curRange);
168 // Append remaining ranges.
169 for (; oldListIter != oldList.end(); oldListIter++)
170 newList.push_back(*oldListIter);
172 DE_ASSERT(isRangeListValid(newList.begin(), newList.end()));
177 class BasicBufferDataCase : public BufferCase
180 BasicBufferDataCase (Context& context, const char* name, const char* desc, deUint32 target, deUint32 usage, int size, VerifyType verify)
181 : BufferCase (context, name, desc)
189 IterateResult iterate (void)
191 const deUint32 dataSeed = deStringHash(getName()) ^ 0x125;
192 BufferVerifier verifier (m_context, m_verify);
193 ReferenceBuffer refBuf;
196 refBuf.setSize(m_size);
197 fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed);
199 deUint32 buf = genBuffer();
200 glBindBuffer(m_target, buf);
201 glBufferData(m_target, m_size, refBuf.getPtr(), m_usage);
205 isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size);
209 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
210 isOk ? "Pass" : "Buffer verification failed");
221 class RecreateBufferDataStoreCase : public BufferCase
224 RecreateBufferDataStoreCase (Context& context, const char* name, const char* desc, const DataStoreSpec* specs, int numSpecs, VerifyType verify)
225 : BufferCase(context, name, desc)
226 , m_specs (specs, specs+numSpecs)
231 IterateResult iterate (void)
233 const deUint32 baseSeed = deStringHash(getName()) ^ 0xbeef;
234 BufferVerifier verifier (m_context, m_verify);
235 ReferenceBuffer refBuf;
236 const deUint32 buf = genBuffer();
238 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
240 for (vector<DataStoreSpec>::const_iterator spec = m_specs.begin(); spec != m_specs.end(); spec++)
244 refBuf.setSize(spec->size);
245 fillWithRandomBytes(refBuf.getPtr(), spec->size, baseSeed ^ deInt32Hash(spec->size+spec->target+spec->usage));
247 glBindBuffer(spec->target, buf);
248 glBufferData(spec->target, spec->size, refBuf.getPtr(), spec->usage);
252 iterOk = verifier.verify(buf, refBuf.getPtr(), 0, spec->size);
256 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
266 std::vector<DataStoreSpec> m_specs;
270 class BasicBufferSubDataCase : public BufferCase
273 BasicBufferSubDataCase (Context& context, const char* name, const char* desc, deUint32 target, deUint32 usage, int size, int subDataOffs, int subDataSize, VerifyType verify)
274 : BufferCase (context, name, desc)
278 , m_subDataOffs (subDataOffs)
279 , m_subDataSize (subDataSize)
282 DE_ASSERT(de::inBounds(subDataOffs, 0, size) && de::inRange(subDataOffs+subDataSize, 0, size));
285 IterateResult iterate (void)
287 const deUint32 dataSeed = deStringHash(getName());
288 BufferVerifier verifier (m_context, m_verify);
289 ReferenceBuffer refBuf;
292 refBuf.setSize(m_size);
294 deUint32 buf = genBuffer();
295 glBindBuffer(m_target, buf);
297 // Initialize with glBufferData()
298 fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed ^ 0x80354f);
299 glBufferData(m_target, m_size, refBuf.getPtr(), m_usage);
302 // Re-specify part of buffer
303 fillWithRandomBytes(refBuf.getPtr()+m_subDataOffs, m_subDataSize, dataSeed ^ 0xfac425c);
304 glBufferSubData(m_target, m_subDataOffs, m_subDataSize, refBuf.getPtr()+m_subDataOffs);
306 isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size);
310 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
311 isOk ? "Pass" : "Buffer verification failed");
324 class SubDataToUndefinedCase : public BufferCase
327 SubDataToUndefinedCase (Context& context, const char* name, const char* desc, deUint32 target, deUint32 usage, int size, const tcu::IVec2* ranges, int numRanges, VerifyType verify)
328 : BufferCase (context, name, desc)
332 , m_ranges (ranges, ranges+numRanges)
337 IterateResult iterate (void)
339 const deUint32 dataSeed = deStringHash(getName());
340 BufferVerifier verifier (m_context, m_verify);
341 ReferenceBuffer refBuf;
343 std::vector<tcu::IVec2> definedRanges;
345 refBuf.setSize(m_size);
347 deUint32 buf = genBuffer();
348 glBindBuffer(m_target, buf);
350 // Initialize storage with glBufferData()
351 glBufferData(m_target, m_size, DE_NULL, m_usage);
354 // Fill specified ranges with glBufferSubData()
355 for (vector<tcu::IVec2>::const_iterator range = m_ranges.begin(); range != m_ranges.end(); range++)
357 fillWithRandomBytes(refBuf.getPtr()+range->x(), range->y(), dataSeed ^ deInt32Hash(range->x()+range->y()));
358 glBufferSubData(m_target, range->x(), range->y(), refBuf.getPtr()+range->x());
360 // Mark range as defined
361 definedRanges = addRangeToList(definedRanges, *range);
364 // Verify defined parts
365 for (vector<tcu::IVec2>::const_iterator range = definedRanges.begin(); range != definedRanges.end(); range++)
367 if (!verifier.verify(buf, refBuf.getPtr(), range->x(), range->y()))
373 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
374 isOk ? "Pass" : "Buffer verification failed");
382 std::vector<tcu::IVec2> m_ranges;
386 class RandomBufferWriteCase : public BufferCase
389 RandomBufferWriteCase (Context& context, const char* name, const char* desc, deUint32 seed)
390 : BufferCase(context, name, desc)
392 , m_verifier (DE_NULL)
399 ~RandomBufferWriteCase (void)
409 m_buffer = genBuffer();
411 m_verifier = new BufferVerifier(m_context, VERIFY_AS_VERTEX_ARRAY);
413 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
418 deleteBuffer(m_buffer);
419 m_refBuffer.setSize(0);
422 m_verifier = DE_NULL;
424 BufferCase::deinit();
427 IterateResult iterate (void)
430 const int numIterations = 5;
431 const int uploadsPerIteration = 7;
432 const int minSize = 12;
433 const int maxSize = 32*1024;
434 const float respecifyProbability = 0.07f;
435 const float respecifyDataProbability = 0.2f;
437 static const deUint32 bufferTargets[] =
440 GL_ELEMENT_ARRAY_BUFFER
443 static const deUint32 usageHints[] =
451 deUint32 curBoundTarget = GL_NONE;
452 de::Random rnd (m_seed ^ deInt32Hash(m_iterNdx) ^ 0xacf92e);
454 m_testCtx.getLog() << TestLog::Section(string("Iteration") + de::toString(m_iterNdx+1), string("Iteration ") + de::toString(m_iterNdx+1) + " / " + de::toString(numIterations));
456 for (int uploadNdx = 0; uploadNdx < uploadsPerIteration; uploadNdx++)
458 const deUint32 target = bufferTargets[rnd.getInt(0, DE_LENGTH_OF_ARRAY(bufferTargets)-1)];
459 const bool respecify = m_curSize == 0 || rnd.getFloat() < respecifyProbability;
461 if (target != curBoundTarget)
463 glBindBuffer(target, m_buffer);
464 curBoundTarget = target;
469 const int size = rnd.getInt(minSize, maxSize);
470 const deUint32 hint = usageHints[rnd.getInt(0, DE_LENGTH_OF_ARRAY(usageHints)-1)];
471 const bool fillWithData = rnd.getFloat() < respecifyDataProbability;
473 m_refBuffer.setSize(size);
475 fillWithRandomBytes(m_refBuffer.getPtr(), size, rnd.getUint32());
477 glBufferData(target, size, fillWithData ? m_refBuffer.getPtr() : DE_NULL, hint);
479 m_validRanges.clear();
481 m_validRanges.push_back(tcu::IVec2(0, size));
487 // \note Non-uniform size distribution.
488 const int size = de::clamp(deRoundFloatToInt32((float)m_curSize * deFloatPow(rnd.getFloat(0.0f, 0.7f), 3.0f)), minSize, m_curSize);
489 const int offset = rnd.getInt(0, m_curSize-size);
491 fillWithRandomBytes(m_refBuffer.getPtr()+offset, size, rnd.getUint32());
492 glBufferSubData(target, offset, size, m_refBuffer.getPtr()+offset);
494 m_validRanges = addRangeToList(m_validRanges, tcu::IVec2(offset, size));
500 deUint32 err = glGetError();
501 if (err != GL_NO_ERROR)
502 throw tcu::TestError(string("Got ") + glu::getErrorStr(err).toString());
505 // Verify valid ranges.
506 for (vector<IVec2>::const_iterator range = m_validRanges.begin(); range != m_validRanges.end(); range++)
508 if (!m_verifier->verify(m_buffer, m_refBuffer.getPtr(), range->x(), range->y()))
510 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer verification failed");
516 m_testCtx.getLog() << TestLog::EndSection;
518 DE_ASSERT(iterOk || m_testCtx.getTestResult() != QP_TEST_RESULT_PASS);
521 return (iterOk && m_iterNdx < numIterations) ? CONTINUE : STOP;
527 BufferVerifier* m_verifier;
529 ReferenceBuffer m_refBuffer;
530 std::vector<tcu::IVec2> m_validRanges;
535 BufferWriteTests::BufferWriteTests (Context& context)
536 : TestCaseGroup(context, "write", "Buffer data upload tests")
540 BufferWriteTests::~BufferWriteTests (void)
544 void BufferWriteTests::init (void)
546 static const deUint32 bufferTargets[] =
549 GL_ELEMENT_ARRAY_BUFFER
552 static const deUint32 usageHints[] =
565 { "vertex_array", VERIFY_AS_VERTEX_ARRAY },
566 { "index_array", VERIFY_AS_INDEX_ARRAY }
571 tcu::TestCaseGroup* const basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic upload with glBufferData()");
572 addChild(basicGroup);
574 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
576 for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageHints); usageNdx++)
578 const deUint32 target = bufferTargets[targetNdx];
579 const deUint32 usage = usageHints[usageNdx];
580 const int size = 1020;
581 const VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
582 const string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(usage);
584 basicGroup->addChild(new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
591 tcu::TestCaseGroup* const useGroup = new tcu::TestCaseGroup(m_testCtx, "use", "Buffer uses");
594 for (int verifyNdx = 0; verifyNdx < DE_LENGTH_OF_ARRAY(verifyTypes); verifyNdx++)
596 tcu::TestCaseGroup* const verifyGroup = new tcu::TestCaseGroup(m_testCtx, verifyTypes[verifyNdx].name, "");
597 useGroup->addChild(verifyGroup);
599 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
601 const deUint32 target = bufferTargets[targetNdx];
602 const deUint32 usage = GL_STATIC_DRAW;
603 const int size = 763;
604 const VerifyType verify = verifyTypes[verifyNdx].verify;
605 const string name = getBufferTargetName(target);
607 verifyGroup->addChild(new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
614 tcu::TestCaseGroup* const recreateStoreGroup = new tcu::TestCaseGroup(m_testCtx, "recreate_store", "Data store recreate using glBufferData()");
615 addChild(recreateStoreGroup);
617 #define RECREATE_STORE_CASE(NAME, DESC, SPECLIST) \
619 std::vector<DataStoreSpec> specs; \
620 DataStoreSpecVecBuilder builder(specs); \
622 recreateStoreGroup->addChild(new RecreateBufferDataStoreCase(m_context, #NAME, DESC, &specs[0], (int)specs.size(), VERIFY_AS_VERTEX_ARRAY)); \
623 } while (deGetFalse())
625 RECREATE_STORE_CASE(identical_1, "Recreate with identical parameters",
626 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996)
627 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996)
628 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996));
630 RECREATE_STORE_CASE(identical_2, "Recreate with identical parameters",
631 << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 72)
632 << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 72)
633 << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 72));
635 RECREATE_STORE_CASE(different_target_1, "Recreate with different target",
636 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 504)
637 << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 504));
639 RECREATE_STORE_CASE(different_target_2, "Recreate with different target",
640 << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 716)
641 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 716)
642 << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 716));
644 RECREATE_STORE_CASE(different_usage, "Recreate with different usage",
645 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1644)
646 << DataStoreSpec(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, 1644)
647 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 1644)
648 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1644));
650 RECREATE_STORE_CASE(different_size, "Recreate with different size",
651 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1024)
652 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 12)
653 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 3327)
654 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 92)
655 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 12379)
656 << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 571));
658 #undef RECREATE_STORE_CASE
662 const int numRandomCases = 4;
663 const int numUploadsPerCase = 10;
664 const int minSize = 12;
665 const int maxSize = 65536;
666 const VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
667 de::Random rnd (23921);
669 for (int caseNdx = 0; caseNdx < numRandomCases; caseNdx++)
671 vector<DataStoreSpec> specs(numUploadsPerCase);
673 for (vector<DataStoreSpec>::iterator spec = specs.begin(); spec != specs.end(); spec++)
675 spec->target = bufferTargets[rnd.getInt(0, DE_LENGTH_OF_ARRAY(bufferTargets)-1)];
676 spec->usage = usageHints[rnd.getInt(0, DE_LENGTH_OF_ARRAY(usageHints)-1)];
677 spec->size = rnd.getInt(minSize, maxSize);
680 recreateStoreGroup->addChild(new RecreateBufferDataStoreCase(m_context, (string("random_") + de::toString(caseNdx+1)).c_str(), "", &specs[0], (int)specs.size(), verify));
687 tcu::TestCaseGroup* const basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic_subdata", "Basic glBufferSubData() usage");
688 addChild(basicGroup);
690 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
692 for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageHints); usageNdx++)
694 const deUint32 target = bufferTargets[targetNdx];
695 const deUint32 usage = usageHints[usageNdx];
696 const int size = 1020;
697 const VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
698 const string name = string(getBufferTargetName(target)) + "_" + getUsageHintName(usage);
700 basicGroup->addChild(new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
707 tcu::TestCaseGroup* const partialSpecifyGroup = new tcu::TestCaseGroup(m_testCtx, "partial_specify", "Partial buffer data specification with glBufferSubData()");
708 addChild(partialSpecifyGroup);
710 #define PARTIAL_SPECIFY_CASE(NAME, DESC, TARGET, USAGE, SIZE, RANGELIST) \
712 std::vector<tcu::IVec2> ranges; \
713 RangeVecBuilder builder(ranges); \
715 partialSpecifyGroup->addChild(new SubDataToUndefinedCase(m_context, #NAME, DESC, TARGET, USAGE, SIZE, &ranges[0], (int)ranges.size(), VERIFY_AS_VERTEX_ARRAY)); \
716 } while (deGetFalse())
718 PARTIAL_SPECIFY_CASE(whole_1, "Whole buffer specification with single glBufferSubData()", GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996,
720 PARTIAL_SPECIFY_CASE(whole_2, "Whole buffer specification with two calls", GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW, 1728,
723 PARTIAL_SPECIFY_CASE(whole_3, "Whole buffer specification with three calls", GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1944,
726 << IVec2(421, 1000));
727 PARTIAL_SPECIFY_CASE(whole_4, "Whole buffer specification with three calls", GL_ELEMENT_ARRAY_BUFFER, GL_STREAM_DRAW, 1200,
732 PARTIAL_SPECIFY_CASE(low_1, "Low part of buffer specified with single call", GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 1000,
734 PARTIAL_SPECIFY_CASE(low_2, "Low part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996,
737 PARTIAL_SPECIFY_CASE(low_3, "Low part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, 1200,
741 PARTIAL_SPECIFY_CASE(high_1, "High part of buffer specified with single call", GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 1000,
743 PARTIAL_SPECIFY_CASE(high_2, "High part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1200,
746 PARTIAL_SPECIFY_CASE(high_3, "High part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1200,
750 PARTIAL_SPECIFY_CASE(middle_1, "Middle part of buffer specified with single call", GL_ELEMENT_ARRAY_BUFFER, GL_STREAM_DRAW, 2500,
751 << IVec2(1000, 799));
752 PARTIAL_SPECIFY_CASE(middle_2, "Middle part of buffer specified with two calls", GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 2500,
754 << IVec2(1000, 500));
755 PARTIAL_SPECIFY_CASE(middle_3, "Middle part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, 2500,
757 << IVec2(1000, 501));
759 #undef PARTIAL_SPECIFY_CASE
764 tcu::TestCaseGroup* const randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Randomized buffer data cases");
765 addChild(randomGroup);
767 for (int i = 0; i < 10; i++)
768 randomGroup->addChild(new RandomBufferWriteCase(m_context, de::toString(i).c_str(), "", deInt32Hash(i)));