xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *//*!
20  * \file
21  * \brief Descriptor pool tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktApiDescriptorPoolTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 
27 #include "vkDefs.hpp"
28 #include "vkRef.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 
34 #include "tcuCommandLine.hpp"
35 #include "tcuTestLog.hpp"
36 #include "tcuPlatform.hpp"
37 
38 #include "deUniquePtr.hpp"
39 #include "deSharedPtr.hpp"
40 #include "deInt32.h"
41 #include "deSTLUtil.hpp"
42 
43 #ifdef CTS_USES_VULKANSC
44 #include "vkSafetyCriticalUtil.hpp"
45 #include "vktCustomInstancesDevices.hpp"
46 #endif
47 
48 #define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1)
49 
50 namespace vkt
51 {
52 namespace api
53 {
54 
55 namespace
56 {
57 
58 using namespace std;
59 using namespace vk;
60 
61 struct ResetDescriptorPoolTestParams
62 {
ResetDescriptorPoolTestParamsvkt::api::__anonf50597990111::ResetDescriptorPoolTestParams63     ResetDescriptorPoolTestParams(uint32_t numIterations, bool freeDescriptorSets = false)
64         : m_numIterations(numIterations)
65         , m_freeDescriptorSets(freeDescriptorSets)
66     {
67     }
68 
69     uint32_t m_numIterations;
70     bool m_freeDescriptorSets;
71 };
72 
checkSupportFreeDescriptorSets(Context & context,const ResetDescriptorPoolTestParams params)73 void checkSupportFreeDescriptorSets(Context &context, const ResetDescriptorPoolTestParams params)
74 {
75 #ifdef CTS_USES_VULKANSC
76     if (params.m_freeDescriptorSets && context.getDeviceVulkanSC10Properties().recycleDescriptorSetMemory == VK_FALSE)
77         TCU_THROW(NotSupportedError, "vkFreeDescriptorSets not supported");
78 #else
79     DE_UNREF(context);
80     DE_UNREF(params);
81 #endif // CTS_USES_VULKANSC
82 }
83 
resetDescriptorPoolTest(Context & context,const ResetDescriptorPoolTestParams params)84 tcu::TestStatus resetDescriptorPoolTest(Context &context, const ResetDescriptorPoolTestParams params)
85 {
86 #ifndef CTS_USES_VULKANSC
87     const uint32_t numDescriptorSetsPerIter = 2048;
88 #else
89     const uint32_t numDescriptorSetsPerIter = 100;
90 #endif // CTS_USES_VULKANSC
91     const DeviceInterface &vkd = context.getDeviceInterface();
92     const VkDevice device      = context.getDevice();
93 
94     const VkDescriptorPoolSize descriptorPoolSize = {
95         VK_DESCRIPTOR_TYPE_SAMPLER, // type
96         numDescriptorSetsPerIter    // descriptorCount
97     };
98 
99     const VkDescriptorPoolCreateInfo descriptorPoolInfo = {
100         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
101         NULL,                                          // pNext
102         (params.m_freeDescriptorSets) ? (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT :
103                                         0u, // flags
104         numDescriptorSetsPerIter,           // maxSets
105         1,                                  // poolSizeCount
106         &descriptorPoolSize                 // pPoolSizes
107     };
108 
109     {
110         const Unique<VkDescriptorPool> descriptorPool(createDescriptorPool(vkd, device, &descriptorPoolInfo));
111 
112         const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
113             0,                          // binding
114             VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType
115             1,                          // descriptorCount
116             VK_SHADER_STAGE_ALL,        // stageFlags
117             NULL                        // pImmutableSamplers
118         };
119 
120         const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo = {
121             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
122             NULL,                                                // pNext
123             0,                                                   // flags
124             1,                                                   // bindingCount
125             &descriptorSetLayoutBinding                          // pBindings
126         };
127 
128         {
129             typedef de::SharedPtr<Unique<VkDescriptorSetLayout>> DescriptorSetLayoutPtr;
130 
131             vector<DescriptorSetLayoutPtr> descriptorSetLayouts;
132             descriptorSetLayouts.reserve(numDescriptorSetsPerIter);
133 
134             for (uint32_t ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
135             {
136                 descriptorSetLayouts.push_back(DescriptorSetLayoutPtr(new Unique<VkDescriptorSetLayout>(
137                     createDescriptorSetLayout(vkd, device, &descriptorSetLayoutInfo))));
138             }
139 
140             vector<VkDescriptorSetLayout> descriptorSetLayoutsRaw(numDescriptorSetsPerIter);
141 
142             for (uint32_t ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
143             {
144                 descriptorSetLayoutsRaw[ndx] = **descriptorSetLayouts[ndx];
145             }
146 
147             const VkDescriptorSetAllocateInfo descriptorSetInfo = {
148                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
149                 NULL,                                           // pNext
150                 *descriptorPool,                                // descriptorPool
151                 numDescriptorSetsPerIter,                       // descriptorSetCount
152                 &descriptorSetLayoutsRaw[0]                     // pSetLayouts
153             };
154 
155             vector<VkDescriptorSet> testSets(numDescriptorSetsPerIter);
156 
157             for (uint32_t ndx = 0; ndx < params.m_numIterations; ++ndx)
158             {
159                 if (ndx % 1024 == 0)
160                     context.getTestContext().touchWatchdog();
161                 // The test should crash in this loop at some point if there is a memory leak
162                 VK_CHECK(vkd.allocateDescriptorSets(device, &descriptorSetInfo, &testSets[0]));
163                 if (params.m_freeDescriptorSets)
164                     VK_CHECK(vkd.freeDescriptorSets(device, *descriptorPool, 1, &testSets[0]));
165                 VK_CHECK(vkd.resetDescriptorPool(device, *descriptorPool, 0));
166             }
167         }
168     }
169 
170     // If it didn't crash, pass
171     return tcu::TestStatus::pass("Pass");
172 }
173 
outOfPoolMemoryTest(Context & context)174 tcu::TestStatus outOfPoolMemoryTest(Context &context)
175 {
176     const DeviceInterface &vkd            = context.getDeviceInterface();
177     const VkDevice device                 = context.getDevice();
178     const bool expectOutOfPoolMemoryError = context.isDeviceFunctionalitySupported("VK_KHR_maintenance1");
179     uint32_t numErrorsReturned            = 0;
180 
181     const struct FailureCase
182     {
183         uint32_t poolDescriptorCount;    //!< total number of descriptors (of a given type) in the descriptor pool
184         uint32_t poolMaxSets;            //!< max number of descriptor sets that can be allocated from the pool
185         uint32_t bindingCount;           //!< number of bindings per descriptor set layout
186         uint32_t bindingDescriptorCount; //!< number of descriptors in a binding (array size) (in all bindings)
187         uint32_t descriptorSetCount;     //!< number of descriptor sets to allocate
188         string description;              //!< the log message for this failure condition
189     } failureCases[] = {
190         //    pool            pool        binding        binding        alloc set
191         //    descr. count    max sets    count        array size    count
192         {
193             4u,
194             2u,
195             1u,
196             1u,
197             3u,
198             "Out of descriptor sets",
199         },
200         {
201             3u,
202             4u,
203             1u,
204             1u,
205             4u,
206             "Out of descriptors (due to the number of sets)",
207         },
208         {
209             2u,
210             1u,
211             3u,
212             1u,
213             1u,
214             "Out of descriptors (due to the number of bindings)",
215         },
216         {
217             3u,
218             2u,
219             1u,
220             2u,
221             2u,
222             "Out of descriptors (due to descriptor array size)",
223         },
224         {
225             5u,
226             1u,
227             2u,
228             3u,
229             1u,
230             "Out of descriptors (due to descriptor array size in all bindings)",
231         },
232     };
233 
234     context.getTestContext().getLog()
235         << tcu::TestLog::Message
236         << "Creating a descriptor pool with insufficient resources. Descriptor set allocation is likely to fail."
237         << tcu::TestLog::EndMessage;
238 
239     for (uint32_t failureCaseNdx = 0u; failureCaseNdx < DE_LENGTH_OF_ARRAY(failureCases); ++failureCaseNdx)
240     {
241         const FailureCase &params = failureCases[failureCaseNdx];
242         context.getTestContext().getLog()
243             << tcu::TestLog::Message << "Checking: " << params.description << tcu::TestLog::EndMessage;
244 
245         for (VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; descriptorType < VK_DESCRIPTOR_TYPE_LAST;
246              descriptorType                  = static_cast<VkDescriptorType>(descriptorType + 1))
247         {
248             context.getTestContext().getLog()
249                 << tcu::TestLog::Message << "- " << getDescriptorTypeName(descriptorType) << tcu::TestLog::EndMessage;
250 
251             const VkDescriptorPoolSize descriptorPoolSize = {
252                 descriptorType,             // type
253                 params.poolDescriptorCount, // descriptorCount
254             };
255 
256             const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
257                 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType                sType;
258                 DE_NULL,                                       // const void*                    pNext;
259                 (VkDescriptorPoolCreateFlags)0,                // VkDescriptorPoolCreateFlags    flags;
260                 params.poolMaxSets,                            // uint32_t                       maxSets;
261                 1u,                                            // uint32_t                       poolSizeCount;
262                 &descriptorPoolSize,                           // const VkDescriptorPoolSize*    pPoolSizes;
263             };
264 
265             const Unique<VkDescriptorPool> descriptorPool(createDescriptorPool(vkd, device, &descriptorPoolCreateInfo));
266 
267             VkShaderStageFlags stageFlags = (descriptorType != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ?
268                                                 VK_SHADER_STAGE_ALL :
269                                                 VK_SHADER_STAGE_FRAGMENT_BIT;
270             const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
271                 0u,                            // uint32_t              binding;
272                 descriptorType,                // VkDescriptorType      descriptorType;
273                 params.bindingDescriptorCount, // uint32_t              descriptorCount;
274                 stageFlags,                    // VkShaderStageFlags    stageFlags;
275                 DE_NULL,                       // const VkSampler*      pImmutableSamplers;
276             };
277 
278             vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings(params.bindingCount,
279                                                                              descriptorSetLayoutBinding);
280 
281             for (uint32_t binding = 0; binding < uint32_t(descriptorSetLayoutBindings.size()); ++binding)
282             {
283                 descriptorSetLayoutBindings[binding].binding = binding;
284             }
285 
286             const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo = {
287                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType                        sType;
288                 DE_NULL,                                             // const void*                            pNext;
289                 (VkDescriptorSetLayoutCreateFlags)0,                 // VkDescriptorSetLayoutCreateFlags       flags;
290                 static_cast<uint32_t>(
291                     descriptorSetLayoutBindings.size()), // uint32_t                               bindingCount;
292                 &descriptorSetLayoutBindings[0],         // const VkDescriptorSetLayoutBinding*    pBindings;
293             };
294 
295             const Unique<VkDescriptorSetLayout> descriptorSetLayout(
296                 createDescriptorSetLayout(vkd, device, &descriptorSetLayoutInfo));
297             const vector<VkDescriptorSetLayout> rawSetLayouts(params.descriptorSetCount, *descriptorSetLayout);
298             vector<VkDescriptorSet> rawDescriptorSets(params.descriptorSetCount, DE_NULL);
299 
300             const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
301                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                 sType;
302                 DE_NULL,                                        // const void*                     pNext;
303                 *descriptorPool,                                // VkDescriptorPool                descriptorPool;
304                 static_cast<uint32_t>(rawSetLayouts.size()),    // uint32_t                        descriptorSetCount;
305                 &rawSetLayouts[0],                              // const VkDescriptorSetLayout*    pSetLayouts;
306             };
307 
308             const VkResult result =
309                 vkd.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &rawDescriptorSets[0]);
310 
311             if (result != VK_SUCCESS)
312             {
313                 ++numErrorsReturned;
314 
315                 if (expectOutOfPoolMemoryError && result != VK_ERROR_OUT_OF_POOL_MEMORY)
316                     return tcu::TestStatus::fail("Expected VK_ERROR_OUT_OF_POOL_MEMORY but got " +
317                                                  string(getResultName(result)) + " instead");
318             }
319             else
320                 context.getTestContext().getLog()
321                     << tcu::TestLog::Message << "  Allocation was successful anyway" << tcu::TestLog::EndMessage;
322         }
323     }
324 
325     if (numErrorsReturned == 0u)
326         return tcu::TestStatus::pass("Not validated");
327     else
328         return tcu::TestStatus::pass("Pass");
329 }
330 
zeroPoolSizeCount(Context & context)331 tcu::TestStatus zeroPoolSizeCount(Context &context)
332 {
333     const DeviceInterface &vkd = context.getDeviceInterface();
334     const VkDevice device      = context.getDevice();
335 
336     const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
337         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,     // VkStructureType                sType;
338         DE_NULL,                                           // const void*                    pNext;
339         VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags    flags;
340         1u,                                                // uint32_t                       maxSets;
341         0u,                                                // uint32_t                       poolSizeCount;
342         DE_NULL,                                           // const VkDescriptorPoolSize*    pPoolSizes;
343     };
344 
345     // Test a pool can be created for empty descriptor sets.
346     const Unique<VkDescriptorPool> descriptorPool(createDescriptorPool(vkd, device, &descriptorPoolCreateInfo));
347 
348     const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo = {
349         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType                        sType;
350         DE_NULL,                                             // const void*                            pNext;
351         (VkDescriptorSetLayoutCreateFlags)0,                 // VkDescriptorSetLayoutCreateFlags       flags;
352         0u,                                                  // uint32_t                               bindingCount;
353         DE_NULL,                                             // const VkDescriptorSetLayoutBinding*    pBindings;
354     };
355 
356     const Unique<VkDescriptorSetLayout> descriptorSetLayout(
357         createDescriptorSetLayout(vkd, device, &descriptorSetLayoutInfo));
358 
359     const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
360         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                 sType;
361         DE_NULL,                                        // const void*                     pNext;
362         *descriptorPool,                                // VkDescriptorPool                descriptorPool;
363         1u,                                             // uint32_t                        descriptorSetCount;
364         &descriptorSetLayout.get(),                     // const VkDescriptorSetLayout*    pSetLayouts;
365     };
366 
367     // Create an empty descriptor set from the pool.
368     VkDescriptorSet descriptorSet;
369     VkResult result = vkd.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet);
370     if (result != VK_SUCCESS)
371         return tcu::TestStatus::fail("Expected vkAllocateDescriptorSets to return VK_SUCCESS but got " +
372                                      string(getResultName(result)) + " instead");
373 
374     // Free the empty descriptor set back to the pool.
375     result = vkd.freeDescriptorSets(device, *descriptorPool, 1, &descriptorSet);
376     if (result != VK_SUCCESS)
377         return tcu::TestStatus::fail("Expected vkFreeDescriptorSets to return VK_SUCCESS but got " +
378                                      string(getResultName(result)) + " instead");
379 
380     return tcu::TestStatus::pass("Pass");
381 }
382 
383 #ifdef CTS_USES_VULKANSC
noResetDescriptorPoolTest(Context & context,const ResetDescriptorPoolTestParams params)384 tcu::TestStatus noResetDescriptorPoolTest(Context &context, const ResetDescriptorPoolTestParams params)
385 {
386     const DeviceInterface &vkd = context.getDeviceInterface();
387 
388     const uint32_t numDescriptorSetsPerIter = 100;
389     const float queuePriority               = 1.0f;
390 
391     const VkDeviceQueueCreateInfo deviceQueueCI = {
392         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
393         DE_NULL,                                    // pNext
394         (VkDeviceQueueCreateFlags)0u,               // flags
395         0,                                          //queueFamilyIndex;
396         1,                                          //queueCount;
397         &queuePriority,                             //pQueuePriorities;
398     };
399 
400     VkDeviceCreateInfo deviceCreateInfo = {
401         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType;
402         DE_NULL,                              // pNext;
403         (VkDeviceCreateFlags)0u,              // flags
404         1,                                    // queueCount;
405         &deviceQueueCI,                       // pQueues;
406         0,                                    // layerCount;
407         DE_NULL,                              // ppEnabledLayerNames;
408         0,                                    // extensionCount;
409         DE_NULL,                              // ppEnabledExtensionNames;
410         DE_NULL,                              // pEnabledFeatures;
411     };
412 
413     VkDeviceObjectReservationCreateInfo objectInfo    = resetDeviceObjectReservationCreateInfo();
414     objectInfo.descriptorPoolRequestCount             = 1u;
415     objectInfo.descriptorSetRequestCount              = numDescriptorSetsPerIter;
416     objectInfo.descriptorSetLayoutRequestCount        = numDescriptorSetsPerIter;
417     objectInfo.descriptorSetLayoutBindingRequestCount = numDescriptorSetsPerIter;
418     objectInfo.descriptorSetLayoutBindingLimit        = 1u;
419     objectInfo.pNext                                  = DE_NULL;
420 
421     VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
422     sc10Features.pNext                              = &objectInfo;
423 
424     deviceCreateInfo.pNext = &sc10Features;
425 
426     const VkDescriptorPoolSize descriptorPoolSize = {
427         VK_DESCRIPTOR_TYPE_SAMPLER, // type
428         numDescriptorSetsPerIter    // descriptorCount
429     };
430 
431     const VkDescriptorPoolCreateInfo descriptorPoolInfo = {
432         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,                                  // sType
433         NULL,                                                                           // pNext
434         (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // flags
435         numDescriptorSetsPerIter,                                                       // maxSets
436         1,                                                                              // poolSizeCount
437         &descriptorPoolSize                                                             // pPoolSizes
438     };
439 
440     for (uint32_t i = 0; i < params.m_numIterations; ++i)
441     {
442         vkt::CustomInstance instance = vkt::createCustomInstanceFromContext(context);
443         VkPhysicalDevice physicalDevice =
444             chooseDevice(instance.getDriver(), instance, context.getTestContext().getCommandLine());
445         Move<VkDevice> device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(),
446                                                    context.getPlatformInterface(), instance, instance.getDriver(),
447                                                    physicalDevice, &deviceCreateInfo);
448 
449         VkDescriptorPool descriptorPool = 0;
450         VK_CHECK(vkd.createDescriptorPool(*device, &descriptorPoolInfo, DE_NULL, &descriptorPool));
451         if (!descriptorPool)
452             TCU_THROW(TestError, "create descriptor pool failed");
453 
454         const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
455             0,                          // binding
456             VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType
457             1,                          // descriptorCount
458             VK_SHADER_STAGE_ALL,        // stageFlags
459             NULL                        // pImmutableSamplers
460         };
461 
462         const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo = {
463             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
464             NULL,                                                // pNext
465             0,                                                   // flags
466             1,                                                   // bindingCount
467             &descriptorSetLayoutBinding                          // pBindings
468         };
469 
470         typedef de::SharedPtr<Unique<VkDescriptorSetLayout>> DescriptorSetLayoutPtr;
471 
472         vector<DescriptorSetLayoutPtr> descriptorSetLayouts;
473         descriptorSetLayouts.reserve(numDescriptorSetsPerIter);
474 
475         for (uint32_t ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
476         {
477             descriptorSetLayouts.push_back(DescriptorSetLayoutPtr(
478                 new Unique<VkDescriptorSetLayout>(createDescriptorSetLayout(vkd, *device, &descriptorSetLayoutInfo))));
479         }
480 
481         vector<VkDescriptorSetLayout> descriptorSetLayoutsRaw(numDescriptorSetsPerIter);
482 
483         for (uint32_t ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
484         {
485             descriptorSetLayoutsRaw[ndx] = **descriptorSetLayouts[ndx];
486         }
487 
488         const VkDescriptorSetAllocateInfo descriptorSetInfo = {
489             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
490             NULL,                                           // pNext
491             descriptorPool,                                 // descriptorPool
492             numDescriptorSetsPerIter,                       // descriptorSetCount
493             &descriptorSetLayoutsRaw[0]                     // pSetLayouts
494         };
495 
496         vector<VkDescriptorSet> testSets(numDescriptorSetsPerIter);
497 
498         VK_CHECK(vkd.allocateDescriptorSets(*device, &descriptorSetInfo, &testSets[0]));
499         VK_CHECK(vkd.freeDescriptorSets(*device, descriptorPool, numDescriptorSetsPerIter, &testSets[0]));
500     }
501 
502     // If it didn't crash, pass
503     return tcu::TestStatus::pass("Pass");
504 }
505 #endif
506 
507 } // namespace
508 
createDescriptorPoolTests(tcu::TestContext & testCtx)509 tcu::TestCaseGroup *createDescriptorPoolTests(tcu::TestContext &testCtx)
510 {
511     const uint32_t numIterationsHigh = 4096;
512 
513     de::MovePtr<tcu::TestCaseGroup> descriptorPoolTests(new tcu::TestCaseGroup(testCtx, "descriptor_pool"));
514 
515     // Test 2 cycles of vkAllocateDescriptorSets and vkResetDescriptorPool (should pass)
516     addFunctionCase(descriptorPoolTests.get(), "repeated_reset_short", checkSupportFreeDescriptorSets,
517                     resetDescriptorPoolTest, ResetDescriptorPoolTestParams(2U));
518     // Test many cycles of vkAllocateDescriptorSets and vkResetDescriptorPool
519     addFunctionCase(descriptorPoolTests.get(), "repeated_reset_long", checkSupportFreeDescriptorSets,
520                     resetDescriptorPoolTest, ResetDescriptorPoolTestParams(numIterationsHigh));
521     // Test 2 cycles of vkAllocateDescriptorSets, vkFreeDescriptorSets and vkResetDescriptorPool (should pass)
522     addFunctionCase(descriptorPoolTests.get(), "repeated_free_reset_short", checkSupportFreeDescriptorSets,
523                     resetDescriptorPoolTest, ResetDescriptorPoolTestParams(2U, true));
524     // Test many cycles of vkAllocateDescriptorSets, vkFreeDescriptorSets and vkResetDescriptorPool
525     addFunctionCase(descriptorPoolTests.get(), "repeated_free_reset_long", checkSupportFreeDescriptorSets,
526                     resetDescriptorPoolTest, ResetDescriptorPoolTestParams(numIterationsHigh, true));
527     // Test that when we run out of descriptors a correct error code is returned
528     addFunctionCase(descriptorPoolTests.get(), "out_of_pool_memory", outOfPoolMemoryTest);
529     // Test a descriptor pool object can be created with zero pools without error or crash
530     addFunctionCase(descriptorPoolTests.get(), "zero_pool_size_count", zeroPoolSizeCount);
531 #ifdef CTS_USES_VULKANSC
532     // Test 2 cycles of vkAllocateDescriptorSets, vkFreeDescriptorSets and vkDestroyDevice (should pass)
533     addFunctionCase(descriptorPoolTests.get(), "repeated_free_no_reset_short", noResetDescriptorPoolTest,
534                     ResetDescriptorPoolTestParams(2U, true));
535 
536     // Test many cycles of vkAllocateDescriptorSets, vkFreeDescriptorSets and vkDestroyDevice (should pass)
537     addFunctionCase(descriptorPoolTests.get(), "repeated_free_no_reset_long", noResetDescriptorPoolTest,
538                     ResetDescriptorPoolTestParams(200U, true));
539 #endif
540 
541     return descriptorPoolTests.release();
542 }
543 
544 } // namespace api
545 } // namespace vkt
546