Merge remote-tracking branch 'aosp/master' into HEAD
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiDescriptorPoolTests.cpp
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 #define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1)
44
45 namespace vkt
46 {
47 namespace api
48 {
49
50 namespace
51 {
52
53 using namespace std;
54 using namespace vk;
55
56 struct ResetDescriptorPoolTestParams
57 {
58         ResetDescriptorPoolTestParams   (deUint32 numIterations, bool freeDescriptorSets = false)
59                 : m_numIterations               (numIterations)
60                 , m_freeDescriptorSets  (freeDescriptorSets)
61         {}
62
63         deUint32        m_numIterations;
64         bool            m_freeDescriptorSets;
65 };
66
67 tcu::TestStatus resetDescriptorPoolTest (Context& context, const ResetDescriptorPoolTestParams params)
68 {
69         const deUint32                          numDescriptorSetsPerIter = 2048;
70         const DeviceInterface&          vkd                                              = context.getDeviceInterface();
71         const VkDevice                          device                                   = context.getDevice();
72
73         const VkDescriptorPoolSize descriptorPoolSize =
74         {
75                 VK_DESCRIPTOR_TYPE_SAMPLER, // type
76                 numDescriptorSetsPerIter        // descriptorCount
77         };
78
79         const VkDescriptorPoolCreateInfo descriptorPoolInfo =
80         {
81                 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,                                                                                                                                                  // sType
82                 NULL,                                                                                                                                                                                                                                   // pNext
83                 (params.m_freeDescriptorSets) ? (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT : 0u,    // flags
84                 numDescriptorSetsPerIter,                                                                                                                                                                                               // maxSets
85                 1,                                                                                                                                                                                                                                              // poolSizeCount
86                 &descriptorPoolSize                                                                                                                                                                                                             // pPoolSizes
87         };
88
89         {
90                 const Unique<VkDescriptorPool> descriptorPool(
91                         createDescriptorPool(vkd, device,
92                                                                  &descriptorPoolInfo));
93
94                 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding =
95                 {
96                         0,                                                      // binding
97                         VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType
98                         1,                                                      // descriptorCount
99                         VK_SHADER_STAGE_ALL,            // stageFlags
100                         NULL                                            // pImmutableSamplers
101                 };
102
103                 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo =
104                 {
105                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // sType
106                         NULL,                                                                                                   // pNext
107                         0,                                                                                                              // flags
108                         1,                                                                                                              // bindingCount
109                         &descriptorSetLayoutBinding                                                             // pBindings
110                 };
111
112                 {
113                         typedef de::SharedPtr<Unique<VkDescriptorSetLayout> > DescriptorSetLayoutPtr;
114
115                         vector<DescriptorSetLayoutPtr> descriptorSetLayouts;
116                         descriptorSetLayouts.reserve(numDescriptorSetsPerIter);
117
118                         for (deUint32 ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
119                         {
120                                 descriptorSetLayouts.push_back(
121                                         DescriptorSetLayoutPtr(
122                                                 new Unique<VkDescriptorSetLayout>(
123                                                         createDescriptorSetLayout(vkd, device,
124                                                                                                           &descriptorSetLayoutInfo))));
125                         }
126
127                         vector<VkDescriptorSetLayout> descriptorSetLayoutsRaw(numDescriptorSetsPerIter);
128
129                         for (deUint32 ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
130                         {
131                                 descriptorSetLayoutsRaw[ndx] = **descriptorSetLayouts[ndx];
132                         }
133
134                         const VkDescriptorSetAllocateInfo descriptorSetInfo =
135                         {
136                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
137                                 NULL,                                                                                   // pNext
138                                 *descriptorPool,                                                                // descriptorPool
139                                 numDescriptorSetsPerIter,                                               // descriptorSetCount
140                                 &descriptorSetLayoutsRaw[0]                                             // pSetLayouts
141                         };
142
143                         vector<VkDescriptorSet> testSets(numDescriptorSetsPerIter);
144
145                         for (deUint32 ndx = 0; ndx < params.m_numIterations; ++ndx)
146                         {
147                                 // The test should crash in this loop at some point if there is a memory leak
148                                 VK_CHECK(vkd.allocateDescriptorSets(device, &descriptorSetInfo, &testSets[0]));
149                                 if (params.m_freeDescriptorSets)
150                                         VK_CHECK(vkd.freeDescriptorSets(device, *descriptorPool, 1, &testSets[0]));
151                                 VK_CHECK(vkd.resetDescriptorPool(device, *descriptorPool, 0));
152                         }
153
154                 }
155         }
156
157         // If it didn't crash, pass
158         return tcu::TestStatus::pass("Pass");
159 }
160
161 tcu::TestStatus outOfPoolMemoryTest (Context& context)
162 {
163         const DeviceInterface&  vkd                                                     = context.getDeviceInterface();
164         const VkDevice                  device                                          = context.getDevice();
165         const bool                              expectOutOfPoolMemoryError      = isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1");
166         deUint32                                numErrorsReturned                       = 0;
167
168         const struct FailureCase
169         {
170                 deUint32        poolDescriptorCount;            //!< total number of descriptors (of a given type) in the descriptor pool
171                 deUint32        poolMaxSets;                            //!< max number of descriptor sets that can be allocated from the pool
172                 deUint32        bindingCount;                           //!< number of bindings per descriptor set layout
173                 deUint32        bindingDescriptorCount;         //!< number of descriptors in a binding (array size) (in all bindings)
174                 deUint32        descriptorSetCount;                     //!< number of descriptor sets to allocate
175                 string          description;                            //!< the log message for this failure condition
176         } failureCases[] =
177         {
178                 //      pool                    pool            binding         binding         alloc set
179                 //      descr. count    max sets        count           array size      count
180                 {       4u,                             2u,                     1u,                     1u,                     3u,             "Out of descriptor sets",                                                                                       },
181                 {       3u,                             4u,                     1u,                     1u,                     4u,             "Out of descriptors (due to the number of sets)",                                       },
182                 {       2u,                             1u,                     3u,                     1u,                     1u,             "Out of descriptors (due to the number of bindings)",                           },
183                 {       3u,                             2u,                     1u,                     2u,                     2u,             "Out of descriptors (due to descriptor array size)",                            },
184                 {       5u,                             1u,                     2u,                     3u,                     1u,             "Out of descriptors (due to descriptor array size in all bindings)",},
185         };
186
187         context.getTestContext().getLog()
188                 << tcu::TestLog::Message
189                 << "Creating a descriptor pool with insufficient resources. Descriptor set allocation is likely to fail."
190                 << tcu::TestLog::EndMessage;
191
192         for (deUint32 failureCaseNdx = 0u; failureCaseNdx < DE_LENGTH_OF_ARRAY(failureCases); ++failureCaseNdx)
193         {
194                 const FailureCase& params = failureCases[failureCaseNdx];
195                 context.getTestContext().getLog() << tcu::TestLog::Message << "Checking: " << params.description << tcu::TestLog::EndMessage;
196
197                 for (VkDescriptorType   descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
198                                                                 descriptorType < VK_DESCRIPTOR_TYPE_LAST;
199                                                                 descriptorType = static_cast<VkDescriptorType>(descriptorType + 1))
200                 {
201                         context.getTestContext().getLog() << tcu::TestLog::Message << "- " << getDescriptorTypeName(descriptorType) << tcu::TestLog::EndMessage;
202
203                         const VkDescriptorPoolSize                                      descriptorPoolSize =
204                         {
205                                 descriptorType,                                                                                         // type
206                                 params.poolDescriptorCount,                                                                     // descriptorCount
207                         };
208
209                         const VkDescriptorPoolCreateInfo                        descriptorPoolCreateInfo =
210                         {
211                                 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,                          // VkStructureType                sType;
212                                 DE_NULL,                                                                                                        // const void*                    pNext;
213                                 (VkDescriptorPoolCreateFlags)0,                                                         // VkDescriptorPoolCreateFlags    flags;
214                                 params.poolMaxSets,                                                                                     // uint32_t                       maxSets;
215                                 1u,                                                                                                                     // uint32_t                       poolSizeCount;
216                                 &descriptorPoolSize,                                                                            // const VkDescriptorPoolSize*    pPoolSizes;
217                         };
218
219                         const Unique<VkDescriptorPool>                          descriptorPool(createDescriptorPool(vkd, device, &descriptorPoolCreateInfo));
220
221                         const VkDescriptorSetLayoutBinding                      descriptorSetLayoutBinding =
222                         {
223                                 0u,                                                                                                                     // uint32_t              binding;
224                                 descriptorType,                                                                                         // VkDescriptorType      descriptorType;
225                                 params.bindingDescriptorCount,                                                          // uint32_t              descriptorCount;
226                                 VK_SHADER_STAGE_ALL,                                                                            // VkShaderStageFlags    stageFlags;
227                                 DE_NULL,                                                                                                        // const VkSampler*      pImmutableSamplers;
228                         };
229
230                         vector<VkDescriptorSetLayoutBinding>    descriptorSetLayoutBindings (params.bindingCount, descriptorSetLayoutBinding);
231
232                         for (deUint32 binding = 0; binding < deUint32(descriptorSetLayoutBindings.size()); ++binding)
233                         {
234                                 descriptorSetLayoutBindings[binding].binding = binding;
235                         }
236
237                         const VkDescriptorSetLayoutCreateInfo           descriptorSetLayoutInfo =
238                         {
239                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                        sType;
240                                 DE_NULL,                                                                                                        // const void*                            pNext;
241                                 (VkDescriptorSetLayoutCreateFlags)0,                                            // VkDescriptorSetLayoutCreateFlags       flags;
242                                 static_cast<deUint32>(descriptorSetLayoutBindings.size()),      // uint32_t                               bindingCount;
243                                 &descriptorSetLayoutBindings[0],                                                        // const VkDescriptorSetLayoutBinding*    pBindings;
244                         };
245
246                         const Unique<VkDescriptorSetLayout>                     descriptorSetLayout     (createDescriptorSetLayout(vkd, device, &descriptorSetLayoutInfo));
247                         const vector<VkDescriptorSetLayout>                     rawSetLayouts           (params.descriptorSetCount, *descriptorSetLayout);
248                         vector<VkDescriptorSet>                                         rawDescriptorSets       (params.descriptorSetCount, DE_NULL);
249
250                         const VkDescriptorSetAllocateInfo                       descriptorSetAllocateInfo =
251                         {
252                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,                         // VkStructureType                 sType;
253                                 DE_NULL,                                                                                                        // const void*                     pNext;
254                                 *descriptorPool,                                                                                        // VkDescriptorPool                descriptorPool;
255                                 static_cast<deUint32>(rawSetLayouts.size()),                            // uint32_t                        descriptorSetCount;
256                                 &rawSetLayouts[0],                                                                                      // const VkDescriptorSetLayout*    pSetLayouts;
257                         };
258
259                         const VkResult result = vkd.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &rawDescriptorSets[0]);
260
261                         if (result != VK_SUCCESS)
262                         {
263                                 ++numErrorsReturned;
264
265                                 if (expectOutOfPoolMemoryError && result != VK_ERROR_OUT_OF_POOL_MEMORY)
266                                         return tcu::TestStatus::fail("Expected VK_ERROR_OUT_OF_POOL_MEMORY but got " + string(getResultName(result)) + " instead");
267                         }
268                         else
269                                 context.getTestContext().getLog() << tcu::TestLog::Message << "  Allocation was successful anyway" << tcu::TestLog::EndMessage;
270                 }
271         }
272
273         if (numErrorsReturned == 0u)
274                 return tcu::TestStatus::pass("Not validated");
275         else
276                 return tcu::TestStatus::pass("Pass");
277 }
278
279 } // anonymous
280
281 tcu::TestCaseGroup* createDescriptorPoolTests (tcu::TestContext& testCtx)
282 {
283         const deUint32 numIterationsHigh = 4096;
284
285         de::MovePtr<tcu::TestCaseGroup> descriptorPoolTests(
286                 new tcu::TestCaseGroup(testCtx, "descriptor_pool", "Descriptor Pool Tests"));
287
288         addFunctionCase(descriptorPoolTests.get(),
289                                         "repeated_reset_short",
290                                         "Test 2 cycles of vkAllocateDescriptorSets and vkResetDescriptorPool (should pass)",
291                                         resetDescriptorPoolTest, ResetDescriptorPoolTestParams(2U));
292         addFunctionCase(descriptorPoolTests.get(),
293                                         "repeated_reset_long",
294                                         "Test many cycles of vkAllocateDescriptorSets and vkResetDescriptorPool",
295                                         resetDescriptorPoolTest, ResetDescriptorPoolTestParams(numIterationsHigh));
296         addFunctionCase(descriptorPoolTests.get(),
297                                         "repeated_free_reset_short",
298                                         "Test 2 cycles of vkAllocateDescriptorSets, vkFreeDescriptorSets and vkResetDescriptorPool (should pass)",
299                                         resetDescriptorPoolTest, ResetDescriptorPoolTestParams(2U, true));
300         addFunctionCase(descriptorPoolTests.get(),
301                                         "repeated_free_reset_long",
302                                         "Test many cycles of vkAllocateDescriptorSets, vkFreeDescriptorSets and vkResetDescriptorPool",
303                                         resetDescriptorPoolTest, ResetDescriptorPoolTestParams(numIterationsHigh, true));
304         addFunctionCase(descriptorPoolTests.get(),
305                                         "out_of_pool_memory",
306                                         "Test that when we run out of descriptors a correct error code is returned",
307                                         outOfPoolMemoryTest);
308
309         return descriptorPoolTests.release();
310 }
311
312 } // api
313 } // vkt