• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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