Home | History | Annotate | Download | only in api
      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 
     42 inline void release (Context& context, VkBuffer buffer, const VkAllocationCallbacks* pAllocator)
     43 {
     44 	context.getDeviceInterface().destroyBuffer(context.getDevice(), buffer, pAllocator);
     45 }
     46 
     47 inline void release (Context& context, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)
     48 {
     49 	context.getDeviceInterface().destroyBufferView(context.getDevice(), bufferView, pAllocator);
     50 }
     51 
     52 inline void release (Context& context, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator)
     53 {
     54 	context.getDeviceInterface().destroyCommandPool(context.getDevice(), commandPool, pAllocator);
     55 }
     56 
     57 inline void release (Context& context, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator)
     58 {
     59 	context.getDeviceInterface().destroyDescriptorPool(context.getDevice(), descriptorPool, pAllocator);
     60 }
     61 
     62 inline void release (Context& context, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator)
     63 {
     64 	context.getDeviceInterface().destroyDescriptorSetLayout(context.getDevice(), descriptorSetLayout, pAllocator);
     65 }
     66 
     67 inline void release (Context& context, VkDevice device, const VkAllocationCallbacks* pAllocator)
     68 {
     69 	context.getDeviceInterface().destroyDevice(device, pAllocator);
     70 }
     71 
     72 inline void release (Context& context, VkEvent event, const VkAllocationCallbacks* pAllocator)
     73 {
     74 	context.getDeviceInterface().destroyEvent(context.getDevice(), event, pAllocator);
     75 }
     76 
     77 inline void release (Context& context, VkFence fence, const VkAllocationCallbacks* pAllocator)
     78 {
     79 	context.getDeviceInterface().destroyFence(context.getDevice(), fence, pAllocator);
     80 }
     81 
     82 inline void release (Context& context, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator)
     83 {
     84 	context.getDeviceInterface().destroyFramebuffer(context.getDevice(), framebuffer, pAllocator);
     85 }
     86 
     87 inline void release (Context& context, VkImage image, const VkAllocationCallbacks* pAllocator)
     88 {
     89 	context.getDeviceInterface().destroyImage(context.getDevice(), image, pAllocator);
     90 }
     91 
     92 inline void release (Context& context, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
     93 {
     94 	context.getDeviceInterface().destroyImageView(context.getDevice(), imageView, pAllocator);
     95 }
     96 
     97 inline void release (Context& context, VkInstance instance, const VkAllocationCallbacks* pAllocator)
     98 {
     99 	context.getInstanceInterface().destroyInstance(instance, pAllocator);
    100 }
    101 
    102 inline void release (Context& context, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
    103 {
    104 	context.getDeviceInterface().destroyPipeline(context.getDevice(), pipeline, pAllocator);
    105 }
    106 
    107 inline void release (Context& context, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
    108 {
    109 	context.getDeviceInterface().destroyPipelineCache(context.getDevice(), pipelineCache, pAllocator);
    110 }
    111 
    112 inline void release (Context& context, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
    113 {
    114 	context.getDeviceInterface().destroyPipelineLayout(context.getDevice(), pipelineLayout, pAllocator);
    115 }
    116 
    117 inline void release (Context& context, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator)
    118 {
    119 	context.getDeviceInterface().destroyQueryPool(context.getDevice(), queryPool, pAllocator);
    120 }
    121 
    122 inline void release (Context& context, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
    123 {
    124 	context.getDeviceInterface().destroyRenderPass(context.getDevice(), renderPass, pAllocator);
    125 }
    126 
    127 inline void release (Context& context, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
    128 {
    129 	context.getDeviceInterface().destroySampler(context.getDevice(), sampler, pAllocator);
    130 }
    131 
    132 inline void release (Context& context, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
    133 {
    134 	context.getDeviceInterface().destroySemaphore(context.getDevice(), semaphore, pAllocator);
    135 }
    136 
    137 inline void release (Context& context, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator)
    138 {
    139 	context.getDeviceInterface().destroyShaderModule(context.getDevice(), shaderModule, pAllocator);
    140 }
    141 
    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 
    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 
    158 inline void release (Context& context, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator)
    159 {
    160 	context.getDeviceInterface().freeMemory(context.getDevice(), memory, pAllocator);
    161 }
    162 
    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>
    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<>
    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<>
    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 
    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 
    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