1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group 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 Null handle tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktApiNullHandleTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktTestGroupUtil.hpp"
27
28 #include "vkDefs.hpp"
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkAllocationCallbackUtil.hpp"
32
33 namespace vkt
34 {
35 namespace api
36 {
37 namespace
38 {
39
40 using namespace vk;
41
release(Context & context,VkBuffer buffer,const VkAllocationCallbacks * pAllocator)42 inline void release (Context& context, VkBuffer buffer, const VkAllocationCallbacks* pAllocator)
43 {
44 context.getDeviceInterface().destroyBuffer(context.getDevice(), buffer, pAllocator);
45 }
46
release(Context & context,VkBufferView bufferView,const VkAllocationCallbacks * pAllocator)47 inline void release (Context& context, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)
48 {
49 context.getDeviceInterface().destroyBufferView(context.getDevice(), bufferView, pAllocator);
50 }
51
52 #ifndef CTS_USES_VULKANSC
release(Context & context,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)53 inline void release (Context& context, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator)
54 {
55 context.getDeviceInterface().destroyCommandPool(context.getDevice(), commandPool, pAllocator);
56 }
57
release(Context & context,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)58 inline void release (Context& context, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator)
59 {
60 context.getDeviceInterface().destroyDescriptorPool(context.getDevice(), descriptorPool, pAllocator);
61 }
62 #endif // CTS_USES_VULKANSC
63
release(Context & context,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)64 inline void release (Context& context, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator)
65 {
66 context.getDeviceInterface().destroyDescriptorSetLayout(context.getDevice(), descriptorSetLayout, pAllocator);
67 }
68
release(Context & context,VkDevice device,const VkAllocationCallbacks * pAllocator)69 inline void release (Context& context, VkDevice device, const VkAllocationCallbacks* pAllocator)
70 {
71 context.getDeviceInterface().destroyDevice(device, pAllocator);
72 }
73
release(Context & context,VkEvent event,const VkAllocationCallbacks * pAllocator)74 inline void release (Context& context, VkEvent event, const VkAllocationCallbacks* pAllocator)
75 {
76 context.getDeviceInterface().destroyEvent(context.getDevice(), event, pAllocator);
77 }
78
release(Context & context,VkFence fence,const VkAllocationCallbacks * pAllocator)79 inline void release (Context& context, VkFence fence, const VkAllocationCallbacks* pAllocator)
80 {
81 context.getDeviceInterface().destroyFence(context.getDevice(), fence, pAllocator);
82 }
83
release(Context & context,VkFramebuffer framebuffer,const VkAllocationCallbacks * pAllocator)84 inline void release (Context& context, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator)
85 {
86 context.getDeviceInterface().destroyFramebuffer(context.getDevice(), framebuffer, pAllocator);
87 }
88
release(Context & context,VkImage image,const VkAllocationCallbacks * pAllocator)89 inline void release (Context& context, VkImage image, const VkAllocationCallbacks* pAllocator)
90 {
91 context.getDeviceInterface().destroyImage(context.getDevice(), image, pAllocator);
92 }
93
release(Context & context,VkImageView imageView,const VkAllocationCallbacks * pAllocator)94 inline void release (Context& context, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
95 {
96 context.getDeviceInterface().destroyImageView(context.getDevice(), imageView, pAllocator);
97 }
98
release(Context & context,VkInstance instance,const VkAllocationCallbacks * pAllocator)99 inline void release (Context& context, VkInstance instance, const VkAllocationCallbacks* pAllocator)
100 {
101 context.getInstanceInterface().destroyInstance(instance, pAllocator);
102 }
103
release(Context & context,VkPipeline pipeline,const VkAllocationCallbacks * pAllocator)104 inline void release (Context& context, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
105 {
106 context.getDeviceInterface().destroyPipeline(context.getDevice(), pipeline, pAllocator);
107 }
108
release(Context & context,VkPipelineCache pipelineCache,const VkAllocationCallbacks * pAllocator)109 inline void release (Context& context, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
110 {
111 context.getDeviceInterface().destroyPipelineCache(context.getDevice(), pipelineCache, pAllocator);
112 }
113
release(Context & context,VkPipelineLayout pipelineLayout,const VkAllocationCallbacks * pAllocator)114 inline void release (Context& context, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
115 {
116 context.getDeviceInterface().destroyPipelineLayout(context.getDevice(), pipelineLayout, pAllocator);
117 }
118
119 #ifndef CTS_USES_VULKANSC
release(Context & context,VkQueryPool queryPool,const VkAllocationCallbacks * pAllocator)120 inline void release (Context& context, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator)
121 {
122 context.getDeviceInterface().destroyQueryPool(context.getDevice(), queryPool, pAllocator);
123 }
124 #endif // CTS_USES_VULKANSC
125
release(Context & context,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)126 inline void release (Context& context, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
127 {
128 context.getDeviceInterface().destroyRenderPass(context.getDevice(), renderPass, pAllocator);
129 }
130
release(Context & context,VkSampler sampler,const VkAllocationCallbacks * pAllocator)131 inline void release (Context& context, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
132 {
133 context.getDeviceInterface().destroySampler(context.getDevice(), sampler, pAllocator);
134 }
135
release(Context & context,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)136 inline void release (Context& context, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
137 {
138 context.getDeviceInterface().destroySemaphore(context.getDevice(), semaphore, pAllocator);
139 }
140
release(Context & context,VkShaderModule shaderModule,const VkAllocationCallbacks * pAllocator)141 inline void release (Context& context, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator)
142 {
143 #ifndef CTS_USES_VULKANSC
144 context.getDeviceInterface().destroyShaderModule(context.getDevice(), shaderModule, pAllocator);
145 #else
146 DE_UNREF(context);
147 DE_UNREF(shaderModule);
148 DE_UNREF(pAllocator);
149 #endif // CTS_USES_VULKANSC
150 }
151
release(Context & context,VkDevice device,VkCommandPool cmdPool,deUint32 numCmdBuffers,const VkCommandBuffer * pCmdBuffers)152 inline void release (Context& context, VkDevice device, VkCommandPool cmdPool, deUint32 numCmdBuffers, const VkCommandBuffer* pCmdBuffers)
153 {
154 DE_ASSERT(device != DE_NULL);
155 DE_ASSERT(cmdPool != DE_NULL);
156 DE_ASSERT(numCmdBuffers > 0u);
157 context.getDeviceInterface().freeCommandBuffers(device, cmdPool, numCmdBuffers, pCmdBuffers);
158 }
159
release(Context & context,VkDevice device,VkDescriptorPool descriptorPool,deUint32 numDescriptorSets,const VkDescriptorSet * pDescriptorSets)160 inline void release (Context& context, VkDevice device, VkDescriptorPool descriptorPool, deUint32 numDescriptorSets, const VkDescriptorSet* pDescriptorSets)
161 {
162 DE_ASSERT(device != DE_NULL);
163 DE_ASSERT(descriptorPool != DE_NULL);
164 DE_ASSERT(numDescriptorSets > 0u);
165 context.getDeviceInterface().freeDescriptorSets(device, descriptorPool, numDescriptorSets, pDescriptorSets);
166 }
167
168 #ifndef CTS_USES_VULKANSC
release(Context & context,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)169 inline void release (Context& context, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator)
170 {
171 context.getDeviceInterface().freeMemory(context.getDevice(), memory, pAllocator);
172 }
173 #endif // CTS_USES_VULKANSC
174
reportStatus(const bool success)175 tcu::TestStatus reportStatus (const bool success)
176 {
177 if (success)
178 return tcu::TestStatus::pass("OK: no observable change");
179 else
180 return tcu::TestStatus::fail("Implementation allocated/freed the memory");
181 }
182
183 template<typename Object>
test(Context & context)184 tcu::TestStatus test (Context& context)
185 {
186 const Object nullHandle = DE_NULL;
187 const VkAllocationCallbacks* pNullAllocator = DE_NULL;
188
189 #ifndef CTS_USES_VULKANSC
190 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
191 #endif // CTS_USES_VULKANSC
192
193 // Implementation should silently ignore a delete/free of a NULL handle.
194
195 release(context, nullHandle, pNullAllocator);
196 #ifndef CTS_USES_VULKANSC
197 // In Vulkan SC VkAllocationCallbacks must be NULL
198 release(context, nullHandle, recordingAllocator.getCallbacks());
199 return reportStatus(recordingAllocator.getNumRecords() == 0);
200 #else
201 return reportStatus(true);
202 #endif // CTS_USES_VULKANSC
203 }
204
205 template<>
test(Context & context)206 tcu::TestStatus test<VkCommandBuffer> (Context& context)
207 {
208 const DeviceInterface& vk = context.getDeviceInterface();
209 const VkDevice device = context.getDevice();
210 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
211
212 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
213 {
214 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
215 DE_NULL, // const void* pNext;
216 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
217 queueFamilyIndex, // uint32_t queueFamilyIndex;
218 };
219
220 const VkCommandBuffer pNullHandles[] = { DE_NULL, DE_NULL, DE_NULL };
221 const deUint32 numHandles = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pNullHandles));
222
223 // Default allocator
224 {
225 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo));
226
227 release(context, device, *cmdPool, numHandles, pNullHandles);
228 }
229
230 // Custom allocator
231 #ifndef CTS_USES_VULKANSC
232 {
233 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
234 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo, recordingAllocator.getCallbacks()));
235 const std::size_t numInitialRecords = recordingAllocator.getNumRecords();
236
237 release(context, device, *cmdPool, numHandles, pNullHandles);
238
239 return reportStatus(numInitialRecords == recordingAllocator.getNumRecords());
240 }
241 #else
242 return reportStatus(true);
243 #endif // CTS_USES_VULKANSC
244 }
245
checkSupportFreeDescriptorSets(Context & context)246 void checkSupportFreeDescriptorSets (Context& context)
247 {
248 #ifdef CTS_USES_VULKANSC
249 if(context.getDeviceVulkanSC10Properties().recycleDescriptorSetMemory == VK_FALSE )
250 TCU_THROW(NotSupportedError, "vkFreeDescriptorSets not supported");
251 #else
252 DE_UNREF(context);
253 #endif // CTS_USES_VULKANSC
254 }
255
256 template<>
test(Context & context)257 tcu::TestStatus test<VkDescriptorSet> (Context& context)
258 {
259 const DeviceInterface& vk = context.getDeviceInterface();
260 const VkDevice device = context.getDevice();
261
262 const VkDescriptorPoolSize pPoolSizes[] =
263 {
264 // type, descriptorCount
265 { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2u }, // arbitrary values
266 { VK_DESCRIPTOR_TYPE_SAMPLER, 1u },
267 { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3u },
268 };
269 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
270 {
271 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType;
272 DE_NULL, // const void* pNext;
273 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags;
274 2u, // uint32_t maxSets;
275 static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pPoolSizes)), // uint32_t poolSizeCount;
276 pPoolSizes, // const VkDescriptorPoolSize* pPoolSizes;
277 };
278
279 const VkDescriptorSet pNullHandles[] = { DE_NULL, DE_NULL, DE_NULL };
280 const deUint32 numHandles = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pNullHandles));
281
282 // Default allocator
283 {
284 const Unique<VkDescriptorPool> descriptorPool (createDescriptorPool(vk, device, &descriptorPoolCreateInfo));
285
286 release(context, device, *descriptorPool, numHandles, pNullHandles);
287 }
288
289 // Custom allocator
290 #ifndef CTS_USES_VULKANSC
291 {
292 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
293 const Unique<VkDescriptorPool> descriptorPool (createDescriptorPool(vk, device, &descriptorPoolCreateInfo, recordingAllocator.getCallbacks()));
294 const std::size_t numInitialRecords = recordingAllocator.getNumRecords();
295
296 release(context, device, *descriptorPool, numHandles, pNullHandles);
297
298 return reportStatus(numInitialRecords == recordingAllocator.getNumRecords());
299 }
300 #else
301 return reportStatus(true);
302 #endif // CTS_USES_VULKANSC
303 }
304
checkEventSupport(Context & context)305 void checkEventSupport (Context& context)
306 {
307 #ifndef CTS_USES_VULKANSC
308 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && !context.getPortabilitySubsetFeatures().events)
309 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation");
310 #else
311 DE_UNREF(context);
312 #endif // CTS_USES_VULKANSC
313 }
314
addTestsToGroup(tcu::TestCaseGroup * group)315 void addTestsToGroup (tcu::TestCaseGroup* group)
316 {
317 addFunctionCase(group, "destroy_buffer", "", test<VkBuffer>);
318 addFunctionCase(group, "destroy_buffer_view", "", test<VkBufferView>);
319 #ifndef CTS_USES_VULKANSC
320 // Removed from Vulkan SC test set: vkDestroyCommandPool and vkDestroyDescriptorPool command do not exist in Vulkan SC
321 addFunctionCase(group, "destroy_command_pool", "", test<VkCommandPool>);
322 addFunctionCase(group, "destroy_descriptor_pool", "", test<VkDescriptorPool>);
323 #endif // CTS_USES_VULKANSC
324 addFunctionCase(group, "destroy_descriptor_set_layout", "", test<VkDescriptorSetLayout>);
325 addFunctionCase(group, "destroy_device", "", test<VkDevice>);
326 addFunctionCase(group, "destroy_event", "", checkEventSupport, test<VkEvent>);
327 addFunctionCase(group, "destroy_fence", "", test<VkFence>);
328 addFunctionCase(group, "destroy_framebuffer", "", test<VkFramebuffer>);
329 addFunctionCase(group, "destroy_image", "", test<VkImage>);
330 addFunctionCase(group, "destroy_image_view", "", test<VkImageView>);
331 addFunctionCase(group, "destroy_instance", "", test<VkInstance>);
332 addFunctionCase(group, "destroy_pipeline", "", test<VkPipeline>);
333 addFunctionCase(group, "destroy_pipeline_cache", "", test<VkPipelineCache>);
334 addFunctionCase(group, "destroy_pipeline_layout", "", test<VkPipelineLayout>);
335 #ifndef CTS_USES_VULKANSC
336 // Removed from Vulkan SC test set: vkDestroyQueryPool command does not exist in Vulkan SC
337 addFunctionCase(group, "destroy_query_pool", "", test<VkQueryPool>);
338 #endif // CTS_USES_VULKANSC
339 addFunctionCase(group, "destroy_render_pass", "", test<VkRenderPass>);
340 addFunctionCase(group, "destroy_sampler", "", test<VkSampler>);
341 addFunctionCase(group, "destroy_semaphore", "", test<VkSemaphore>);
342 addFunctionCase(group, "destroy_shader_module", "", test<VkShaderModule>);
343 addFunctionCase(group, "free_command_buffers", "", test<VkCommandBuffer>);
344 addFunctionCase(group, "free_descriptor_sets", "", checkSupportFreeDescriptorSets, test<VkDescriptorSet>);
345 #ifndef CTS_USES_VULKANSC
346 // Removed from Vulkan SC test set: vkFreeMemory command does not exist in Vulkan SC
347 addFunctionCase(group, "free_memory", "", test<VkDeviceMemory>);
348 #endif // CTS_USES_VULKANSC
349 }
350
351 } // anonymous
352
createNullHandleTests(tcu::TestContext & testCtx)353 tcu::TestCaseGroup* createNullHandleTests (tcu::TestContext& testCtx)
354 {
355 return createTestGroup(testCtx, "null_handle", "Destroying/freeing a VK_NULL_HANDLE should be silently ignored", addTestsToGroup);
356 }
357
358 } // api
359 } // vkt
360