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 33namespace vkt 34{ 35namespace api 36{ 37namespace 38{ 39 40using namespace vk; 41 42inline void release (Context& context, VkBuffer buffer, const VkAllocationCallbacks* pAllocator) 43{ 44 context.getDeviceInterface().destroyBuffer(context.getDevice(), buffer, pAllocator); 45} 46 47inline 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 53inline void release (Context& context, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator) 54{ 55 context.getDeviceInterface().destroyCommandPool(context.getDevice(), commandPool, pAllocator); 56} 57 58inline 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 64inline void release (Context& context, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator) 65{ 66 context.getDeviceInterface().destroyDescriptorSetLayout(context.getDevice(), descriptorSetLayout, pAllocator); 67} 68 69inline void release (Context& context, VkDevice device, const VkAllocationCallbacks* pAllocator) 70{ 71 context.getDeviceInterface().destroyDevice(device, pAllocator); 72} 73 74inline void release (Context& context, VkEvent event, const VkAllocationCallbacks* pAllocator) 75{ 76 context.getDeviceInterface().destroyEvent(context.getDevice(), event, pAllocator); 77} 78 79inline void release (Context& context, VkFence fence, const VkAllocationCallbacks* pAllocator) 80{ 81 context.getDeviceInterface().destroyFence(context.getDevice(), fence, pAllocator); 82} 83 84inline void release (Context& context, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator) 85{ 86 context.getDeviceInterface().destroyFramebuffer(context.getDevice(), framebuffer, pAllocator); 87} 88 89inline void release (Context& context, VkImage image, const VkAllocationCallbacks* pAllocator) 90{ 91 context.getDeviceInterface().destroyImage(context.getDevice(), image, pAllocator); 92} 93 94inline void release (Context& context, VkImageView imageView, const VkAllocationCallbacks* pAllocator) 95{ 96 context.getDeviceInterface().destroyImageView(context.getDevice(), imageView, pAllocator); 97} 98 99inline void release (Context& context, VkInstance instance, const VkAllocationCallbacks* pAllocator) 100{ 101 context.getInstanceInterface().destroyInstance(instance, pAllocator); 102} 103 104inline void release (Context& context, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator) 105{ 106 context.getDeviceInterface().destroyPipeline(context.getDevice(), pipeline, pAllocator); 107} 108 109inline void release (Context& context, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator) 110{ 111 context.getDeviceInterface().destroyPipelineCache(context.getDevice(), pipelineCache, pAllocator); 112} 113 114inline 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 120inline 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 126inline void release (Context& context, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator) 127{ 128 context.getDeviceInterface().destroyRenderPass(context.getDevice(), renderPass, pAllocator); 129} 130 131inline void release (Context& context, VkSampler sampler, const VkAllocationCallbacks* pAllocator) 132{ 133 context.getDeviceInterface().destroySampler(context.getDevice(), sampler, pAllocator); 134} 135 136inline void release (Context& context, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator) 137{ 138 context.getDeviceInterface().destroySemaphore(context.getDevice(), semaphore, pAllocator); 139} 140 141inline 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 152inline 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 160inline 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 169inline 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 175tcu::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 183template<typename Object> 184tcu::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 205template<> 206tcu::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 246void 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 256template<> 257tcu::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 305void 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 315void 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 353tcu::TestCaseGroup* createNullHandleTests (tcu::TestContext& testCtx) 354{ 355 // Destroying/freeing a VK_NULL_HANDLE should be silently ignored 356 return createTestGroup(testCtx, "null_handle", addTestsToGroup); 357} 358 359} // api 360} // vkt 361