Add VK_NULL_HANDLE destroy/free tests
authorMaciej Jesionowski <maciej.jesionowski@mobica.com>
Fri, 16 Sep 2016 11:07:28 +0000 (13:07 +0200)
committerPyry Haulos <phaulos@google.com>
Thu, 29 Sep 2016 19:30:12 +0000 (12:30 -0700)
New tests:
- dEQP-VK.api.null_handle.*
- dEQP-VK.wsi.*.surface.destroy_null_handle
- dEQP-VK.wsi.*.swapchain.destroy.null_handle

Fixes #493

Change-Id: I44541b4d1b44ed8da2ba23e5ae9ba1106ee2c015

Android.mk
android/cts/master/vk-master.txt
external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.hpp
external/vulkancts/modules/vulkan/api/CMakeLists.txt
external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/api/vktApiTests.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
external/vulkancts/mustpass/1.0.1/vk-default.txt

index debc0eb..4a76c53 100644 (file)
@@ -727,6 +727,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp \
        external/vulkancts/modules/vulkan/api/vktApiFillBufferTests.cpp \
        external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp \
+       external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.cpp \
        external/vulkancts/modules/vulkan/api/vktApiObjectManagementTests.cpp \
        external/vulkancts/modules/vulkan/api/vktApiSmokeTests.cpp \
        external/vulkancts/modules/vulkan/api/vktApiTests.cpp \
index fc1b78a..36a8537 100644 (file)
@@ -18721,6 +18721,29 @@ dEQP-VK.api.fill_and_update_buffer.fill_buffer_second_part
 dEQP-VK.api.fill_and_update_buffer.update_buffer_second_part
 dEQP-VK.api.descriptor_pool.repeated_reset_short
 dEQP-VK.api.descriptor_pool.repeated_reset_long
+dEQP-VK.api.null_handle.destroy_buffer
+dEQP-VK.api.null_handle.destroy_buffer_view
+dEQP-VK.api.null_handle.destroy_command_pool
+dEQP-VK.api.null_handle.destroy_descriptor_pool
+dEQP-VK.api.null_handle.destroy_descriptor_set_layout
+dEQP-VK.api.null_handle.destroy_device
+dEQP-VK.api.null_handle.destroy_event
+dEQP-VK.api.null_handle.destroy_fence
+dEQP-VK.api.null_handle.destroy_framebuffer
+dEQP-VK.api.null_handle.destroy_image
+dEQP-VK.api.null_handle.destroy_image_view
+dEQP-VK.api.null_handle.destroy_instance
+dEQP-VK.api.null_handle.destroy_pipeline
+dEQP-VK.api.null_handle.destroy_pipeline_cache
+dEQP-VK.api.null_handle.destroy_pipeline_layout
+dEQP-VK.api.null_handle.destroy_query_pool
+dEQP-VK.api.null_handle.destroy_render_pass
+dEQP-VK.api.null_handle.destroy_sampler
+dEQP-VK.api.null_handle.destroy_semaphore
+dEQP-VK.api.null_handle.destroy_shader_module
+dEQP-VK.api.null_handle.free_command_buffers
+dEQP-VK.api.null_handle.free_descriptor_sets
+dEQP-VK.api.null_handle.free_memory
 dEQP-VK.memory.allocation.basic.size_64.forward.count_1
 dEQP-VK.memory.allocation.basic.size_64.forward.count_10
 dEQP-VK.memory.allocation.basic.size_64.forward.count_100
@@ -103739,6 +103762,7 @@ dEQP-VK.wsi.android.surface.query_support
 dEQP-VK.wsi.android.surface.query_capabilities
 dEQP-VK.wsi.android.surface.query_formats
 dEQP-VK.wsi.android.surface.query_present_modes
+dEQP-VK.wsi.android.surface.destroy_null_handle
 dEQP-VK.wsi.android.surface.initial_size
 dEQP-VK.wsi.android.swapchain.create.min_image_count
 dEQP-VK.wsi.android.swapchain.create.image_format
@@ -103762,6 +103786,7 @@ dEQP-VK.wsi.android.swapchain.simulate_oom.present_mode
 dEQP-VK.wsi.android.swapchain.simulate_oom.clipped
 dEQP-VK.wsi.android.swapchain.render.basic
 dEQP-VK.wsi.android.swapchain.modify.resize
+dEQP-VK.wsi.android.swapchain.destroy.null_handle
 dEQP-VK.synchronization.smoke.fences
 dEQP-VK.synchronization.smoke.semaphores
 dEQP-VK.synchronization.smoke.events
index 63cabd8..7e5dbd0 100644 (file)
@@ -147,6 +147,7 @@ public:
 
        RecordIterator                  getRecordsBegin                         (void) const { return m_records.begin();        }
        RecordIterator                  getRecordsEnd                           (void) const { return m_records.end();          }
+       std::size_t                             getNumRecords                           (void) const { return m_records.size();         }
 
 private:
        typedef de::AppendList<AllocationCallbackRecord> Records;
index 249c305..8bfda38 100644 (file)
@@ -33,6 +33,8 @@ set(DEQP_VK_API_SRCS
        vktApiFillBufferTests.hpp
        vktApiDescriptorPoolTests.cpp
        vktApiDescriptorPoolTests.hpp
+       vktApiNullHandleTests.cpp
+       vktApiNullHandleTests.hpp
        )
 
 set(DEQP_VK_API_LIBS
diff --git a/external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.cpp
new file mode 100644 (file)
index 0000000..609106e
--- /dev/null
@@ -0,0 +1,303 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Null handle tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktApiNullHandleTests.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+
+#include "vkDefs.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkAllocationCallbackUtil.hpp"
+
+namespace vkt
+{
+namespace api
+{
+namespace
+{
+
+using namespace vk;
+
+inline void release (Context& context, VkBuffer buffer, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyBuffer(context.getDevice(), buffer, pAllocator);
+}
+
+inline void release (Context& context, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyBufferView(context.getDevice(), bufferView, pAllocator);
+}
+
+inline void release (Context& context, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyCommandPool(context.getDevice(), commandPool, pAllocator);
+}
+
+inline void release (Context& context, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyDescriptorPool(context.getDevice(), descriptorPool, pAllocator);
+}
+
+inline void release (Context& context, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyDescriptorSetLayout(context.getDevice(), descriptorSetLayout, pAllocator);
+}
+
+inline void release (Context& context, VkDevice device, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyDevice(device, pAllocator);
+}
+
+inline void release (Context& context, VkEvent event, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyEvent(context.getDevice(), event, pAllocator);
+}
+
+inline void release (Context& context, VkFence fence, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyFence(context.getDevice(), fence, pAllocator);
+}
+
+inline void release (Context& context, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyFramebuffer(context.getDevice(), framebuffer, pAllocator);
+}
+
+inline void release (Context& context, VkImage image, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyImage(context.getDevice(), image, pAllocator);
+}
+
+inline void release (Context& context, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyImageView(context.getDevice(), imageView, pAllocator);
+}
+
+inline void release (Context& context, VkInstance instance, const VkAllocationCallbacks* pAllocator)
+{
+       context.getInstanceInterface().destroyInstance(instance, pAllocator);
+}
+
+inline void release (Context& context, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyPipeline(context.getDevice(), pipeline, pAllocator);
+}
+
+inline void release (Context& context, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyPipelineCache(context.getDevice(), pipelineCache, pAllocator);
+}
+
+inline void release (Context& context, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyPipelineLayout(context.getDevice(), pipelineLayout, pAllocator);
+}
+
+inline void release (Context& context, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyQueryPool(context.getDevice(), queryPool, pAllocator);
+}
+
+inline void release (Context& context, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyRenderPass(context.getDevice(), renderPass, pAllocator);
+}
+
+inline void release (Context& context, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroySampler(context.getDevice(), sampler, pAllocator);
+}
+
+inline void release (Context& context, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroySemaphore(context.getDevice(), semaphore, pAllocator);
+}
+
+inline void release (Context& context, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().destroyShaderModule(context.getDevice(), shaderModule, pAllocator);
+}
+
+inline void release (Context& context, VkDevice device, VkCommandPool cmdPool, deUint32 numCmdBuffers, const VkCommandBuffer* pCmdBuffers)
+{
+       DE_ASSERT(device                != DE_NULL);
+       DE_ASSERT(cmdPool               != DE_NULL);
+       DE_ASSERT(numCmdBuffers >  0u);
+       context.getDeviceInterface().freeCommandBuffers(device, cmdPool, numCmdBuffers, pCmdBuffers);
+}
+
+inline void release (Context& context, VkDevice device, VkDescriptorPool descriptorPool, deUint32 numDescriptorSets, const VkDescriptorSet* pDescriptorSets)
+{
+       DE_ASSERT(device                        != DE_NULL);
+       DE_ASSERT(descriptorPool        != DE_NULL);
+       DE_ASSERT(numDescriptorSets     >  0u);
+       context.getDeviceInterface().freeDescriptorSets(device, descriptorPool, numDescriptorSets, pDescriptorSets);
+}
+
+inline void release (Context& context, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator)
+{
+       context.getDeviceInterface().freeMemory(context.getDevice(), memory, pAllocator);
+}
+
+tcu::TestStatus reportStatus (const bool success)
+{
+       if (success)
+               return tcu::TestStatus::pass("OK: no observable change");
+       else
+               return tcu::TestStatus::fail("Implementation allocated/freed the memory");
+}
+
+template<typename Object>
+tcu::TestStatus test (Context& context)
+{
+       const Object                                    nullHandle                      = DE_NULL;
+       const VkAllocationCallbacks*    pNullAllocator          = DE_NULL;
+       AllocationCallbackRecorder              recordingAllocator      (getSystemAllocator(), 1u);
+
+       // Implementation should silently ignore a delete/free of a NULL handle.
+
+       release(context, nullHandle, pNullAllocator);
+       release(context, nullHandle, recordingAllocator.getCallbacks());
+
+       return reportStatus(recordingAllocator.getNumRecords() == 0);
+}
+
+template<>
+tcu::TestStatus test<VkCommandBuffer> (Context& context)
+{
+       const DeviceInterface&                  vk                                      = context.getDeviceInterface();
+       const VkDevice                                  device                          = context.getDevice();
+       const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
+
+       const VkCommandPoolCreateInfo   cmdPoolCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType             sType;
+               DE_NULL,                                                                                // const void*                 pNext;
+               VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags    flags;
+               queueFamilyIndex,                                                               // uint32_t                    queueFamilyIndex;
+       };
+
+       const VkCommandBuffer                   pNullHandles[]          = { DE_NULL, DE_NULL, DE_NULL };
+       const deUint32                                  numHandles                      = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pNullHandles));
+
+       // Default allocator
+       {
+               const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, &cmdPoolCreateInfo));
+
+               release(context, device, *cmdPool, numHandles, pNullHandles);
+       }
+
+       // Custom allocator
+       {
+               AllocationCallbackRecorder              recordingAllocator      (getSystemAllocator(), 1u);
+               const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, &cmdPoolCreateInfo, recordingAllocator.getCallbacks()));
+               const std::size_t                               numInitialRecords       = recordingAllocator.getNumRecords();
+
+               release(context, device, *cmdPool, numHandles, pNullHandles);
+
+               return reportStatus(numInitialRecords == recordingAllocator.getNumRecords());
+       }
+}
+
+template<>
+tcu::TestStatus test<VkDescriptorSet> (Context& context)
+{
+       const DeviceInterface&                          vk                                      = context.getDeviceInterface();
+       const VkDevice                                          device                          = context.getDevice();
+
+       const VkDescriptorPoolSize                      pPoolSizes[] =
+       {
+               // type, descriptorCount
+               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,    2u },   // arbitrary values
+               { VK_DESCRIPTOR_TYPE_SAMPLER,                   1u },
+               { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,             3u },
+       };
+       const VkDescriptorPoolCreateInfo        descriptorPoolCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,                          // VkStructureType                sType;
+               DE_NULL,                                                                                                        // const void*                    pNext;
+               VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,                      // VkDescriptorPoolCreateFlags    flags;
+               2u,                                                                                                                     // uint32_t                       maxSets;
+               static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pPoolSizes)),          // uint32_t                       poolSizeCount;
+               pPoolSizes,                                                                                                     // const VkDescriptorPoolSize*    pPoolSizes;
+       };
+
+       const VkDescriptorSet                           pNullHandles[]  = { DE_NULL, DE_NULL, DE_NULL };
+       const deUint32                                          numHandles              = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(pNullHandles));
+
+       // Default allocator
+       {
+               const Unique<VkDescriptorPool>  descriptorPool          (createDescriptorPool(vk, device, &descriptorPoolCreateInfo));
+
+               release(context, device, *descriptorPool, numHandles, pNullHandles);
+       }
+
+       // Custom allocator
+       {
+               AllocationCallbackRecorder              recordingAllocator      (getSystemAllocator(), 1u);
+               const Unique<VkDescriptorPool>  descriptorPool          (createDescriptorPool(vk, device, &descriptorPoolCreateInfo, recordingAllocator.getCallbacks()));
+               const std::size_t                               numInitialRecords       = recordingAllocator.getNumRecords();
+
+               release(context, device, *descriptorPool, numHandles, pNullHandles);
+
+               return reportStatus(numInitialRecords == recordingAllocator.getNumRecords());
+       }
+}
+
+void addTestsToGroup (tcu::TestCaseGroup* group)
+{
+       addFunctionCase(group,  "destroy_buffer",                                       "",             test<VkBuffer>);
+       addFunctionCase(group,  "destroy_buffer_view",                          "",             test<VkBufferView>);
+       addFunctionCase(group,  "destroy_command_pool",                         "",             test<VkCommandPool>);
+       addFunctionCase(group,  "destroy_descriptor_pool",                      "",             test<VkDescriptorPool>);
+       addFunctionCase(group,  "destroy_descriptor_set_layout",        "",             test<VkDescriptorSetLayout>);
+       addFunctionCase(group,  "destroy_device",                                       "",             test<VkDevice>);
+       addFunctionCase(group,  "destroy_event",                                        "",             test<VkEvent>);
+       addFunctionCase(group,  "destroy_fence",                                        "",             test<VkFence>);
+       addFunctionCase(group,  "destroy_framebuffer",                          "",             test<VkFramebuffer>);
+       addFunctionCase(group,  "destroy_image",                                        "",             test<VkImage>);
+       addFunctionCase(group,  "destroy_image_view",                           "",             test<VkImageView>);
+       addFunctionCase(group,  "destroy_instance",                                     "",             test<VkInstance>);
+       addFunctionCase(group,  "destroy_pipeline",                                     "",             test<VkPipeline>);
+       addFunctionCase(group,  "destroy_pipeline_cache",                       "",             test<VkPipelineCache>);
+       addFunctionCase(group,  "destroy_pipeline_layout",                      "",             test<VkPipelineLayout>);
+       addFunctionCase(group,  "destroy_query_pool",                           "",             test<VkQueryPool>);
+       addFunctionCase(group,  "destroy_render_pass",                          "",             test<VkRenderPass>);
+       addFunctionCase(group,  "destroy_sampler",                                      "",             test<VkSampler>);
+       addFunctionCase(group,  "destroy_semaphore",                            "",             test<VkSemaphore>);
+       addFunctionCase(group,  "destroy_shader_module",                        "",             test<VkShaderModule>);
+       addFunctionCase(group,  "free_command_buffers",                         "",             test<VkCommandBuffer>);
+       addFunctionCase(group,  "free_descriptor_sets",                         "",             test<VkDescriptorSet>);
+       addFunctionCase(group,  "free_memory",                                          "",             test<VkDeviceMemory>);
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createNullHandleTests (tcu::TestContext& testCtx)
+{
+       return createTestGroup(testCtx, "null_handle", "Destroying/freeing a VK_NULL_HANDLE should be silently ignored", addTestsToGroup);
+}
+
+} // api
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.hpp b/external/vulkancts/modules/vulkan/api/vktApiNullHandleTests.hpp
new file mode 100644 (file)
index 0000000..0959333
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _VKTAPINULLHANDLETESTS_HPP
+#define _VKTAPINULLHANDLETESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Null handle tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace api
+{
+
+tcu::TestCaseGroup*    createNullHandleTests   (tcu::TestContext& testCtx);
+
+} // api
+} // vkt
+
+#endif // _VKTAPINULLHANDLETESTS_HPP
index 9d97f06..a27cf1a 100644 (file)
@@ -36,6 +36,7 @@
 #include "vktApiImageClearingTests.hpp"
 #include "vktApiFillBufferTests.hpp"
 #include "vktApiDescriptorPoolTests.hpp"
+#include "vktApiNullHandleTests.hpp"
 
 namespace vkt
 {
@@ -67,7 +68,8 @@ void createApiTests (tcu::TestCaseGroup* apiTests)
        apiTests->addChild(createCopiesAndBlittingTests         (testCtx));
        apiTests->addChild(createImageClearingTests                     (testCtx));
        apiTests->addChild(createFillAndUpdateBufferTests       (testCtx));
-       apiTests->addChild(createDescriptorPoolTests(testCtx));
+       apiTests->addChild(createDescriptorPoolTests            (testCtx));
+       apiTests->addChild(createNullHandleTests                        (testCtx));
 }
 
 } // anonymous
index 701ec4b..3ea0864 100644 (file)
@@ -604,6 +604,27 @@ tcu::TestStatus resizeSurfaceTest (Context& context, Type wsiType)
        return tcu::TestStatus(results.getResult(), results.getMessage());
 }
 
+tcu::TestStatus destroyNullHandleSurfaceTest (Context& context, Type wsiType)
+{
+       const InstanceHelper    instHelper      (context, wsiType);
+       const VkSurfaceKHR              nullHandle      = DE_NULL;
+
+       // Default allocator
+       instHelper.vki.destroySurfaceKHR(*instHelper.instance, nullHandle, DE_NULL);
+
+       // Custom allocator
+       {
+               AllocationCallbackRecorder      recordingAllocator      (getSystemAllocator(), 1u);
+
+               instHelper.vki.destroySurfaceKHR(*instHelper.instance, nullHandle, recordingAllocator.getCallbacks());
+
+               if (recordingAllocator.getNumRecords() != 0u)
+                       return tcu::TestStatus::fail("Implementation allocated/freed the memory");
+       }
+
+       return tcu::TestStatus::pass("Destroying a VK_NULL_HANDLE surface has no effect");
+}
+
 } // anonymous
 
 void createSurfaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
@@ -617,6 +638,7 @@ void createSurfaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
        addFunctionCase(testGroup, "query_capabilities",                "Query surface capabilities",                   querySurfaceCapabilitiesTest,           wsiType);
        addFunctionCase(testGroup, "query_formats",                             "Query surface formats",                                querySurfaceFormatsTest,                        wsiType);
        addFunctionCase(testGroup, "query_present_modes",               "Query surface present modes",                  querySurfacePresentModesTest,           wsiType);
+       addFunctionCase(testGroup, "destroy_null_handle",               "Destroy VK_NULL_HANDLE surface",               destroyNullHandleSurfaceTest,           wsiType);
 
        if ((platformProperties.features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE) != 0)
                addFunctionCase(testGroup, "initial_size",      "Create surface with initial window size set",  createSurfaceInitialSizeTest,   wsiType);
index 4eb92f5..506f598 100644 (file)
@@ -1675,6 +1675,30 @@ tcu::TestStatus resizeSwapchainTest (Context& context, Type wsiType)
        return tcu::TestStatus::pass("Resizing tests suceeded");
 }
 
+tcu::TestStatus destroyNullHandleSwapchainTest (Context& context, Type wsiType)
+{
+       const InstanceHelper            instHelper      (context, wsiType);
+       const NativeObjects                     native          (context, instHelper.supportedExtensions, wsiType);
+       const Unique<VkSurfaceKHR>      surface         (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
+       const DeviceHelper                      devHelper       (context, instHelper.vki, *instHelper.instance, *surface);
+       const VkSwapchainKHR            nullHandle      = DE_NULL;
+
+       // Default allocator
+       devHelper.vkd.destroySwapchainKHR(*devHelper.device, nullHandle, DE_NULL);
+
+       // Custom allocator
+       {
+               AllocationCallbackRecorder      recordingAllocator      (getSystemAllocator(), 1u);
+
+               devHelper.vkd.destroySwapchainKHR(*devHelper.device, nullHandle, recordingAllocator.getCallbacks());
+
+               if (recordingAllocator.getNumRecords() != 0u)
+                       return tcu::TestStatus::fail("Implementation allocated/freed the memory");
+       }
+
+       return tcu::TestStatus::pass("Destroying a VK_NULL_HANDLE surface has no effect");
+}
+
 void getBasicRenderPrograms (SourceCollections& dst, Type)
 {
        TriangleRenderer::getPrograms(dst);
@@ -1697,6 +1721,11 @@ void populateModifyGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
        // \todo [2016-05-30 jesse] Add tests for modifying preTransform, compositeAlpha, presentMode
 }
 
+void populateDestroyGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
+{
+       addFunctionCase(testGroup, "null_handle", "Destroying a VK_NULL_HANDLE swapchain", destroyNullHandleSwapchainTest, wsiType);
+}
+
 } // anonymous
 
 void createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
@@ -1705,6 +1734,7 @@ void createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
        addTestGroup(testGroup, "simulate_oom",         "Simulate OOM using callbacks during swapchain construction",   populateSwapchainOOMGroup,      wsiType);
        addTestGroup(testGroup, "render",                       "Rendering Tests",                                                                                              populateRenderGroup,            wsiType);
        addTestGroup(testGroup, "modify",                       "Modify VkSwapchain",                                                                                   populateModifyGroup,            wsiType);
+       addTestGroup(testGroup, "destroy",                      "Destroy VkSwapchain",                                                                                  populateDestroyGroup,           wsiType);
 }
 
 } // wsi
index ef8688a..81d0a8d 100644 (file)
@@ -12576,6 +12576,29 @@ dEQP-VK.api.fill_and_update_buffer.fill_buffer_second_part
 dEQP-VK.api.fill_and_update_buffer.update_buffer_second_part
 dEQP-VK.api.descriptor_pool.repeated_reset_short
 dEQP-VK.api.descriptor_pool.repeated_reset_long
+dEQP-VK.api.null_handle.destroy_buffer
+dEQP-VK.api.null_handle.destroy_buffer_view
+dEQP-VK.api.null_handle.destroy_command_pool
+dEQP-VK.api.null_handle.destroy_descriptor_pool
+dEQP-VK.api.null_handle.destroy_descriptor_set_layout
+dEQP-VK.api.null_handle.destroy_device
+dEQP-VK.api.null_handle.destroy_event
+dEQP-VK.api.null_handle.destroy_fence
+dEQP-VK.api.null_handle.destroy_framebuffer
+dEQP-VK.api.null_handle.destroy_image
+dEQP-VK.api.null_handle.destroy_image_view
+dEQP-VK.api.null_handle.destroy_instance
+dEQP-VK.api.null_handle.destroy_pipeline
+dEQP-VK.api.null_handle.destroy_pipeline_cache
+dEQP-VK.api.null_handle.destroy_pipeline_layout
+dEQP-VK.api.null_handle.destroy_query_pool
+dEQP-VK.api.null_handle.destroy_render_pass
+dEQP-VK.api.null_handle.destroy_sampler
+dEQP-VK.api.null_handle.destroy_semaphore
+dEQP-VK.api.null_handle.destroy_shader_module
+dEQP-VK.api.null_handle.free_command_buffers
+dEQP-VK.api.null_handle.free_descriptor_sets
+dEQP-VK.api.null_handle.free_memory
 dEQP-VK.memory.allocation.basic.size_64.forward.count_1
 dEQP-VK.memory.allocation.basic.size_64.forward.count_10
 dEQP-VK.memory.allocation.basic.size_64.forward.count_100
@@ -97308,6 +97331,7 @@ dEQP-VK.wsi.xlib.surface.query_support
 dEQP-VK.wsi.xlib.surface.query_capabilities
 dEQP-VK.wsi.xlib.surface.query_formats
 dEQP-VK.wsi.xlib.surface.query_present_modes
+dEQP-VK.wsi.xlib.surface.destroy_null_handle
 dEQP-VK.wsi.xlib.surface.initial_size
 dEQP-VK.wsi.xlib.surface.resize
 dEQP-VK.wsi.xlib.swapchain.create.min_image_count
@@ -97331,6 +97355,7 @@ dEQP-VK.wsi.xlib.swapchain.simulate_oom.composite_alpha
 dEQP-VK.wsi.xlib.swapchain.simulate_oom.present_mode
 dEQP-VK.wsi.xlib.swapchain.simulate_oom.clipped
 dEQP-VK.wsi.xlib.swapchain.render.basic
+dEQP-VK.wsi.xlib.swapchain.destroy.null_handle
 dEQP-VK.wsi.xcb.surface.create
 dEQP-VK.wsi.xcb.surface.create_custom_allocator
 dEQP-VK.wsi.xcb.surface.create_simulate_oom
@@ -97338,6 +97363,7 @@ dEQP-VK.wsi.xcb.surface.query_support
 dEQP-VK.wsi.xcb.surface.query_capabilities
 dEQP-VK.wsi.xcb.surface.query_formats
 dEQP-VK.wsi.xcb.surface.query_present_modes
+dEQP-VK.wsi.xcb.surface.destroy_null_handle
 dEQP-VK.wsi.xcb.surface.initial_size
 dEQP-VK.wsi.xcb.surface.resize
 dEQP-VK.wsi.xcb.swapchain.create.min_image_count
@@ -97361,6 +97387,7 @@ dEQP-VK.wsi.xcb.swapchain.simulate_oom.composite_alpha
 dEQP-VK.wsi.xcb.swapchain.simulate_oom.present_mode
 dEQP-VK.wsi.xcb.swapchain.simulate_oom.clipped
 dEQP-VK.wsi.xcb.swapchain.render.basic
+dEQP-VK.wsi.xcb.swapchain.destroy.null_handle
 dEQP-VK.wsi.wayland.surface.create
 dEQP-VK.wsi.wayland.surface.create_custom_allocator
 dEQP-VK.wsi.wayland.surface.create_simulate_oom
@@ -97368,6 +97395,7 @@ dEQP-VK.wsi.wayland.surface.query_support
 dEQP-VK.wsi.wayland.surface.query_capabilities
 dEQP-VK.wsi.wayland.surface.query_formats
 dEQP-VK.wsi.wayland.surface.query_present_modes
+dEQP-VK.wsi.wayland.surface.destroy_null_handle
 dEQP-VK.wsi.wayland.swapchain.create.min_image_count
 dEQP-VK.wsi.wayland.swapchain.create.image_format
 dEQP-VK.wsi.wayland.swapchain.create.image_extent
@@ -97390,6 +97418,7 @@ dEQP-VK.wsi.wayland.swapchain.simulate_oom.present_mode
 dEQP-VK.wsi.wayland.swapchain.simulate_oom.clipped
 dEQP-VK.wsi.wayland.swapchain.render.basic
 dEQP-VK.wsi.wayland.swapchain.modify.resize
+dEQP-VK.wsi.wayland.swapchain.destroy.null_handle
 dEQP-VK.wsi.mir.surface.create
 dEQP-VK.wsi.mir.surface.create_custom_allocator
 dEQP-VK.wsi.mir.surface.create_simulate_oom
@@ -97397,6 +97426,7 @@ dEQP-VK.wsi.mir.surface.query_support
 dEQP-VK.wsi.mir.surface.query_capabilities
 dEQP-VK.wsi.mir.surface.query_formats
 dEQP-VK.wsi.mir.surface.query_present_modes
+dEQP-VK.wsi.mir.surface.destroy_null_handle
 dEQP-VK.wsi.mir.surface.initial_size
 dEQP-VK.wsi.mir.surface.resize
 dEQP-VK.wsi.mir.swapchain.create.min_image_count
@@ -97421,6 +97451,7 @@ dEQP-VK.wsi.mir.swapchain.simulate_oom.present_mode
 dEQP-VK.wsi.mir.swapchain.simulate_oom.clipped
 dEQP-VK.wsi.mir.swapchain.render.basic
 dEQP-VK.wsi.mir.swapchain.modify.resize
+dEQP-VK.wsi.mir.swapchain.destroy.null_handle
 dEQP-VK.wsi.android.surface.create
 dEQP-VK.wsi.android.surface.create_custom_allocator
 dEQP-VK.wsi.android.surface.create_simulate_oom
@@ -97428,6 +97459,7 @@ dEQP-VK.wsi.android.surface.query_support
 dEQP-VK.wsi.android.surface.query_capabilities
 dEQP-VK.wsi.android.surface.query_formats
 dEQP-VK.wsi.android.surface.query_present_modes
+dEQP-VK.wsi.android.surface.destroy_null_handle
 dEQP-VK.wsi.android.surface.initial_size
 dEQP-VK.wsi.android.swapchain.create.min_image_count
 dEQP-VK.wsi.android.swapchain.create.image_format
@@ -97451,6 +97483,7 @@ dEQP-VK.wsi.android.swapchain.simulate_oom.present_mode
 dEQP-VK.wsi.android.swapchain.simulate_oom.clipped
 dEQP-VK.wsi.android.swapchain.render.basic
 dEQP-VK.wsi.android.swapchain.modify.resize
+dEQP-VK.wsi.android.swapchain.destroy.null_handle
 dEQP-VK.wsi.win32.surface.create
 dEQP-VK.wsi.win32.surface.create_custom_allocator
 dEQP-VK.wsi.win32.surface.create_simulate_oom
@@ -97458,6 +97491,7 @@ dEQP-VK.wsi.win32.surface.query_support
 dEQP-VK.wsi.win32.surface.query_capabilities
 dEQP-VK.wsi.win32.surface.query_formats
 dEQP-VK.wsi.win32.surface.query_present_modes
+dEQP-VK.wsi.win32.surface.destroy_null_handle
 dEQP-VK.wsi.win32.surface.initial_size
 dEQP-VK.wsi.win32.surface.resize
 dEQP-VK.wsi.win32.swapchain.create.min_image_count
@@ -97481,6 +97515,7 @@ dEQP-VK.wsi.win32.swapchain.simulate_oom.composite_alpha
 dEQP-VK.wsi.win32.swapchain.simulate_oom.present_mode
 dEQP-VK.wsi.win32.swapchain.simulate_oom.clipped
 dEQP-VK.wsi.win32.swapchain.render.basic
+dEQP-VK.wsi.win32.swapchain.destroy.null_handle
 dEQP-VK.synchronization.smoke.fences
 dEQP-VK.synchronization.smoke.semaphores
 dEQP-VK.synchronization.smoke.events