1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 Google Inc.
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 Descriptor pool tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktApiDescriptorPoolTests.hpp"
25 #include "vktTestCaseUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkDeviceUtil.hpp"
33 #include "tcuCommandLine.hpp"
34 #include "tcuTestLog.hpp"
35 #include "tcuPlatform.hpp"
37 #include "deUniquePtr.hpp"
38 #include "deSharedPtr.hpp"
40 #include "deSTLUtil.hpp"
53 tcu::TestStatus resetDescriptorPoolTest (Context& context, deUint32 numIterations)
55 const deUint32 numDescriptorSetsPerIter = 2048;
56 const DeviceInterface& vkd = context.getDeviceInterface();
57 const VkDevice device = context.getDevice();
59 const VkDescriptorPoolSize descriptorPoolSize =
61 VK_DESCRIPTOR_TYPE_SAMPLER, // type
62 numDescriptorSetsPerIter // descriptorCount
65 // \todo [2016-05-24 collinbaker] Test with flag VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT
66 const VkDescriptorPoolCreateInfo descriptorPoolInfo =
68 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
71 numDescriptorSetsPerIter, // maxSets
73 &descriptorPoolSize // pPoolSizes
77 const Unique<VkDescriptorPool> descriptorPool(
78 createDescriptorPool(vkd, device,
79 &descriptorPoolInfo));
81 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding =
84 VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType
86 VK_SHADER_STAGE_ALL, // stageFlags
87 NULL // pImmutableSamplers
90 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo =
92 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
96 &descriptorSetLayoutBinding // pBindings
100 typedef de::SharedPtr<Unique<VkDescriptorSetLayout> > DescriptorSetLayoutPtr;
102 vector<DescriptorSetLayoutPtr> descriptorSetLayouts;
103 descriptorSetLayouts.reserve(numDescriptorSetsPerIter);
105 for (deUint32 ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
107 descriptorSetLayouts.push_back(
108 DescriptorSetLayoutPtr(
109 new Unique<VkDescriptorSetLayout>(
110 createDescriptorSetLayout(vkd, device,
111 &descriptorSetLayoutInfo))));
114 vector<VkDescriptorSetLayout> descriptorSetLayoutsRaw(numDescriptorSetsPerIter);
116 for (deUint32 ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
118 descriptorSetLayoutsRaw[ndx] = **descriptorSetLayouts[ndx];
121 const VkDescriptorSetAllocateInfo descriptorSetInfo =
123 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
125 *descriptorPool, // descriptorPool
126 numDescriptorSetsPerIter, // descriptorSetCount
127 &descriptorSetLayoutsRaw[0] // pSetLayouts
130 vector<VkDescriptorSet> testSets(numDescriptorSetsPerIter);
132 for (deUint32 ndx = 0; ndx < numIterations; ++ndx)
134 // The test should crash in this loop at some point if there is a memory leak
135 VK_CHECK(vkd.allocateDescriptorSets(device, &descriptorSetInfo, &testSets[0]));
136 VK_CHECK(vkd.resetDescriptorPool(device, *descriptorPool, 0));
142 // If it didn't crash, pass
143 return tcu::TestStatus::pass("Pass");
146 tcu::TestStatus outOfPoolMemoryTest (Context& context)
148 const DeviceInterface& vkd = context.getDeviceInterface();
149 const VkDevice device = context.getDevice();
150 const bool expectOutOfPoolMemoryError = de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1");
151 deUint32 numErrorsReturned = 0;
153 const struct FailureCase
155 deUint32 poolDescriptorCount; //!< total number of descriptors (of a given type) in the descriptor pool
156 deUint32 poolMaxSets; //!< max number of descriptor sets that can be allocated from the pool
157 deUint32 bindingCount; //!< number of bindings per descriptor set layout
158 deUint32 bindingDescriptorCount; //!< number of descriptors in a binding (array size) (in all bindings)
159 deUint32 descriptorSetCount; //!< number of descriptor sets to allocate
160 string description; //!< the log message for this failure condition
163 // pool pool binding binding alloc set
164 // descr. count max sets count array size count
165 { 4u, 2u, 1u, 1u, 3u, "Out of descriptor sets", },
166 { 3u, 4u, 1u, 1u, 4u, "Out of descriptors (due to the number of sets)", },
167 { 2u, 1u, 3u, 1u, 1u, "Out of descriptors (due to the number of bindings)", },
168 { 3u, 2u, 1u, 2u, 2u, "Out of descriptors (due to descriptor array size)", },
169 { 5u, 1u, 2u, 3u, 1u, "Out of descriptors (due to descriptor array size in all bindings)",},
172 context.getTestContext().getLog()
173 << tcu::TestLog::Message
174 << "Creating a descriptor pool with insufficient resources. Descriptor set allocation is likely to fail."
175 << tcu::TestLog::EndMessage;
177 for (deUint32 failureCaseNdx = 0u; failureCaseNdx < DE_LENGTH_OF_ARRAY(failureCases); ++failureCaseNdx)
179 const FailureCase& params = failureCases[failureCaseNdx];
180 context.getTestContext().getLog() << tcu::TestLog::Message << "Checking: " << params.description << tcu::TestLog::EndMessage;
182 for (VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
183 descriptorType < VK_DESCRIPTOR_TYPE_LAST;
184 descriptorType = static_cast<VkDescriptorType>(descriptorType + 1))
186 context.getTestContext().getLog() << tcu::TestLog::Message << "- " << getDescriptorTypeName(descriptorType) << tcu::TestLog::EndMessage;
188 const VkDescriptorPoolSize descriptorPoolSize =
190 descriptorType, // type
191 params.poolDescriptorCount, // descriptorCount
194 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
196 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType;
197 DE_NULL, // const void* pNext;
198 (VkDescriptorPoolCreateFlags)0, // VkDescriptorPoolCreateFlags flags;
199 params.poolMaxSets, // uint32_t maxSets;
200 1u, // uint32_t poolSizeCount;
201 &descriptorPoolSize, // const VkDescriptorPoolSize* pPoolSizes;
204 const Unique<VkDescriptorPool> descriptorPool(createDescriptorPool(vkd, device, &descriptorPoolCreateInfo));
206 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding =
208 0u, // uint32_t binding;
209 descriptorType, // VkDescriptorType descriptorType;
210 params.bindingDescriptorCount, // uint32_t descriptorCount;
211 VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags;
212 DE_NULL, // const VkSampler* pImmutableSamplers;
215 const vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings (params.bindingCount, descriptorSetLayoutBinding);
216 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo =
218 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
219 DE_NULL, // const void* pNext;
220 (VkDescriptorSetLayoutCreateFlags)0, // VkDescriptorSetLayoutCreateFlags flags;
221 static_cast<deUint32>(descriptorSetLayoutBindings.size()), // uint32_t bindingCount;
222 &descriptorSetLayoutBindings[0], // const VkDescriptorSetLayoutBinding* pBindings;
225 const Unique<VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout(vkd, device, &descriptorSetLayoutInfo));
226 const vector<VkDescriptorSetLayout> rawSetLayouts (params.descriptorSetCount, *descriptorSetLayout);
227 vector<VkDescriptorSet> rawDescriptorSets (params.descriptorSetCount, DE_NULL);
229 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
231 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
232 DE_NULL, // const void* pNext;
233 *descriptorPool, // VkDescriptorPool descriptorPool;
234 static_cast<deUint32>(rawSetLayouts.size()), // uint32_t descriptorSetCount;
235 &rawSetLayouts[0], // const VkDescriptorSetLayout* pSetLayouts;
238 const VkResult result = vkd.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &rawDescriptorSets[0]);
240 if (result != VK_SUCCESS)
244 if (expectOutOfPoolMemoryError && result != VK_ERROR_OUT_OF_POOL_MEMORY_KHR)
245 return tcu::TestStatus::fail("Expected VK_ERROR_OUT_OF_POOL_MEMORY_KHR but got " + string(getResultName(result)) + " instead");
248 context.getTestContext().getLog() << tcu::TestLog::Message << " Allocation was successful anyway" << tcu::TestLog::EndMessage;
252 if (numErrorsReturned == 0u)
253 return tcu::TestStatus::pass("Not validated");
255 return tcu::TestStatus::pass("Pass");
260 tcu::TestCaseGroup* createDescriptorPoolTests (tcu::TestContext& testCtx)
262 const deUint32 numIterationsHigh = 4096;
264 de::MovePtr<tcu::TestCaseGroup> descriptorPoolTests(
265 new tcu::TestCaseGroup(testCtx, "descriptor_pool", "Descriptor Pool Tests"));
267 addFunctionCase(descriptorPoolTests.get(),
268 "repeated_reset_short",
269 "Test 2 cycles of vkAllocateDescriptorSets and vkResetDescriptorPool (should pass)",
270 resetDescriptorPoolTest, 2U);
271 addFunctionCase(descriptorPoolTests.get(),
272 "repeated_reset_long",
273 "Test many cycles of vkAllocateDescriptorSets and vkResetDescriptorPool",
274 resetDescriptorPoolTest, numIterationsHigh);
275 addFunctionCase(descriptorPoolTests.get(),
276 "out_of_pool_memory",
277 "Test that when we run out of descriptors a correct error code is returned",
278 outOfPoolMemoryTest);
280 return descriptorPoolTests.release();