Add allocation callback tests for WSI
authorPyry Haulos <phaulos@google.com>
Fri, 18 Mar 2016 23:28:17 +0000 (16:28 -0700)
committerPyry Haulos <phaulos@google.com>
Mon, 21 Mar 2016 17:18:57 +0000 (10:18 -0700)
Includes tests for simulating out of host memory.

Change-Id: I9d754654dbae51e5236887761e58fa37a87d8b7a

android/cts/master/com.drawelements.deqp.vk.xml
android/cts/master/vk-master.txt
external/vulkancts/framework/vulkan/vkDeviceUtil.cpp
external/vulkancts/framework/vulkan/vkDeviceUtil.hpp
external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp

index 6a6cef9..3b93b5d 100644 (file)
                                        <Test name="create">
                                                <TestInstance/>
                                        </Test>
+                                       <Test name="create_custom_allocator">
+                                               <TestInstance/>
+                                       </Test>
+                                       <Test name="create_simulate_oom">
+                                               <TestInstance/>
+                                       </Test>
                                        <Test name="query_support">
                                                <TestInstance/>
                                        </Test>
                                                        <TestInstance/>
                                                </Test>
                                        </TestCase>
+                                       <TestCase name="simulate_oom">
+                                               <Test name="min_image_count">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="image_format">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="image_extent">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="image_array_layers">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="image_usage">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="image_sharing_mode">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="pre_transform">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="composite_alpha">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="present_mode">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="clipped">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
                                </TestSuite>
                        </TestSuite>
                </TestSuite>
index 67729e3..fdb1556 100644 (file)
@@ -80289,6 +80289,8 @@ dEQP-VK.image.image_size.buffer.readonly_writeonly_12
 dEQP-VK.image.image_size.buffer.readonly_writeonly_1
 dEQP-VK.image.image_size.buffer.readonly_writeonly_7
 dEQP-VK.wsi.android.surface.create
+dEQP-VK.wsi.android.surface.create_custom_allocator
+dEQP-VK.wsi.android.surface.create_simulate_oom
 dEQP-VK.wsi.android.surface.query_support
 dEQP-VK.wsi.android.surface.query_capabilities
 dEQP-VK.wsi.android.surface.query_formats
@@ -80304,6 +80306,16 @@ dEQP-VK.wsi.android.swapchain.create.pre_transform
 dEQP-VK.wsi.android.swapchain.create.composite_alpha
 dEQP-VK.wsi.android.swapchain.create.present_mode
 dEQP-VK.wsi.android.swapchain.create.clipped
+dEQP-VK.wsi.android.swapchain.simulate_oom.min_image_count
+dEQP-VK.wsi.android.swapchain.simulate_oom.image_format
+dEQP-VK.wsi.android.swapchain.simulate_oom.image_extent
+dEQP-VK.wsi.android.swapchain.simulate_oom.image_array_layers
+dEQP-VK.wsi.android.swapchain.simulate_oom.image_usage
+dEQP-VK.wsi.android.swapchain.simulate_oom.image_sharing_mode
+dEQP-VK.wsi.android.swapchain.simulate_oom.pre_transform
+dEQP-VK.wsi.android.swapchain.simulate_oom.composite_alpha
+dEQP-VK.wsi.android.swapchain.simulate_oom.present_mode
+dEQP-VK.wsi.android.swapchain.simulate_oom.clipped
 dEQP-VK.synchronization.fences
 dEQP-VK.synchronization.semaphores
 dEQP-VK.synchronization.events
index a551680..3e146f6 100644 (file)
@@ -43,9 +43,10 @@ namespace vk
 using std::vector;
 using std::string;
 
-Move<VkInstance> createDefaultInstance (const PlatformInterface&       vkPlatform,
-                                                                               const vector<string>&           enabledLayers,
-                                                                               const vector<string>&           enabledExtensions)
+Move<VkInstance> createDefaultInstance (const PlatformInterface&               vkPlatform,
+                                                                               const vector<string>&                   enabledLayers,
+                                                                               const vector<string>&                   enabledExtensions,
+                                                                               const VkAllocationCallbacks*    pAllocator)
 {
        vector<const char*>             layerNamePtrs           (enabledLayers.size());
        vector<const char*>             extensionNamePtrs       (enabledExtensions.size());
@@ -79,12 +80,12 @@ Move<VkInstance> createDefaultInstance (const PlatformInterface&    vkPlatform,
        for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
                extensionNamePtrs[ndx] = enabledExtensions[ndx].c_str();
 
-       return createInstance(vkPlatform, &instanceInfo);
+       return createInstance(vkPlatform, &instanceInfo, pAllocator);
 }
 
 Move<VkInstance> createDefaultInstance (const PlatformInterface& vkPlatform)
 {
-       return createDefaultInstance(vkPlatform, vector<string>(), vector<string>());
+       return createDefaultInstance(vkPlatform, vector<string>(), vector<string>(), DE_NULL);
 }
 
 VkPhysicalDevice chooseDevice (const InstanceInterface& vkInstance, VkInstance instance, const tcu::CommandLine& cmdLine)
index 3b59e8b..123a815 100644 (file)
@@ -47,7 +47,8 @@ namespace vk
 Move<VkInstance>       createDefaultInstance   (const PlatformInterface&                       vkPlatform);
 Move<VkInstance>       createDefaultInstance   (const PlatformInterface&                       vkPlatform,
                                                                                         const std::vector<std::string>&        enabledLayers,
-                                                                                        const std::vector<std::string>&        enabledExtensions);
+                                                                                        const std::vector<std::string>&        enabledExtensions,
+                                                                                        const VkAllocationCallbacks*           pAllocator      = DE_NULL);
 
 VkPhysicalDevice       chooseDevice                    (const InstanceInterface&                       vkInstance,
                                                                                         VkInstance                                                     instance,
index 29b8973..42c0553 100644 (file)
@@ -45,6 +45,7 @@
 #include "vkTypeUtil.hpp"
 #include "vkWsiPlatform.hpp"
 #include "vkWsiUtil.hpp"
+#include "vkAllocationCallbackUtil.hpp"
 
 #include "tcuTestLog.hpp"
 #include "tcuFormatUtil.hpp"
@@ -108,9 +109,10 @@ void checkAllSupported (const Extensions& supportedExtensions, const vector<stri
        }
 }
 
-Move<VkInstance> createInstanceWithWsi (const PlatformInterface&       vkp,
-                                                                               const Extensions&                       supportedExtensions,
-                                                                               Type                                            wsiType)
+Move<VkInstance> createInstanceWithWsi (const PlatformInterface&               vkp,
+                                                                               const Extensions&                               supportedExtensions,
+                                                                               Type                                                    wsiType,
+                                                                               const VkAllocationCallbacks*    pAllocator      = DE_NULL)
 {
        vector<string>  extensions;
 
@@ -119,7 +121,7 @@ Move<VkInstance> createInstanceWithWsi (const PlatformInterface&    vkp,
 
        checkAllSupported(supportedExtensions, extensions);
 
-       return createDefaultInstance(vkp, vector<string>(), extensions);
+       return createDefaultInstance(vkp, vector<string>(), extensions, pAllocator);
 }
 
 struct InstanceHelper
@@ -128,12 +130,13 @@ struct InstanceHelper
        Unique<VkInstance>                                      instance;
        const InstanceDriver                            vki;
 
-       InstanceHelper (Context& context, Type wsiType)
+       InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
                : supportedExtensions   (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
                                                                                                                                          DE_NULL))
                , instance                              (createInstanceWithWsi(context.getPlatformInterface(),
                                                                                                           supportedExtensions,
-                                                                                                          wsiType))
+                                                                                                          wsiType,
+                                                                                                          pAllocator))
                , vki                                   (context.getPlatformInterface(), *instance)
        {}
 };
@@ -196,6 +199,89 @@ tcu::TestStatus createSurfaceTest (Context& context, Type wsiType)
        return tcu::TestStatus::pass("Creating surface succeeded");
 }
 
+tcu::TestStatus createSurfaceCustomAllocatorTest (Context& context, Type wsiType)
+{
+       AllocationCallbackRecorder      allocationRecorder      (getSystemAllocator());
+       tcu::TestLog&                           log                                     = context.getTestContext().getLog();
+
+       {
+               const InstanceHelper            instHelper      (context, wsiType, allocationRecorder.getCallbacks());
+               const NativeObjects                     native          (context, instHelper.supportedExtensions, wsiType);
+               const Unique<VkSurfaceKHR>      surface         (createSurface(instHelper.vki,
+                                                                                                                          *instHelper.instance,
+                                                                                                                          wsiType,
+                                                                                                                          *native.display,
+                                                                                                                          *native.window,
+                                                                                                                          allocationRecorder.getCallbacks()));
+
+               if (!validateAndLog(log,
+                                                       allocationRecorder,
+                                                       (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)         |
+                                                       (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
+                       return tcu::TestStatus::fail("Detected invalid system allocation callback");
+       }
+
+       if (!validateAndLog(log, allocationRecorder, 0u))
+               return tcu::TestStatus::fail("Detected invalid system allocation callback");
+
+       if (allocationRecorder.getRecordsBegin() == allocationRecorder.getRecordsEnd())
+               return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
+       else
+               return tcu::TestStatus::pass("Creating surface succeeded using custom allocator");
+}
+
+tcu::TestStatus createSurfaceSimulateOOMTest (Context& context, Type wsiType)
+{
+       tcu::TestLog&   log     = context.getTestContext().getLog();
+
+       for (deUint32 numPassingAllocs = 0; numPassingAllocs <= 1024u; ++numPassingAllocs)
+       {
+               AllocationCallbackRecorder      allocationRecorder      (getSystemAllocator());
+               DeterministicFailAllocator      failingAllocator        (allocationRecorder.getCallbacks(), numPassingAllocs);
+               bool                                            gotOOM                          = false;
+
+               log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
+
+               try
+               {
+                       const InstanceHelper            instHelper      (context, wsiType, failingAllocator.getCallbacks());
+                       const NativeObjects                     native          (context, instHelper.supportedExtensions, wsiType);
+                       const Unique<VkSurfaceKHR>      surface         (createSurface(instHelper.vki,
+                                                                                                                                  *instHelper.instance,
+                                                                                                                                  wsiType,
+                                                                                                                                  *native.display,
+                                                                                                                                  *native.window,
+                                                                                                                                  failingAllocator.getCallbacks()));
+
+                       if (!validateAndLog(log,
+                                                               allocationRecorder,
+                                                               (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)         |
+                                                               (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
+                               return tcu::TestStatus::fail("Detected invalid system allocation callback");
+               }
+               catch (const OutOfMemoryError& e)
+               {
+                       log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
+                       gotOOM = true;
+               }
+
+               if (!validateAndLog(log, allocationRecorder, 0u))
+                       return tcu::TestStatus::fail("Detected invalid system allocation callback");
+
+               if (!gotOOM)
+               {
+                       log << TestLog::Message << "Creating surface succeeded!" << TestLog::EndMessage;
+
+                       if (numPassingAllocs == 0)
+                               return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
+                       else
+                               return tcu::TestStatus::pass("OOM simulation completed");
+               }
+       }
+
+       return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Creating surface did not succeed, callback limit exceeded");
+}
+
 deUint32 getNumQueueFamilies (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
 {
        deUint32        numFamilies             = 0;
@@ -524,11 +610,13 @@ void createSurfaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
 {
        const PlatformProperties&       platformProperties      = getPlatformProperties(wsiType);
 
-       addFunctionCase(testGroup, "create",                            "Create surface",                               createSurfaceTest,                              wsiType);
-       addFunctionCase(testGroup, "query_support",                     "Query surface support",                querySurfaceSupportTest,                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, "create",                                    "Create surface",                                               createSurfaceTest,                                      wsiType);
+       addFunctionCase(testGroup, "create_custom_allocator",   "Create surface with custom allocator", createSurfaceCustomAllocatorTest,       wsiType);
+       addFunctionCase(testGroup, "create_simulate_oom",               "Create surface with simulating OOM",   createSurfaceSimulateOOMTest,           wsiType);
+       addFunctionCase(testGroup, "query_support",                             "Query surface support",                                querySurfaceSupportTest,                        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);
 
        if ((platformProperties.features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE) != 0)
                addFunctionCase(testGroup, "initial_size",      "Create surface with initial window size set",  createSurfaceInitialSizeTest,   wsiType);
index 5f977b8..1342955 100644 (file)
@@ -45,6 +45,7 @@
 #include "vkTypeUtil.hpp"
 #include "vkWsiPlatform.hpp"
 #include "vkWsiUtil.hpp"
+#include "vkAllocationCallbackUtil.hpp"
 
 #include "tcuTestLog.hpp"
 #include "tcuFormatUtil.hpp"
@@ -89,9 +90,10 @@ void checkAllSupported (const Extensions& supportedExtensions, const vector<stri
        }
 }
 
-Move<VkInstance> createInstanceWithWsi (const PlatformInterface&       vkp,
-                                                                               const Extensions&                       supportedExtensions,
-                                                                               Type                                            wsiType)
+Move<VkInstance> createInstanceWithWsi (const PlatformInterface&               vkp,
+                                                                               const Extensions&                               supportedExtensions,
+                                                                               Type                                                    wsiType,
+                                                                               const VkAllocationCallbacks*    pAllocator      = DE_NULL)
 {
        vector<string>  extensions;
 
@@ -100,7 +102,7 @@ Move<VkInstance> createInstanceWithWsi (const PlatformInterface&    vkp,
 
        checkAllSupported(supportedExtensions, extensions);
 
-       return createDefaultInstance(vkp, vector<string>(), extensions);
+       return createDefaultInstance(vkp, vector<string>(), extensions, pAllocator);
 }
 
 VkPhysicalDeviceFeatures getDeviceFeaturesForWsi (void)
@@ -110,10 +112,11 @@ VkPhysicalDeviceFeatures getDeviceFeaturesForWsi (void)
        return features;
 }
 
-Move<VkDevice> createDeviceWithWsi (const InstanceInterface&   vki,
-                                                                       VkPhysicalDevice                        physicalDevice,
-                                                                       const Extensions&                       supportedExtensions,
-                                                                       const deUint32                          queueFamilyIndex)
+Move<VkDevice> createDeviceWithWsi (const InstanceInterface&           vki,
+                                                                       VkPhysicalDevice                                physicalDevice,
+                                                                       const Extensions&                               supportedExtensions,
+                                                                       const deUint32                                  queueFamilyIndex,
+                                                                       const VkAllocationCallbacks*    pAllocator = DE_NULL)
 {
        const float                                             queuePriorities[]       = { 1.0f };
        const VkDeviceQueueCreateInfo   queueInfos[]            =
@@ -149,7 +152,7 @@ Move<VkDevice> createDeviceWithWsi (const InstanceInterface&        vki,
                        TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
        }
 
-       return createDevice(vki, physicalDevice, &deviceParams, (const VkAllocationCallbacks*)DE_NULL);
+       return createDevice(vki, physicalDevice, &deviceParams, pAllocator);
 }
 
 deUint32 getNumQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
@@ -191,12 +194,13 @@ struct InstanceHelper
        const Unique<VkInstance>                        instance;
        const InstanceDriver                            vki;
 
-       InstanceHelper (Context& context, Type wsiType)
+       InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
                : supportedExtensions   (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
                                                                                                                                          DE_NULL))
                , instance                              (createInstanceWithWsi(context.getPlatformInterface(),
                                                                                                           supportedExtensions,
-                                                                                                          wsiType))
+                                                                                                          wsiType,
+                                                                                                          pAllocator))
                , vki                                   (context.getPlatformInterface(), *instance)
        {}
 };
@@ -216,13 +220,18 @@ struct DeviceHelper
        const DeviceDriver              vkd;
        const VkQueue                   queue;
 
-       DeviceHelper (Context& context, const InstanceInterface& vki, VkInstance instance, VkSurfaceKHR surface)
+       DeviceHelper (Context&                                          context,
+                                 const InstanceInterface&              vki,
+                                 VkInstance                                    instance,
+                                 VkSurfaceKHR                                  surface,
+                                 const VkAllocationCallbacks*  pAllocator = DE_NULL)
                : physicalDevice        (chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
                , queueFamilyIndex      (chooseQueueFamilyIndex(vki, physicalDevice, surface))
                , device                        (createDeviceWithWsi(vki,
                                                                                                 physicalDevice,
                                                                                                 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
-                                                                                                queueFamilyIndex))
+                                                                                                queueFamilyIndex,
+                                                                                                pAllocator))
                , vkd                           (vki, *device)
                , queue                         (getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
        {
@@ -572,6 +581,75 @@ tcu::TestStatus createSwapchainTest (Context& context, TestParameters params)
        return tcu::TestStatus::pass("Creating swapchain succeeded");
 }
 
+tcu::TestStatus createSwapchainSimulateOOMTest (Context& context, TestParameters params)
+{
+       tcu::TestLog&   log     = context.getTestContext().getLog();
+
+       // \note This is a little counter-intuitive order (iterating on callback count until all cases pass)
+       //               but since cases depend on what device reports, it is the only easy way. In practice
+       //               we should see same number of total callbacks (and executed code) regardless of the
+       //               loop order.
+
+       for (deUint32 numPassingAllocs = 0; numPassingAllocs <= 16*1024u; ++numPassingAllocs)
+       {
+               AllocationCallbackRecorder      allocationRecorder      (getSystemAllocator());
+               DeterministicFailAllocator      failingAllocator        (allocationRecorder.getCallbacks(), numPassingAllocs);
+               bool                                            gotOOM                          = false;
+
+               log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
+
+               try
+               {
+                       const InstanceHelper                                    instHelper      (context, params.wsiType, failingAllocator.getCallbacks());
+                       const NativeObjects                                             native          (context, instHelper.supportedExtensions, params.wsiType);
+                       const Unique<VkSurfaceKHR>                              surface         (createSurface(instHelper.vki,
+                                                                                                                                                          *instHelper.instance,
+                                                                                                                                                          params.wsiType,
+                                                                                                                                                          *native.display,
+                                                                                                                                                          *native.window,
+                                                                                                                                                          failingAllocator.getCallbacks()));
+                       const DeviceHelper                                              devHelper       (context, instHelper.vki, *instHelper.instance, *surface, failingAllocator.getCallbacks());
+                       const vector<VkSwapchainCreateInfoKHR>  cases           (generateSwapchainParameterCases(params.wsiType, params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));
+
+                       for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
+                       {
+                               VkSwapchainCreateInfoKHR        curParams       = cases[caseNdx];
+
+                               curParams.surface                               = *surface;
+                               curParams.queueFamilyIndexCount = 1u;
+                               curParams.pQueueFamilyIndices   = &devHelper.queueFamilyIndex;
+
+                               context.getTestContext().getLog()
+                                       << TestLog::Message << "Sub-case " << (caseNdx+1) << " / " << cases.size() << TestLog::EndMessage;
+
+                               {
+                                       const Unique<VkSwapchainKHR>    swapchain       (createSwapchainKHR(devHelper.vkd, *devHelper.device, &curParams, failingAllocator.getCallbacks()));
+                               }
+                       }
+               }
+               catch (const OutOfMemoryError& e)
+               {
+                       log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
+                       gotOOM = true;
+               }
+
+               if (!validateAndLog(log, allocationRecorder, 0u))
+                       return tcu::TestStatus::fail("Detected invalid system allocation callback");
+
+               if (!gotOOM)
+               {
+                       log << TestLog::Message << "Creating surface succeeded!" << TestLog::EndMessage;
+
+                       if (numPassingAllocs == 0)
+                               return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
+                       else
+                               return tcu::TestStatus::pass("OOM simulation completed");
+               }
+       }
+
+       return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Creating swapchain did not succeed, callback limit exceeded");
+}
+
 struct GroupParameters
 {
        typedef FunctionInstance1<TestParameters>::Function     Function;
@@ -604,7 +682,8 @@ void populateSwapchainGroup (tcu::TestCaseGroup* testGroup, GroupParameters para
 
 void createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
 {
-       addTestGroup(testGroup, "create", "Create VkSwapchain with various parameters", populateSwapchainGroup, GroupParameters(wsiType, createSwapchainTest));
+       addTestGroup(testGroup, "create",                       "Create VkSwapchain with various parameters",                                   populateSwapchainGroup, GroupParameters(wsiType, createSwapchainTest));
+       addTestGroup(testGroup, "simulate_oom",         "Simulate OOM using callbacks during swapchain construction",   populateSwapchainGroup, GroupParameters(wsiType, createSwapchainSimulateOOMTest));
 }
 
 } // wsi