dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / memory / vktMemoryAllocationTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and/or associated documentation files (the
9  * "Materials"), to deal in the Materials without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Materials, and to
12  * permit persons to whom the Materials are furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice(s) and this permission notice shall be
16  * included in all copies or substantial portions of the Materials.
17  *
18  * The Materials are Confidential Information as defined by the
19  * Khronos Membership Agreement until designated non-confidential by
20  * Khronos, at which point this condition clause shall be removed.
21  *
22  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
29  *
30  *//*!
31  * \file
32  * \brief Simple memory allocation tests.
33  *//*--------------------------------------------------------------------*/
34
35 #include "vktMemoryAllocationTests.hpp"
36
37 #include "vktTestCaseUtil.hpp"
38
39 #include "tcuMaybe.hpp"
40 #include "tcuResultCollector.hpp"
41 #include "tcuTestLog.hpp"
42
43 #include "vkPlatform.hpp"
44 #include "vkStrUtil.hpp"
45 #include "vkRef.hpp"
46 #include "vkDeviceUtil.hpp"
47 #include "vkQueryUtil.hpp"
48
49 #include "deUniquePtr.hpp"
50 #include "deStringUtil.hpp"
51 #include "deRandom.hpp"
52
53 using tcu::Maybe;
54 using tcu::TestLog;
55
56 using std::string;
57 using std::vector;
58
59 using namespace vk;
60
61 namespace vkt
62 {
63 namespace memory
64 {
65 namespace
66 {
67
68 struct TestConfig
69 {
70         enum Order
71         {
72                 ALLOC_FREE,
73                 ALLOC_REVERSE_FREE,
74                 MIXED_ALLOC_FREE,
75                 ORDER_LAST
76         };
77
78         Maybe<VkDeviceSize>     memorySize;
79         Maybe<float>            memoryPercentage;
80         deUint32                        memoryAllocationCount;
81         Order                           order;
82
83         TestConfig (void)
84                 : memoryAllocationCount ((deUint32)-1)
85                 , order                                 (ORDER_LAST)
86         {
87         }
88 };
89
90 class AllocateFreeTestInstance : public TestInstance
91 {
92 public:
93                                                 AllocateFreeTestInstance                (Context& context, const TestConfig config)
94                 : TestInstance                  (context)
95                 , m_config                              (config)
96                 , m_result                              (m_context.getTestContext().getLog())
97                 , m_memoryTypeIndex             (0)
98                 , m_memoryProperties    (getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()))
99         {
100                 DE_ASSERT(!!m_config.memorySize != !!m_config.memoryPercentage);
101         }
102
103         tcu::TestStatus         iterate                                                 (void);
104
105 private:
106         const TestConfig                                                m_config;
107         tcu::ResultCollector                                    m_result;
108         deUint32                                                                m_memoryTypeIndex;
109         const VkPhysicalDeviceMemoryProperties  m_memoryProperties;
110 };
111
112 tcu::TestStatus AllocateFreeTestInstance::iterate (void)
113 {
114         TestLog&                                                                log                                     = m_context.getTestContext().getLog();
115         const VkDevice                                                  device                          = m_context.getDevice();
116         const DeviceInterface&                                  vkd                                     = m_context.getDeviceInterface();
117
118         if (m_memoryTypeIndex == 0)
119         {
120                 log << TestLog::Message << "Memory allocation count: " << m_config.memoryAllocationCount << TestLog::EndMessage;
121                 log << TestLog::Message << "Single allocation size: " << (m_config.memorySize ? de::toString(*m_config.memorySize) : de::toString(100.0f * (*m_config.memoryPercentage)) + " of heap size.D") << TestLog::EndMessage;
122
123                 if (m_config.order == TestConfig::ALLOC_REVERSE_FREE)
124                         log << TestLog::Message << "Memory is freed in reversed order. " << TestLog::EndMessage;
125                 else if (m_config.order == TestConfig::ALLOC_FREE)
126                         log << TestLog::Message << "Memory is freed in same order as allocated. " << TestLog::EndMessage;
127                 else if (m_config.order == TestConfig::MIXED_ALLOC_FREE)
128                         log << TestLog::Message << "Memory is freed right after allocation. " << TestLog::EndMessage;
129                 else
130                         DE_FATAL("Unknown allocation order");
131         }
132
133         try
134         {
135                 const VkMemoryType              memoryType              = m_memoryProperties.memoryTypes[m_memoryTypeIndex];
136                 const VkMemoryHeap              memoryHeap              = m_memoryProperties.memoryHeaps[memoryType.heapIndex];
137
138                 const VkDeviceSize              allocationSize  = (m_config.memorySize ? *m_config.memorySize : (VkDeviceSize)(*m_config.memoryPercentage * (float)memoryHeap.size));
139                 vector<VkDeviceMemory>  memoryObjects   (m_config.memoryAllocationCount, (VkDeviceMemory)0);
140
141                 log << TestLog::Message << "Memory type index: " << m_memoryTypeIndex << TestLog::EndMessage;
142
143                 if (memoryType.heapIndex >= m_memoryProperties.memoryHeapCount)
144                         m_result.fail("Invalid heap index defined for memory type.");
145
146                 {
147                         log << TestLog::Message << "Memory type: " << memoryType << TestLog::EndMessage;
148                         log << TestLog::Message << "Memory heap: " << memoryHeap << TestLog::EndMessage;
149
150                         if (allocationSize * m_config.memoryAllocationCount * 8 > memoryHeap.size)
151                                 TCU_THROW(NotSupportedError, "Memory heap doesn't have enough memory.");
152
153                         try
154                         {
155                                 if (m_config.order == TestConfig::ALLOC_FREE || m_config.order == TestConfig::ALLOC_REVERSE_FREE)
156                                 {
157                                         for (size_t ndx = 0; ndx < m_config.memoryAllocationCount; ndx++)
158                                         {
159                                                 const VkMemoryAllocateInfo alloc =
160                                                 {
161                                                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
162                                                         DE_NULL,                                                                // pNext
163                                                         allocationSize,                                                 // allocationSize
164                                                         m_memoryTypeIndex                                               // memoryTypeIndex;
165                                                 };
166
167                                                 VK_CHECK(vkd.allocateMemory(device, &alloc, (const VkAllocationCallbacks*)DE_NULL, &memoryObjects[ndx]));
168
169                                                 TCU_CHECK(!!memoryObjects[ndx]);
170                                         }
171
172                                         if (m_config.order == TestConfig::ALLOC_FREE)
173                                         {
174                                                 for (size_t ndx = 0; ndx < m_config.memoryAllocationCount; ndx++)
175                                                 {
176                                                         const VkDeviceMemory mem = memoryObjects[memoryObjects.size() - 1 - ndx];
177
178                                                         vkd.freeMemory(device, mem, (const VkAllocationCallbacks*)DE_NULL);
179                                                         memoryObjects[memoryObjects.size() - 1 - ndx] = (VkDeviceMemory)0;
180                                                 }
181                                         }
182                                         else
183                                         {
184                                                 for (size_t ndx = 0; ndx < m_config.memoryAllocationCount; ndx++)
185                                                 {
186                                                         const VkDeviceMemory mem = memoryObjects[ndx];
187
188                                                         vkd.freeMemory(device, mem, (const VkAllocationCallbacks*)DE_NULL);
189                                                         memoryObjects[ndx] = (VkDeviceMemory)0;
190                                                 }
191                                         }
192                                 }
193                                 else
194                                 {
195                                         for (size_t ndx = 0; ndx < m_config.memoryAllocationCount; ndx++)
196                                         {
197                                                 const VkMemoryAllocateInfo alloc =
198                                                 {
199                                                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
200                                                         DE_NULL,                                                                // pNext
201                                                         allocationSize,                                                 // allocationSize
202                                                         m_memoryTypeIndex                                               // memoryTypeIndex;
203                                                 };
204
205                                                 VK_CHECK(vkd.allocateMemory(device, &alloc, (const VkAllocationCallbacks*)DE_NULL, &memoryObjects[ndx]));
206                                                 TCU_CHECK(!!memoryObjects[ndx]);
207
208                                                 vkd.freeMemory(device, memoryObjects[ndx], (const VkAllocationCallbacks*)DE_NULL);
209                                                 memoryObjects[ndx] = (VkDeviceMemory)0;
210                                         }
211                                 }
212                         }
213                         catch (...)
214                         {
215                                 for (size_t ndx = 0; ndx < m_config.memoryAllocationCount; ndx++)
216                                 {
217                                         const VkDeviceMemory mem = memoryObjects[ndx];
218
219                                         if (!!mem)
220                                         {
221                                                 vkd.freeMemory(device, mem, (const VkAllocationCallbacks*)DE_NULL);
222                                                 memoryObjects[ndx] = (VkDeviceMemory)0;
223                                         }
224                                 }
225
226                                 throw;
227                         }
228                 }
229         }
230         catch (const tcu::TestError& error)
231         {
232                 m_result.fail(error.getMessage());
233         }
234
235         m_memoryTypeIndex++;
236
237         if (m_memoryTypeIndex < m_memoryProperties.memoryTypeCount)
238                 return tcu::TestStatus::incomplete();
239         else
240                 return tcu::TestStatus(m_result.getResult(), m_result.getMessage());
241 }
242
243 struct MemoryType
244 {
245         deUint32                index;
246         VkMemoryType    type;
247 };
248
249 struct MemoryObject
250 {
251         VkDeviceMemory  memory;
252         VkDeviceSize    size;
253 };
254
255 struct Heap
256 {
257         VkMemoryHeap                    heap;
258         VkDeviceSize                    memoryUsage;
259         VkDeviceSize                    maxMemoryUsage;
260         vector<MemoryType>              types;
261         vector<MemoryObject>    objects;
262 };
263
264 class RandomAllocFreeTestInstance : public TestInstance
265 {
266 public:
267                                                 RandomAllocFreeTestInstance             (Context& context, deUint32 seed);
268                                                 ~RandomAllocFreeTestInstance    (void);
269
270         tcu::TestStatus         iterate                                                 (void);
271
272 private:
273         const size_t            m_opCount;
274         size_t                          m_opNdx;
275         de::Random                      m_rng;
276         vector<Heap>            m_heaps;
277         vector<size_t>          m_nonFullHeaps;
278         vector<size_t>          m_nonEmptyHeaps;
279 };
280
281 RandomAllocFreeTestInstance::RandomAllocFreeTestInstance        (Context& context, deUint32 seed)
282         : TestInstance  (context)
283         , m_opCount             (128)
284         , m_opNdx               (0)
285         , m_rng                 (seed)
286 {
287         const VkPhysicalDevice                                  physicalDevice          = context.getPhysicalDevice();
288         const InstanceInterface&                                vki                                     = context.getInstanceInterface();
289         const VkPhysicalDeviceMemoryProperties  memoryProperties        = getPhysicalDeviceMemoryProperties(vki, physicalDevice);
290
291         TCU_CHECK(memoryProperties.memoryHeapCount <= 32);
292         TCU_CHECK(memoryProperties.memoryTypeCount <= 32);
293
294         m_heaps.resize(memoryProperties.memoryHeapCount);
295
296         m_nonFullHeaps.reserve(m_heaps.size());
297         m_nonEmptyHeaps.reserve(m_heaps.size());
298
299         for (deUint32 heapNdx = 0; heapNdx < memoryProperties.memoryHeapCount; heapNdx++)
300         {
301                 m_heaps[heapNdx].heap                   = memoryProperties.memoryHeaps[heapNdx];
302                 m_heaps[heapNdx].memoryUsage    = 0;
303                 m_heaps[heapNdx].maxMemoryUsage = m_heaps[heapNdx].heap.size / 8;
304
305                 m_heaps[heapNdx].objects.reserve(100);
306
307                 m_nonFullHeaps.push_back((size_t)heapNdx);
308         }
309
310         for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < memoryProperties.memoryTypeCount; memoryTypeNdx++)
311         {
312                 const MemoryType type =
313                 {
314                         memoryTypeNdx,
315                         memoryProperties.memoryTypes[memoryTypeNdx]
316                 };
317
318                 TCU_CHECK(type.type.heapIndex < memoryProperties.memoryHeapCount);
319
320                 m_heaps[type.type.heapIndex].types.push_back(type);
321         }
322 }
323
324 RandomAllocFreeTestInstance::~RandomAllocFreeTestInstance (void)
325 {
326         const VkDevice                                                  device                          = m_context.getDevice();
327         const DeviceInterface&                                  vkd                                     = m_context.getDeviceInterface();
328
329         for (deUint32 heapNdx = 0; heapNdx < (deUint32)m_heaps.size(); heapNdx++)
330         {
331                 const Heap&     heap    = m_heaps[heapNdx];
332
333                 for (size_t objectNdx = 0; objectNdx < heap.objects.size(); objectNdx++)
334                 {
335                         if (!!heap.objects[objectNdx].memory)
336                                 vkd.freeMemory(device, heap.objects[objectNdx].memory, (const VkAllocationCallbacks*)DE_NULL);
337                 }
338         }
339 }
340
341 tcu::TestStatus RandomAllocFreeTestInstance::iterate (void)
342 {
343         const VkDevice                  device                  = m_context.getDevice();
344         const DeviceInterface&  vkd                             = m_context.getDeviceInterface();
345         TestLog&                                log                             = m_context.getTestContext().getLog();
346         bool                                    allocateMore;
347
348         if (m_opNdx == 0)
349         {
350                 log << TestLog::Message << "Performing " << m_opCount << " random VkAllocMemory() / VkFreeMemory() calls before freeing all memory." << TestLog::EndMessage;
351                 log << TestLog::Message << "Using max 1/8 of the memory in each memory heap." << TestLog::EndMessage;
352         }
353
354         if (m_opNdx >= m_opCount)
355         {
356                 if (m_nonEmptyHeaps.empty())
357                         return tcu::TestStatus::pass("Pass");
358                 else
359                         allocateMore = false;
360         }
361         else if (!m_nonEmptyHeaps.empty() && !m_nonFullHeaps.empty())
362                 allocateMore = m_rng.getBool(); // Randomize if both operations are doable.
363         else if (m_nonEmptyHeaps.empty())
364                 allocateMore = true; // Allocate more if there are no objects to free.
365         else if (m_nonFullHeaps.empty())
366                 allocateMore = false; // Free objects if there is no free space for new objects.
367         else
368         {
369                 allocateMore = false;
370                 DE_FATAL("Fail");
371         }
372
373         if (allocateMore)
374         {
375                 const size_t            nonFullHeapNdx  = (size_t)(m_rng.getUint32() % (deUint32)m_nonFullHeaps.size());
376                 const size_t            heapNdx                 = m_nonFullHeaps[nonFullHeapNdx];
377                 Heap&                           heap                    = m_heaps[heapNdx];
378                 const MemoryType&       memoryType              = m_rng.choose<MemoryType>(heap.types.begin(), heap.types.end());
379                 const VkDeviceSize      allocationSize  = 1 + (m_rng.getUint64() % (deUint64)(heap.maxMemoryUsage - heap.memoryUsage));
380
381                 const MemoryObject object =
382                 {
383                         (VkDeviceMemory)0,
384                         allocationSize
385                 };
386
387                 heap.objects.push_back(object);
388
389                 const VkMemoryAllocateInfo alloc =
390                 {
391                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
392                         DE_NULL,                                                                // pNext
393                         object.size,                                                    // allocationSize
394                         memoryType.index                                                // memoryTypeIndex;
395                 };
396
397                 VK_CHECK(vkd.allocateMemory(device, &alloc, (const VkAllocationCallbacks*)DE_NULL, &heap.objects.back().memory));
398                 TCU_CHECK(!!heap.objects.back().memory);
399
400                 // If heap was empty add to the non empty heaps.
401                 if (heap.memoryUsage == 0)
402                 {
403                         DE_ASSERT(heap.objects.size() == 1);
404                         m_nonEmptyHeaps.push_back(heapNdx);
405                 }
406                 else
407                         DE_ASSERT(heap.objects.size() > 1);
408
409                 heap.memoryUsage += allocationSize;
410
411                 // If heap became full, remove from non full heaps.
412                 if (heap.memoryUsage >= heap.maxMemoryUsage)
413                 {
414                         m_nonFullHeaps[nonFullHeapNdx] = m_nonFullHeaps.back();
415                         m_nonFullHeaps.pop_back();
416                 }
417         }
418         else
419         {
420                 const size_t            nonEmptyHeapNdx = (size_t)(m_rng.getUint32() % (deUint32)m_nonEmptyHeaps.size());
421                 const size_t            heapNdx                 = m_nonEmptyHeaps[nonEmptyHeapNdx];
422                 Heap&                           heap                    = m_heaps[heapNdx];
423                 const size_t            memoryObjectNdx = m_rng.getUint32() % heap.objects.size();
424                 MemoryObject&           memoryObject    = heap.objects[memoryObjectNdx];
425
426                 vkd.freeMemory(device, memoryObject.memory, (const VkAllocationCallbacks*)DE_NULL);
427                 memoryObject.memory = (VkDeviceMemory)0;
428
429                 if (heap.memoryUsage >= heap.maxMemoryUsage && heap.memoryUsage - memoryObject.size < heap.maxMemoryUsage)
430                         m_nonFullHeaps.push_back(heapNdx);
431
432                 heap.memoryUsage -= memoryObject.size;
433
434                 heap.objects[memoryObjectNdx] = heap.objects.back();
435                 heap.objects.pop_back();
436
437                 if (heap.memoryUsage == 0)
438                 {
439                         DE_ASSERT(heap.objects.empty());
440
441                         m_nonEmptyHeaps[nonEmptyHeapNdx] = m_nonEmptyHeaps.back();
442                         m_nonEmptyHeaps.pop_back();
443                 }
444                 else
445                         DE_ASSERT(!heap.objects.empty());
446         }
447
448         m_opNdx++;
449         return tcu::TestStatus::incomplete();
450 }
451
452
453 } // anonymous
454
455 tcu::TestCaseGroup* createAllocationTests (tcu::TestContext& testCtx)
456 {
457         de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "allocation", "Memory allocation tests."));
458
459         const VkDeviceSize      KiB     = 1024;
460         const VkDeviceSize      MiB     = 1024 * KiB;
461
462         const struct
463         {
464                 const char* const       str;
465                 VkDeviceSize            size;
466         } allocationSizes[] =
467         {
468                 {   "64", 64 },
469                 {  "128", 128 },
470                 {  "256", 256 },
471                 {  "512", 512 },
472                 { "1KiB", 1*KiB },
473                 { "4KiB", 4*KiB },
474                 { "8KiB", 8*KiB },
475                 { "1MiB", 1*MiB }
476         };
477
478         const float allocationPercents[] =
479         {
480                 0.01f
481         };
482
483         const int allocationCounts[] =
484         {
485                 1, 10, 100, 1000, -1
486         };
487
488         const struct
489         {
490                 const char* const               str;
491                 const TestConfig::Order order;
492         } orders[] =
493         {
494                 { "forward",    TestConfig::ALLOC_FREE },
495                 { "reverse",    TestConfig::ALLOC_REVERSE_FREE },
496                 { "mixed",              TestConfig::MIXED_ALLOC_FREE }
497         };
498
499         {
500                 de::MovePtr<tcu::TestCaseGroup> basicGroup      (new tcu::TestCaseGroup(testCtx, "basic", "Basic memory allocation and free tests"));
501
502                 for (size_t allocationSizeNdx = 0; allocationSizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); allocationSizeNdx++)
503                 {
504                         const VkDeviceSize                              allocationSize          = allocationSizes[allocationSizeNdx].size;
505                         const char* const                               allocationSizeName      = allocationSizes[allocationSizeNdx].str;
506                         de::MovePtr<tcu::TestCaseGroup> sizeGroup                       (new tcu::TestCaseGroup(testCtx, ("size_" + string(allocationSizeName)).c_str(), ("Test different allocation sizes " + de::toString(allocationSize)).c_str()));
507
508                         for (size_t orderNdx = 0; orderNdx < DE_LENGTH_OF_ARRAY(orders); orderNdx++)
509                         {
510                                 const TestConfig::Order                 order                           = orders[orderNdx].order;
511                                 const char* const                               orderName                       = orders[orderNdx].str;
512                                 const char* const                               orderDescription        = orderName;
513                                 de::MovePtr<tcu::TestCaseGroup> orderGroup                      (new tcu::TestCaseGroup(testCtx, orderName, orderDescription));
514
515                                 for (size_t allocationCountNdx = 0; allocationCountNdx < DE_LENGTH_OF_ARRAY(allocationCounts); allocationCountNdx++)
516                                 {
517                                         const int allocationCount = allocationCounts[allocationCountNdx];
518
519                                         if (allocationCount != -1 && allocationCount * allocationSize > 50 * MiB)
520                                                 continue;
521
522                                         TestConfig config;
523
524                                         config.memorySize                               = allocationSize;
525                                         config.order                                    = order;
526
527                                         if (allocationCount == -1)
528                                         {
529                                                 if (allocationSize < 4096)
530                                                         continue;
531
532                                                 config.memoryAllocationCount    = (deUint32)(50 * MiB / allocationSize);
533
534                                                 if (config.memoryAllocationCount == 0
535                                                         || config.memoryAllocationCount == 1
536                                                         || config.memoryAllocationCount == 10
537                                                         || config.memoryAllocationCount == 100
538                                                         || config.memoryAllocationCount == 1000)
539                                                 continue;
540                                         }
541                                         else
542                                                 config.memoryAllocationCount    = allocationCount;
543
544                                         orderGroup->addChild(new InstanceFactory1<AllocateFreeTestInstance, TestConfig>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "count_" + de::toString(config.memoryAllocationCount), "", config));
545                                 }
546
547                                 sizeGroup->addChild(orderGroup.release());
548                         }
549
550                         basicGroup->addChild(sizeGroup.release());
551                 }
552
553                 for (size_t allocationPercentNdx = 0; allocationPercentNdx < DE_LENGTH_OF_ARRAY(allocationPercents); allocationPercentNdx++)
554                 {
555                         const float                                             allocationPercent       = allocationPercents[allocationPercentNdx];
556                         de::MovePtr<tcu::TestCaseGroup> percentGroup            (new tcu::TestCaseGroup(testCtx, ("percent_" + de::toString((int)(100.0f * allocationPercent))).c_str(), ("Test different allocation percents " + de::toString(allocationPercent * 100.0f)).c_str()));
557
558                         for (size_t orderNdx = 0; orderNdx < DE_LENGTH_OF_ARRAY(orders); orderNdx++)
559                         {
560                                 const TestConfig::Order                 order                           = orders[orderNdx].order;
561                                 const char* const                               orderName                       = orders[orderNdx].str;
562                                 const char* const                               orderDescription        = orderName;
563                                 de::MovePtr<tcu::TestCaseGroup> orderGroup                      (new tcu::TestCaseGroup(testCtx, orderName, orderDescription));
564
565                                 for (size_t allocationCountNdx = 0; allocationCountNdx < DE_LENGTH_OF_ARRAY(allocationCounts); allocationCountNdx++)
566                                 {
567                                         const int allocationCount = allocationCounts[allocationCountNdx];
568
569                                         if ((allocationCount != -1) && ((float)allocationCount * allocationPercent >= 1.00f / 8.00f))
570                                                 continue;
571
572                                         TestConfig config;
573
574                                         config.memoryPercentage                 = allocationPercent;
575                                         config.order                                    = order;
576
577                                         if (allocationCount == -1)
578                                         {
579                                                 config.memoryAllocationCount    = (int)((1.00f / 8.00f) / allocationPercent);
580
581                                                 if (config.memoryAllocationCount == 0
582                                                         || config.memoryAllocationCount == 1
583                                                         || config.memoryAllocationCount == 10
584                                                         || config.memoryAllocationCount == 100
585                                                         || config.memoryAllocationCount == 1000)
586                                                 continue;
587                                         }
588                                         else
589                                                 config.memoryAllocationCount    = allocationCount;
590
591                                         orderGroup->addChild(new InstanceFactory1<AllocateFreeTestInstance, TestConfig>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "count_" + de::toString(config.memoryAllocationCount), "", config));
592                                 }
593
594                                 percentGroup->addChild(orderGroup.release());
595                         }
596
597                         basicGroup->addChild(percentGroup.release());
598                 }
599
600                 group->addChild(basicGroup.release());
601         }
602
603         {
604                 const deUint32                                  caseCount       = 100;
605                 de::MovePtr<tcu::TestCaseGroup> randomGroup     (new tcu::TestCaseGroup(testCtx, "random", "Random memory allocation tests."));
606
607                 for (deUint32 caseNdx = 0; caseNdx < caseCount; caseNdx++)
608                 {
609                         const deUint32 seed = deInt32Hash(caseNdx ^ 32480);
610
611                         randomGroup->addChild(new InstanceFactory1<RandomAllocFreeTestInstance, deUint32>(testCtx, tcu::NODETYPE_SELF_VALIDATE, de::toString(caseNdx), "Random case", seed));
612                 }
613
614                 group->addChild(randomGroup.release());
615         }
616
617         return group.release();
618 }
619
620 } // memory
621 } // vkt