Add test for vkResetDescriptorPool memory leak
authorCollin Baker <collinbaker@google.com>
Tue, 24 May 2016 20:50:43 +0000 (13:50 -0700)
committerCollin Baker <collinbaker@google.com>
Wed, 25 May 2016 22:03:31 +0000 (15:03 -0700)
New test runs vkAllocateDescriptorSets then vkResetDescriptorPool
repeatedly to check for memory leak. Contains two cases; one that runs
only 2 cycles and should always pass, and one that runs 256 cycles and
should crash if a memory leak exists.

Bug: 28793498
Change-Id: I864bae72ab957bd64042f9023d694a5ae33b13dd

Android.mk
android/cts/master/com.drawelements.deqp.vk.xml
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/api/CMakeLists.txt
external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/api/vktApiTests.cpp

index 46342fc..95409ad 100644 (file)
@@ -700,6 +700,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp \
        external/vulkancts/modules/vulkan/api/vktApiComputeInstanceResultBuffer.cpp \
        external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp \
+       external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.cpp \
        external/vulkancts/modules/vulkan/api/vktApiDeviceInitializationTests.cpp \
        external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp \
        external/vulkancts/modules/vulkan/api/vktApiFillBufferTests.cpp \
index c4c89c5..8ef1ba1 100644 (file)
                                        <TestInstance/>
                                </Test>
                        </TestCase>
+                       <TestCase name="descriptor_pool">
+                               <Test name="repeated_reset_short">
+                                       <TestInstance/>
+                               </Test>
+                               <Test name="repeated_reset_long">
+                                       <TestInstance/>
+                               </Test>
+                       </TestCase>
                </TestSuite>
                <TestSuite name="pipeline">
                        <TestSuite name="stencil">
index 0986a28..6515d34 100644 (file)
@@ -4509,6 +4509,8 @@ dEQP-VK.api.fill_and_update_buffer.fill_buffer_second_one
 dEQP-VK.api.fill_and_update_buffer.update_buffer_second_one
 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.pipeline.stencil.format.s8_uint.states.front_fail_decc_pass_repl_dfail_inv_comp_not_equal_back_fail_decc_pass_repl_dfail_keep_comp_less
 dEQP-VK.pipeline.stencil.format.s8_uint.states.front_fail_incc_pass_keep_dfail_inv_comp_not_equal_back_fail_decc_pass_repl_dfail_inv_comp_not_equal
 dEQP-VK.pipeline.stencil.format.s8_uint.states.front_fail_wrap_pass_decw_dfail_wrap_comp_less_back_fail_incc_pass_keep_dfail_inv_comp_not_equal
index 9c7f9d9..249c305 100644 (file)
@@ -31,6 +31,8 @@ set(DEQP_VK_API_SRCS
        vktApiImageClearingTests.hpp
        vktApiFillBufferTests.cpp
        vktApiFillBufferTests.hpp
+       vktApiDescriptorPoolTests.cpp
+       vktApiDescriptorPoolTests.hpp
        )
 
 set(DEQP_VK_API_LIBS
diff --git a/external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.cpp
new file mode 100644 (file)
index 0000000..792142c
--- /dev/null
@@ -0,0 +1,195 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google 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 Descriptor pool tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktApiDescriptorPoolTests.hpp"
+#include "vktTestCaseUtil.hpp"
+
+#include "vkDefs.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkDeviceUtil.hpp"
+#include "vkAllocationCallbackUtil.hpp"
+
+#include "tcuCommandLine.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuPlatform.hpp"
+
+#include "deUniquePtr.hpp"
+#include "deSharedPtr.hpp"
+#include "deInt32.h"
+
+namespace vkt
+{
+namespace api
+{
+
+namespace
+{
+
+using namespace std;
+using namespace vk;
+
+size_t checkAndLogMemoryUsage (tcu::TestLog& log, AllocationCallbackRecorder& allocRecorder, const char* prefix)
+{
+       size_t                                                          memoryUsage;
+       AllocationCallbackValidationResults validationResults;
+
+       validateAllocationCallbacks(allocRecorder, &validationResults);
+       memoryUsage = getLiveSystemAllocationTotal(validationResults);
+
+       log << tcu::TestLog::Message << prefix << ": " << memoryUsage << tcu::TestLog::EndMessage;
+
+       return memoryUsage;
+}
+
+tcu::TestStatus resetDescriptorPoolTest (Context& context, deUint32 numIterations)
+{
+       AllocationCallbackRecorder      allocRecorder(getSystemAllocator());
+
+       const deUint32                          numDescriptorSetsPerIter = 2048;
+       const DeviceInterface&          vkd                                              = context.getDeviceInterface();
+       const VkDevice                          device                                   = context.getDevice();
+       tcu::TestLog&                           log                                              = context.getTestContext().getLog();
+
+       const VkDescriptorPoolSize descriptorPoolSize =
+       {
+               VK_DESCRIPTOR_TYPE_SAMPLER, // type
+               numDescriptorSetsPerIter        // descriptorCount
+       };
+
+       // \todo [2016-05-24 collinbaker] Test with flag VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT
+       const VkDescriptorPoolCreateInfo descriptorPoolInfo =
+       {
+               VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,  // sType
+               NULL,                                                                                   // pNext
+               0,                                                                                              // flags
+               numDescriptorSetsPerIter,                                               // maxSets
+               1,                                                                                              // poolSizeCount
+               &descriptorPoolSize                                                             // pPoolSizes
+       };
+
+       {
+               const Unique<VkDescriptorPool> descriptorPool(
+                       createDescriptorPool(vkd, device,
+                                                                &descriptorPoolInfo,
+                                                                allocRecorder.getCallbacks()));
+
+               checkAndLogMemoryUsage(log, allocRecorder, "Memory usage after vkCreateDescriptorPool");
+
+               const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding =
+               {
+                       0,                                                      // binding
+                       VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType
+                       1,                                                      // descriptorCount
+                       VK_SHADER_STAGE_ALL,            // stageFlags
+                       NULL                                            // pImmutableSamplers
+               };
+
+               const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo =
+               {
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // sType
+                       NULL,                                                                                                   // pNext
+                       0,                                                                                                              // flags
+                       1,                                                                                                              // bindingCount
+                       &descriptorSetLayoutBinding                                                             // pBindings
+               };
+
+               {
+                       typedef de::SharedPtr<Unique<VkDescriptorSetLayout> > DescriptorSetLayoutPtr;
+
+                       vector<DescriptorSetLayoutPtr> descriptorSetLayouts;
+                       descriptorSetLayouts.reserve(numDescriptorSetsPerIter);
+
+                       for (deUint32 ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
+                       {
+                               descriptorSetLayouts.push_back(
+                                       DescriptorSetLayoutPtr(
+                                               new Unique<VkDescriptorSetLayout>(
+                                                       createDescriptorSetLayout(vkd, device,
+                                                                                                         &descriptorSetLayoutInfo,
+                                                                                                         allocRecorder.getCallbacks()))));
+                       }
+
+                       vector<VkDescriptorSetLayout> descriptorSetLayoutsRaw(numDescriptorSetsPerIter);
+
+                       for (deUint32 ndx = 0; ndx < numDescriptorSetsPerIter; ++ndx)
+                       {
+                               descriptorSetLayoutsRaw[ndx] = **descriptorSetLayouts[ndx];
+                       }
+
+                       checkAndLogMemoryUsage(log, allocRecorder, "Memory usage after vkCreateDescriptorSetLayout");
+
+                       const VkDescriptorSetAllocateInfo descriptorSetInfo =
+                       {
+                               VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
+                               NULL,                                                                                   // pNext
+                               *descriptorPool,                                                                // descriptorPool
+                               numDescriptorSetsPerIter,                                               // descriptorSetCount
+                               &descriptorSetLayoutsRaw[0]                                             // pSetLayouts
+                       };
+
+                       vector<VkDescriptorSet> testSets(numDescriptorSetsPerIter);
+
+                       for (deUint32 ndx = 0; ndx < numIterations; ++ndx)
+                       {
+                               // The test should crash in this loop at some point if there is a memory leak
+                               VK_CHECK(vkd.allocateDescriptorSets(device, &descriptorSetInfo, &testSets[0]));
+                               VK_CHECK(vkd.resetDescriptorPool(device, *descriptorPool, 0));
+                       }
+
+               }
+
+               checkAndLogMemoryUsage(log, allocRecorder, "Memory usage after vkDestroyDescriptorSetLayout");
+
+       }
+
+       checkAndLogMemoryUsage(log, allocRecorder, "Memory usage after vkDestroyDescriptorPool");
+
+       // If it didn't crash, pass
+       return tcu::TestStatus::pass("Pass");
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createDescriptorPoolTests (tcu::TestContext& testCtx)
+{
+       const deUint32 numIterationsHigh = 4096;
+
+       de::MovePtr<tcu::TestCaseGroup> descriptorPoolTests(
+               new tcu::TestCaseGroup(testCtx, "descriptor_pool", "Descriptor Pool Tests"));
+
+       addFunctionCase(descriptorPoolTests.get(),
+                                       "repeated_reset_short",
+                                       "Test 2 cycles of vkAllocateDescriptorSets and vkResetDescriptorPool (should pass)",
+                                       resetDescriptorPoolTest, 2U);
+       addFunctionCase(descriptorPoolTests.get(),
+                                       "repeated_reset_long",
+                                       "Test many cycles of vkAllocateDescriptorSets and vkResetDescriptorPool",
+                                       resetDescriptorPoolTest, numIterationsHigh);
+
+       return descriptorPoolTests.release();
+}
+
+} // api
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.hpp b/external/vulkancts/modules/vulkan/api/vktApiDescriptorPoolTests.hpp
new file mode 100644 (file)
index 0000000..7a3099b
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _VKTAPIDESCRIPTORPOOLTESTS_HPP
+#define _VKTAPIDESCRIPTORPOOLTESTS_HPP
+
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google 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 Descriptor pool tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace api
+{
+
+tcu::TestCaseGroup* createDescriptorPoolTests (tcu::TestContext& testCtx);
+
+} // api
+} // vkt
+
+#endif // _VKTAPIDESCRIPTORPOOLTESTS_HPP
index 83f4f61..9d97f06 100644 (file)
@@ -35,6 +35,7 @@
 #include "vktApiCopiesAndBlittingTests.hpp"
 #include "vktApiImageClearingTests.hpp"
 #include "vktApiFillBufferTests.hpp"
+#include "vktApiDescriptorPoolTests.hpp"
 
 namespace vkt
 {
@@ -66,6 +67,7 @@ void createApiTests (tcu::TestCaseGroup* apiTests)
        apiTests->addChild(createCopiesAndBlittingTests         (testCtx));
        apiTests->addChild(createImageClearingTests                     (testCtx));
        apiTests->addChild(createFillAndUpdateBufferTests       (testCtx));
+       apiTests->addChild(createDescriptorPoolTests(testCtx));
 }
 
 } // anonymous