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
release(Context & context,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)52 inline void release (Context& context, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator)
53 {
54 context.getDeviceInterface().destroyCommandPool(context.getDevice(), commandPool, pAllocator);
55 }
56
release(Context & context,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)57 inline void release (Context& context, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator)
58 {
59 context.getDeviceInterface().destroyDescriptorPool(context.getDevice(), descriptorPool, pAllocator);
60 }
61
release(Context & context,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)62 inline void release (Context& context, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator)
63 {
64 context.getDeviceInterface().destroyDescriptorSetLayout(context.getDevice(), descriptorSetLayout, pAllocator);
65 }
66
release(Context & context,VkDevice device,const VkAllocationCallbacks * pAllocator)67 inline void release (Context& context, VkDevice device, const VkAllocationCallbacks* pAllocator)
68 {
69 context.getDeviceInterface().destroyDevice(device, pAllocator);
70 }
71
release(Context & context,VkEvent event,const VkAllocationCallbacks * pAllocator)72 inline void release (Context& context, VkEvent event, const VkAllocationCallbacks* pAllocator)
73 {
74 context.getDeviceInterface().destroyEvent(context.getDevice(), event, pAllocator);
75 }
76
release(Context & context,VkFence fence,const VkAllocationCallbacks * pAllocator)77 inline void release (Context& context, VkFence fence, const VkAllocationCallbacks* pAllocator)
78 {
79 context.getDeviceInterface().destroyFence(context.getDevice(), fence, pAllocator);
80 }
81
release(Context & context,VkFramebuffer framebuffer,const VkAllocationCallbacks * pAllocator)82 inline void release (Context& context, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator)
83 {
84 context.getDeviceInterface().destroyFramebuffer(context.getDevice(), framebuffer, pAllocator);
85 }
86
release(Context & context,VkImage image,const VkAllocationCallbacks * pAllocator)87 inline void release (Context& context, VkImage image, const VkAllocationCallbacks* pAllocator)
88 {
89 context.getDeviceInterface().destroyImage(context.getDevice(), image, pAllocator);
90 }
91
release(Context & context,VkImageView imageView,const VkAllocationCallbacks * pAllocator)92 inline void release (Context& context, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
93 {
94 context.getDeviceInterface().destroyImageView(context.getDevice(), imageView, pAllocator);
95 }
96
release(Context & context,VkInstance instance,const VkAllocationCallbacks * pAllocator)97 inline void release (Context& context, VkInstance instance, const VkAllocationCallbacks* pAllocator)
98 {
99 context.getInstanceInterface().destroyInstance(instance, pAllocator);
100 }
101
release(Context & context,VkPipeline pipeline,const VkAllocationCallbacks * pAllocator)102 inline void release (Context& context, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
103 {
104 context.getDeviceInterface().destroyPipeline(context.getDevice(), pipeline, pAllocator);
105 }
106
release(Context & context,VkPipelineCache pipelineCache,const VkAllocationCallbacks * pAllocator)107 inline void release (Context& context, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
108 {
109 context.getDeviceInterface().destroyPipelineCache(context.getDevice(), pipelineCache, pAllocator);
110 }
111
release(Context & context,VkPipelineLayout pipelineLayout,const VkAllocationCallbacks * pAllocator)112 inline void release (Context& context, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
113 {
114 context.getDeviceInterface().destroyPipelineLayout(context.getDevice(), pipelineLayout, pAllocator);
115 }
116
release(Context & context,VkQueryPool queryPool,const VkAllocationCallbacks * pAllocator)117 inline void release (Context& context, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator)
118 {
119 context.getDeviceInterface().destroyQueryPool(context.getDevice(), queryPool, pAllocator);
120 }
121
release(Context & context,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)122 inline void release (Context& context, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
123 {
124 context.getDeviceInterface().destroyRenderPass(context.getDevice(), renderPass, pAllocator);
125 }
126
release(Context & context,VkSampler sampler,const VkAllocationCallbacks * pAllocator)127 inline void release (Context& context, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
128 {
129 context.getDeviceInterface().destroySampler(context.getDevice(), sampler, pAllocator);
130 }
131
release(Context & context,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)132 inline void release (Context& context, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
133 {
134 context.getDeviceInterface().destroySemaphore(context.getDevice(), semaphore, pAllocator);
135 }
136
release(Context & context,VkShaderModule shaderModule,const VkAllocationCallbacks * pAllocator)137 inline void release (Context& context, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator)
138 {
139 context.getDeviceInterface().destroyShaderModule(context.getDevice(), shaderModule, pAllocator);
140 }
141
release(Context & context,VkDevice device,VkCommandPool cmdPool,deUint32 numCmdBuffers,const VkCommandBuffer * pCmdBuffers)142 inline void release (Context& context, VkDevice device, VkCommandPool cmdPool, deUint32 numCmdBuffers, const VkCommandBuffer* pCmdBuffers)
143 {
144 DE_ASSERT(device != DE_NULL);
145 DE_ASSERT(cmdPool != DE_NULL);
146 DE_ASSERT(numCmdBuffers > 0u);
147 context.getDeviceInterface().freeCommandBuffers(device, cmdPool, numCmdBuffers, pCmdBuffers);
148 }
149
release(Context & context,VkDevice device,VkDescriptorPool descriptorPool,deUint32 numDescriptorSets,const VkDescriptorSet * pDescriptorSets)150 inline void release (Context& context, VkDevice device, VkDescriptorPool descriptorPool, deUint32 numDescriptorSets, const VkDescriptorSet* pDescriptorSets)
151 {
152 DE_ASSERT(device != DE_NULL);
153 DE_ASSERT(descriptorPool != DE_NULL);
154 DE_ASSERT(numDescriptorSets > 0u);
155 context.getDeviceInterface().freeDescriptorSets(device, descriptorPool, numDescriptorSets, pDescriptorSets);
156 }
157
release(Context & context,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)158 inline void release (Context& context, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator)
159 {
160 context.getDeviceInterface().freeMemory(context.getDevice(), memory, pAllocator);
161 }
162
reportStatus(const bool success)163 tcu::TestStatus reportStatus (const bool success)
164 {
165 if (success)
166 return tcu::TestStatus::pass("OK: no observable change");
167 else
168 return tcu::TestStatus::fail("Implementation allocated/freed the memory");
169 }
170
171 template<typename Object>
test(Context & context)172 tcu::TestStatus test (Context& context)
173 {
174 const Object nullHandle = DE_NULL;
175 const VkAllocationCallbacks* pNullAllocator = DE_NULL;
176 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
177
178 // Implementation should silently ignore a delete/free of a NULL handle.
179
180 release(context, nullHandle, pNullAllocator);
181 release(context, nullHandle, recordingAllocator.getCallbacks());
182
183 return reportStatus(recordingAllocator.getNumRecords() == 0);
184 }
185
186 template<>
test(Context & context)187 tcu::TestStatus test<VkCommandBuffer> (Context& context)
188 {
189 const DeviceInterface& vk = context.getDeviceInterface();
190 const VkDevice device = context.getDevice();
191 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
192
193 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
194 {
195 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
196 DE_NULL, // const void* pNext;
197 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
198 queueFamilyIndex, // uint32_t queueFamilyIndex;
199 };
200
201 const VkCommandBuffer pNullHandles[] = { DE_NULL, DE_NULL, DE_NULL };
202 const deUint32 numHandles = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pNullHandles));
203
204 // Default allocator
205 {
206 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo));
207
208 release(context, device, *cmdPool, numHandles, pNullHandles);
209 }
210
211 // Custom allocator
212 {
213 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
214 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo, recordingAllocator.getCallbacks()));
215 const std::size_t numInitialRecords = recordingAllocator.getNumRecords();
216
217 release(context, device, *cmdPool, numHandles, pNullHandles);
218
219 return reportStatus(numInitialRecords == recordingAllocator.getNumRecords());
220 }
221 }
222
223 template<>
test(Context & context)224 tcu::TestStatus test<VkDescriptorSet> (Context& context)
225 {
226 const DeviceInterface& vk = context.getDeviceInterface();
227 const VkDevice device = context.getDevice();
228
229 const VkDescriptorPoolSize pPoolSizes[] =
230 {
231 // type, descriptorCount
232 { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2u }, // arbitrary values
233 { VK_DESCRIPTOR_TYPE_SAMPLER, 1u },
234 { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3u },
235 };
236 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
237 {
238 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType;
239 DE_NULL, // const void* pNext;
240 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags;
241 2u, // uint32_t maxSets;
242 static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pPoolSizes)), // uint32_t poolSizeCount;
243 pPoolSizes, // const VkDescriptorPoolSize* pPoolSizes;
244 };
245
246 const VkDescriptorSet pNullHandles[] = { DE_NULL, DE_NULL, DE_NULL };
247 const deUint32 numHandles = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pNullHandles));
248
249 // Default allocator
250 {
251 const Unique<VkDescriptorPool> descriptorPool (createDescriptorPool(vk, device, &descriptorPoolCreateInfo));
252
253 release(context, device, *descriptorPool, numHandles, pNullHandles);
254 }
255
256 // Custom allocator
257 {
258 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
259 const Unique<VkDescriptorPool> descriptorPool (createDescriptorPool(vk, device, &descriptorPoolCreateInfo, recordingAllocator.getCallbacks()));
260 const std::size_t numInitialRecords = recordingAllocator.getNumRecords();
261
262 release(context, device, *descriptorPool, numHandles, pNullHandles);
263
264 return reportStatus(numInitialRecords == recordingAllocator.getNumRecords());
265 }
266 }
267
addTestsToGroup(tcu::TestCaseGroup * group)268 void addTestsToGroup (tcu::TestCaseGroup* group)
269 {
270 addFunctionCase(group, "destroy_buffer", "", test<VkBuffer>);
271 addFunctionCase(group, "destroy_buffer_view", "", test<VkBufferView>);
272 addFunctionCase(group, "destroy_command_pool", "", test<VkCommandPool>);
273 addFunctionCase(group, "destroy_descriptor_pool", "", test<VkDescriptorPool>);
274 addFunctionCase(group, "destroy_descriptor_set_layout", "", test<VkDescriptorSetLayout>);
275 addFunctionCase(group, "destroy_device", "", test<VkDevice>);
276 addFunctionCase(group, "destroy_event", "", test<VkEvent>);
277 addFunctionCase(group, "destroy_fence", "", test<VkFence>);
278 addFunctionCase(group, "destroy_framebuffer", "", test<VkFramebuffer>);
279 addFunctionCase(group, "destroy_image", "", test<VkImage>);
280 addFunctionCase(group, "destroy_image_view", "", test<VkImageView>);
281 addFunctionCase(group, "destroy_instance", "", test<VkInstance>);
282 addFunctionCase(group, "destroy_pipeline", "", test<VkPipeline>);
283 addFunctionCase(group, "destroy_pipeline_cache", "", test<VkPipelineCache>);
284 addFunctionCase(group, "destroy_pipeline_layout", "", test<VkPipelineLayout>);
285 addFunctionCase(group, "destroy_query_pool", "", test<VkQueryPool>);
286 addFunctionCase(group, "destroy_render_pass", "", test<VkRenderPass>);
287 addFunctionCase(group, "destroy_sampler", "", test<VkSampler>);
288 addFunctionCase(group, "destroy_semaphore", "", test<VkSemaphore>);
289 addFunctionCase(group, "destroy_shader_module", "", test<VkShaderModule>);
290 addFunctionCase(group, "free_command_buffers", "", test<VkCommandBuffer>);
291 addFunctionCase(group, "free_descriptor_sets", "", test<VkDescriptorSet>);
292 addFunctionCase(group, "free_memory", "", test<VkDeviceMemory>);
293 }
294
295 } // anonymous
296
createNullHandleTests(tcu::TestContext & testCtx)297 tcu::TestCaseGroup* createNullHandleTests (tcu::TestContext& testCtx)
298 {
299 return createTestGroup(testCtx, "null_handle", "Destroying/freeing a VK_NULL_HANDLE should be silently ignored", addTestsToGroup);
300 }
301
302 } // api
303 } // vkt
304