dEQP-VK.api.info.vulkan1p2_limits_validation.ext_line_rasterization
dEQP-VK.api.device_init.create_instance_extension_name_abuse
dEQP-VK.api.device_init.create_instance_layer_name_abuse
+dEQP-VK.api.device_init.enumerate_devices_alloc_leak
dEQP-VK.api.buffer.basic.size_max_uint64
dEQP-VK.api.buffer_marker.graphics.external_host_mem.top_of_pipe.sequential.4
dEQP-VK.api.buffer_marker.graphics.external_host_mem.top_of_pipe.sequential.64
dEQP-VK.api.device_init.create_instance_unsupported_extensions
dEQP-VK.api.device_init.create_instance_extension_name_abuse
dEQP-VK.api.device_init.create_instance_layer_name_abuse
+dEQP-VK.api.device_init.enumerate_devices_alloc_leak
dEQP-VK.api.device_init.create_device
dEQP-VK.api.device_init.create_multiple_devices
dEQP-VK.api.device_init.create_device_unsupported_extensions
#include "vkMemUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkApiVersion.hpp"
+#include "vkAllocationCallbackUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuResultCollector.hpp"
return tcu::TestStatus::pass("Pass, creating instances with unsupported layers were rejected.");
}
+tcu::TestStatus enumerateDevicesAllocLeakTest(Context& context)
+{
+ // enumeratePhysicalDevices uses instance-provided allocator
+ // and this test checks if all alocated memory is freed
+
+ typedef AllocationCallbackRecorder::RecordIterator RecordIterator;
+
+ const PlatformInterface& vkp (context.getPlatformInterface());
+ const deUint32 apiVersion (context.getUsedApiVersion());
+ DeterministicFailAllocator objAllocator (getSystemAllocator(), DeterministicFailAllocator::MODE_DO_NOT_COUNT, 0);
+ AllocationCallbackRecorder recorder (objAllocator.getCallbacks(), 128);
+ Move<VkInstance> instance (vk::createDefaultInstance(vkp, apiVersion, {}, {}, recorder.getCallbacks()));
+ InstanceDriver vki (vkp, *instance);
+ vector<VkPhysicalDevice> devices (enumeratePhysicalDevices(vki, *instance));
+ RecordIterator recordToCheck (recorder.getRecordsEnd());
+
+ try
+ {
+ devices = enumeratePhysicalDevices(vki, *instance);
+ }
+ catch (const vk::OutOfMemoryError& e)
+ {
+ if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY)
+ return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Got out of memory error - leaks in enumeratePhysicalDevices not tested.");
+ }
+
+ // make sure that same number of allocations and frees was done
+ deInt32 allocationRecords (0);
+ RecordIterator lastRecordToCheck (recorder.getRecordsEnd());
+ while (recordToCheck != lastRecordToCheck)
+ {
+ const AllocationCallbackRecord& record = *recordToCheck;
+ switch (record.type)
+ {
+ case AllocationCallbackRecord::TYPE_ALLOCATION:
+ ++allocationRecords;
+ break;
+ case AllocationCallbackRecord::TYPE_FREE:
+ if (record.data.free.mem != DE_NULL)
+ --allocationRecords;
+ break;
+ default:
+ break;
+ }
+ ++recordToCheck;
+ }
+
+ if (allocationRecords)
+ return tcu::TestStatus::fail("enumeratePhysicalDevices leaked memory");
+ return tcu::TestStatus::pass("Ok");
+}
+
tcu::TestStatus createDeviceTest (Context& context)
{
const PlatformInterface& platformInterface = context.getPlatformInterface();
addFunctionCase(deviceInitializationTests.get(), "create_instance_unsupported_extensions", "", createInstanceWithUnsupportedExtensionsTest);
addFunctionCase(deviceInitializationTests.get(), "create_instance_extension_name_abuse", "", createInstanceWithExtensionNameAbuseTest);
addFunctionCase(deviceInitializationTests.get(), "create_instance_layer_name_abuse", "", createInstanceWithLayerNameAbuseTest);
+ addFunctionCase(deviceInitializationTests.get(), "enumerate_devices_alloc_leak", "", enumerateDevicesAllocLeakTest);
addFunctionCase(deviceInitializationTests.get(), "create_device", "", createDeviceTest);
addFunctionCase(deviceInitializationTests.get(), "create_multiple_devices", "", createMultipleDevicesTest);
addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_extensions", "", createDeviceWithUnsupportedExtensionsTest);
#include "deInt32.h"
#include <limits>
+#include <algorithm>
#define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1)
return tcu::TestStatus::pass("Ok");
}
-template<typename Object> deUint32 getOomIterLimit (void) { return 1024; }
-template<> deUint32 getOomIterLimit<Device> (void) { return 20; }
+template<typename Object> deUint32 getOomIterLimit (void) { return 40; }
+template<> deUint32 getOomIterLimit<Device> (void) { return 20; }
template<> deUint32 getOomIterLimit<DeviceGroup> (void) { return 20; }
template<typename Object>
deUint32 numPassingAllocs = 0;
const deUint32 cmdLineIterCount = (deUint32)context.getTestContext().getCommandLine().getTestIterationCount();
const deUint32 maxTries = cmdLineIterCount != 0 ? cmdLineIterCount : getOomIterLimit<Object>();
+ const deUint32 finalLimit = std::max(maxTries, 10000u);
+ bool createOk = false;
{
const EnvClone resEnv (rootEnv, getDefaulDeviceParameters(context), 1u);
const typename Object::Resources res (resEnv.env, params);
// Iterate over test until object allocation succeeds
- for (; numPassingAllocs < maxTries; ++numPassingAllocs)
+ while(true)
{
DeterministicFailAllocator objAllocator(getSystemAllocator(),
DeterministicFailAllocator::MODE_COUNT_AND_FAIL,
recorder.getCallbacks(),
resEnv.env.maxResourceConsumers,
resEnv.env.commandLine);
- bool createOk = false;
context.getTestContext().getLog()
<< TestLog::Message
<< "Trying to create object with " << numPassingAllocs << " allocation" << (numPassingAllocs != 1 ? "s" : "") << " passing"
<< TestLog::EndMessage;
+ createOk = false;
try
{
Unique<typename Object::Type> obj (Object::create(objEnv, res, params));
<< TestLog::Message << "Object construction succeeded! " << TestLog::EndMessage;
break;
}
+
+ ++numPassingAllocs;
+ // if allocation didn't succeed with huge limit then stop trying
+ if (numPassingAllocs >= finalLimit)
+ break;
+ // if we reached maxTries but didn't create object, try doing it with huge limit
+ if (numPassingAllocs >= maxTries)
+ numPassingAllocs = finalLimit;
}
}
if (numPassingAllocs == 0)
return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks not called");
- else if (numPassingAllocs == maxTries)
+ else if (numPassingAllocs >= finalLimit)
{
+ if (createOk)
+ {
+ context.getTestContext().getLog()
+ << TestLog::Message << "Maximum iteration count (" << maxTries << ") reached without object construction passing. "
+ << "Object was succesfully constructed with " << numPassingAllocs << " iterations limit." << TestLog::EndMessage;
+ return tcu::TestStatus(QP_TEST_RESULT_PASS, "Construction passed but not all iterations were checked");
+ }
+
context.getTestContext().getLog()
- << TestLog::Message << "WARNING: Maximum iteration count (" << maxTries << ") reached without object construction passing. "
- << "OOM testing incomplete, use --deqp-test-iteration-count= to test with higher limit." << TestLog::EndMessage;
+ << TestLog::Message << "WARNING: Maximum iteration count (" << finalLimit << ") reached without object construction passing. "
+ << "OOM testing incomplete, use --deqp-test-iteration-count= to test with higher limit." << TestLog::EndMessage;
return tcu::TestStatus(QP_TEST_RESULT_PASS, "Max iter count reached");
}
else
dEQP-VK.api.device_init.create_instance_unsupported_extensions
dEQP-VK.api.device_init.create_instance_extension_name_abuse
dEQP-VK.api.device_init.create_instance_layer_name_abuse
+dEQP-VK.api.device_init.enumerate_devices_alloc_leak
dEQP-VK.api.device_init.create_device
dEQP-VK.api.device_init.create_multiple_devices
dEQP-VK.api.device_init.create_device_unsupported_extensions