Tests for VK_KHR_present_id and VK_KHR_present_wait
authorRicardo Garcia <rgarcia@igalia.com>
Mon, 19 Apr 2021 13:56:11 +0000 (15:56 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Tue, 27 Jul 2021 15:26:55 +0000 (15:26 +0000)
Add tests for VK_KHR_present_id and VK_KHR_present_wait. This commit
also refactors some code so it can be reused in several places, hence
marking all WSI tests as affected.

Affected tests:
dEQP-VK.info.device_mandatory_features
dEQP-VK.wsi.*

New tests:
dEQP-VK.wsi.*.present_id_wait.*

Components: Vulkan
VK-GL-CTS issue: 2098
VK-GL-CTS issue: 2099

Change-Id: I1c95fbf031d651773a9fff1c10a23038d73f6e53
(cherry picked from commit 8bf210fd592883b3adebb57c3d6cc49188d1758e)

19 files changed:
AndroidGen.mk
android/cts/master/vk-master-2021-03-01/wsi.txt
android/cts/master/vk-master/wsi.txt
external/vulkancts/framework/vulkan/vkDeviceExtensions.inl
external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
external/vulkancts/framework/vulkan/vkWsiUtil.cpp
external/vulkancts/modules/vulkan/wsi/CMakeLists.txt
external/vulkancts/modules/vulkan/wsi/vktNativeObjectsUtil.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/wsi/vktNativeObjectsUtil.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/wsi/vktWsiColorSpaceTests.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiFullScreenExclusiveTests.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiPresentIdWaitTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/wsi/vktWsiPresentIdWaitTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
external/vulkancts/modules/vulkan/wsi/vktWsiTests.cpp
external/vulkancts/mustpass/master/vk-default/wsi.txt
external/vulkancts/scripts/src/extensions_data.txt
external/vulkancts/scripts/src/mandatory_features.txt

index 8c548ad..61f2663 100644 (file)
@@ -515,12 +515,14 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/vktTestGroupUtil.cpp \
        external/vulkancts/modules/vulkan/vktTestPackage.cpp \
        external/vulkancts/modules/vulkan/vktTestPackageEntry.cpp \
+       external/vulkancts/modules/vulkan/wsi/vktNativeObjectsUtil.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiColorSpaceTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiDisplayControlTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTimingTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiFullScreenExclusiveTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiIncrementalPresentTests.cpp \
+       external/vulkancts/modules/vulkan/wsi/vktWsiPresentIdWaitTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiSharedPresentableImageTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp \
index a527ecc..cbc218b 100644 (file)
@@ -19,6 +19,15 @@ dEQP-VK.wsi.android.full_screen_exclusive.default
 dEQP-VK.wsi.android.full_screen_exclusive.allowed
 dEQP-VK.wsi.android.full_screen_exclusive.disallowed
 dEQP-VK.wsi.android.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.android.present_id_wait.id.zero
+dEQP-VK.wsi.android.present_id_wait.id.increasing
+dEQP-VK.wsi.android.present_id_wait.id.interleaved
+dEQP-VK.wsi.android.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.android.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.android.present_id_wait.wait.no_frames
+dEQP-VK.wsi.android.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.android.present_id_wait.wait.future_frame
+dEQP-VK.wsi.android.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.macos.swapchain.acquire.too_many
 dEQP-VK.wsi.macos.swapchain.acquire.too_many_timeout
 dEQP-VK.wsi.macos.swapchain.private_data.min_image_count
@@ -40,6 +49,15 @@ dEQP-VK.wsi.macos.full_screen_exclusive.default
 dEQP-VK.wsi.macos.full_screen_exclusive.allowed
 dEQP-VK.wsi.macos.full_screen_exclusive.disallowed
 dEQP-VK.wsi.macos.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.macos.present_id_wait.id.zero
+dEQP-VK.wsi.macos.present_id_wait.id.increasing
+dEQP-VK.wsi.macos.present_id_wait.id.interleaved
+dEQP-VK.wsi.macos.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.macos.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.macos.present_id_wait.wait.no_frames
+dEQP-VK.wsi.macos.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.macos.present_id_wait.wait.future_frame
+dEQP-VK.wsi.macos.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.headless.surface.create
 dEQP-VK.wsi.headless.surface.create_custom_allocator
 dEQP-VK.wsi.headless.surface.create_simulate_oom
@@ -481,3 +499,12 @@ dEQP-VK.wsi.headless.full_screen_exclusive.default
 dEQP-VK.wsi.headless.full_screen_exclusive.allowed
 dEQP-VK.wsi.headless.full_screen_exclusive.disallowed
 dEQP-VK.wsi.headless.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.headless.present_id_wait.id.zero
+dEQP-VK.wsi.headless.present_id_wait.id.increasing
+dEQP-VK.wsi.headless.present_id_wait.id.interleaved
+dEQP-VK.wsi.headless.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.headless.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.headless.present_id_wait.wait.no_frames
+dEQP-VK.wsi.headless.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.headless.present_id_wait.wait.future_frame
+dEQP-VK.wsi.headless.present_id_wait.wait.two_swapchains
index bb56709..8bf41c3 100644 (file)
@@ -798,6 +798,15 @@ dEQP-VK.wsi.android.full_screen_exclusive.default
 dEQP-VK.wsi.android.full_screen_exclusive.allowed
 dEQP-VK.wsi.android.full_screen_exclusive.disallowed
 dEQP-VK.wsi.android.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.android.present_id_wait.id.zero
+dEQP-VK.wsi.android.present_id_wait.id.increasing
+dEQP-VK.wsi.android.present_id_wait.id.interleaved
+dEQP-VK.wsi.android.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.android.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.android.present_id_wait.wait.no_frames
+dEQP-VK.wsi.android.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.android.present_id_wait.wait.future_frame
+dEQP-VK.wsi.android.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.macos.surface.create
 dEQP-VK.wsi.macos.surface.create_custom_allocator
 dEQP-VK.wsi.macos.surface.create_simulate_oom
@@ -1240,6 +1249,15 @@ dEQP-VK.wsi.macos.full_screen_exclusive.default
 dEQP-VK.wsi.macos.full_screen_exclusive.allowed
 dEQP-VK.wsi.macos.full_screen_exclusive.disallowed
 dEQP-VK.wsi.macos.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.macos.present_id_wait.id.zero
+dEQP-VK.wsi.macos.present_id_wait.id.increasing
+dEQP-VK.wsi.macos.present_id_wait.id.interleaved
+dEQP-VK.wsi.macos.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.macos.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.macos.present_id_wait.wait.no_frames
+dEQP-VK.wsi.macos.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.macos.present_id_wait.wait.future_frame
+dEQP-VK.wsi.macos.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.headless.surface.create
 dEQP-VK.wsi.headless.surface.create_custom_allocator
 dEQP-VK.wsi.headless.surface.create_simulate_oom
@@ -1681,6 +1699,15 @@ dEQP-VK.wsi.headless.full_screen_exclusive.default
 dEQP-VK.wsi.headless.full_screen_exclusive.allowed
 dEQP-VK.wsi.headless.full_screen_exclusive.disallowed
 dEQP-VK.wsi.headless.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.headless.present_id_wait.id.zero
+dEQP-VK.wsi.headless.present_id_wait.id.increasing
+dEQP-VK.wsi.headless.present_id_wait.id.interleaved
+dEQP-VK.wsi.headless.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.headless.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.headless.present_id_wait.wait.no_frames
+dEQP-VK.wsi.headless.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.headless.present_id_wait.wait.future_frame
+dEQP-VK.wsi.headless.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.display.get_display_properties
 dEQP-VK.wsi.display.get_display_plane_properties
 dEQP-VK.wsi.display.get_display_plane_supported_displays
index 46d64d7..cfd915e 100644 (file)
@@ -77,5 +77,7 @@ static const char* s_allowedDeviceKhrExtensions[] =
        "VK_VALVE_mutable_descriptor_type",
        "VK_EXT_multi_draw",
        "VK_KHR_shader_subgroup_uniform_control_flow",
+       "VK_KHR_present_id",
+       "VK_KHR_present_wait",
 };
 
index 91c3655..fe57bdb 100644 (file)
@@ -266,6 +266,26 @@ bool checkMandatoryFeatures(const vkt::Context& context)
                nextPtr  = &physicalDevicePipelineExecutablePropertiesFeaturesKHR.pNext;
        }
 
+       vk::VkPhysicalDevicePresentIdFeaturesKHR physicalDevicePresentIdFeaturesKHR;
+       deMemset(&physicalDevicePresentIdFeaturesKHR, 0, sizeof(physicalDevicePresentIdFeaturesKHR));
+
+       if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_present_id")) )
+       {
+               physicalDevicePresentIdFeaturesKHR.sType = getStructureType<VkPhysicalDevicePresentIdFeaturesKHR>();
+               *nextPtr = &physicalDevicePresentIdFeaturesKHR;
+               nextPtr  = &physicalDevicePresentIdFeaturesKHR.pNext;
+       }
+
+       vk::VkPhysicalDevicePresentWaitFeaturesKHR physicalDevicePresentWaitFeaturesKHR;
+       deMemset(&physicalDevicePresentWaitFeaturesKHR, 0, sizeof(physicalDevicePresentWaitFeaturesKHR));
+
+       if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_present_wait")) )
+       {
+               physicalDevicePresentWaitFeaturesKHR.sType = getStructureType<VkPhysicalDevicePresentWaitFeaturesKHR>();
+               *nextPtr = &physicalDevicePresentWaitFeaturesKHR;
+               nextPtr  = &physicalDevicePresentWaitFeaturesKHR.pNext;
+       }
+
        vk::VkPhysicalDeviceRayQueryFeaturesKHR physicalDeviceRayQueryFeaturesKHR;
        deMemset(&physicalDeviceRayQueryFeaturesKHR, 0, sizeof(physicalDeviceRayQueryFeaturesKHR));
 
@@ -1838,6 +1858,24 @@ bool checkMandatoryFeatures(const vkt::Context& context)
                }
        }
 
+       if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_present_id")) )
+       {
+               if ( physicalDevicePresentIdFeaturesKHR.presentId == VK_FALSE )
+               {
+                       log << tcu::TestLog::Message << "Mandatory feature presentId not supported" << tcu::TestLog::EndMessage;
+                       result = false;
+               }
+       }
+
+       if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_present_wait")) )
+       {
+               if ( physicalDevicePresentWaitFeaturesKHR.presentWait == VK_FALSE )
+               {
+                       log << tcu::TestLog::Message << "Mandatory feature presentWait not supported" << tcu::TestLog::EndMessage;
+                       result = false;
+               }
+       }
+
        return result;
 }
 
index 0f3b966..b1023db 100644 (file)
@@ -609,7 +609,7 @@ Move<VkRenderPass> WsiTriangleRenderer::createRenderPass (const DeviceInterface&
                VK_ATTACHMENT_STORE_OP_STORE,
                VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                VK_ATTACHMENT_STORE_OP_DONT_CARE,
-               (explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+               (explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED,
                (explicitLayoutTransitions) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
        };
        const VkAttachmentReference             colorAttRef                     =
index c884157..0e8f299 100644 (file)
@@ -3,6 +3,8 @@
 include_directories(..)
 
 set(DEQP_VK_WSI_SRCS
+       vktNativeObjectsUtil.cpp
+       vktNativeObjectsUtil.hpp
        vktWsiTests.cpp
        vktWsiTests.hpp
        vktWsiSurfaceTests.cpp
@@ -23,6 +25,8 @@ set(DEQP_VK_WSI_SRCS
        vktWsiColorSpaceTests.hpp
        vktWsiFullScreenExclusiveTests.cpp
        vktWsiFullScreenExclusiveTests.hpp
+       vktWsiPresentIdWaitTests.cpp
+       vktWsiPresentIdWaitTests.hpp
        )
 
 set(DEQP_VK_WSI_LIBS
diff --git a/external/vulkancts/modules/vulkan/wsi/vktNativeObjectsUtil.cpp b/external/vulkancts/modules/vulkan/wsi/vktNativeObjectsUtil.cpp
new file mode 100644 (file)
index 0000000..d2bbaa4
--- /dev/null
@@ -0,0 +1,105 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2019 Valve Corporation.
+ *
+ * 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 WSI Native Objects utility class.
+ *//*--------------------------------------------------------------------*/
+#include "vktNativeObjectsUtil.hpp"
+
+#include "vkQueryUtil.hpp"
+#include "vkWsiUtil.hpp"
+
+#include "tcuPlatform.hpp"
+
+#include "deDefs.hpp"
+
+namespace vkt
+{
+namespace wsi
+{
+
+de::MovePtr<vk::wsi::Display> NativeObjects::createDisplay     (const vk::Platform&                            platform,
+                                                                                                                        const NativeObjects::Extensions&       supportedExtensions,
+                                                                                                                        vk::wsi::Type                                          wsiType)
+{
+       try
+       {
+               return de::MovePtr<vk::wsi::Display>(platform.createWsiDisplay(wsiType));
+       }
+       catch (const tcu::NotSupportedError& e)
+       {
+               if (vk::isExtensionSupported(supportedExtensions, vk::RequiredExtension(vk::wsi::getExtensionName(wsiType))) &&
+                       platform.hasDisplay(wsiType))
+               {
+                       // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
+                       // must support creating native display & window for that WSI type.
+                       throw tcu::TestError(e.getMessage());
+               }
+               else
+                       throw;
+       }
+}
+
+de::MovePtr<vk::wsi::Window> NativeObjects::createWindow (const vk::wsi::Display& display, const tcu::Maybe<tcu::UVec2>& initialSize)
+{
+       try
+       {
+               return de::MovePtr<vk::wsi::Window>(display.createWindow(initialSize));
+       }
+       catch (const tcu::NotSupportedError& e)
+       {
+               // See createDisplay - assuming that wsi::Display was supported platform port
+               // should also support creating a window.
+               throw tcu::TestError(e.getMessage());
+       }
+}
+
+NativeObjects::NativeObjects (Context&                                         context,
+                                                         const Extensions&                             supportedExtensions,
+                                                         vk::wsi::Type                                 wsiType,
+                                                         size_t                                                windowCount,
+                                                         const tcu::Maybe<tcu::UVec2>& initialWindowSize)
+       : display (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
+{
+       DE_ASSERT(windowCount > 0u);
+       for (size_t i = 0; i < windowCount; ++i)
+               windows.emplace_back(createWindow(*display, initialWindowSize));
+}
+
+NativeObjects::NativeObjects (NativeObjects&& other)
+       : display       (other.display.move())
+       , windows       ()
+{
+       windows.swap(other.windows);
+}
+
+vk::wsi::Display& NativeObjects::getDisplay    () const
+{
+       return *display;
+}
+
+vk::wsi::Window& NativeObjects::getWindow (size_t index) const
+{
+       DE_ASSERT(index < windows.size());
+       return *windows[index];
+}
+
+} // wsi
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/wsi/vktNativeObjectsUtil.hpp b/external/vulkancts/modules/vulkan/wsi/vktNativeObjectsUtil.hpp
new file mode 100644 (file)
index 0000000..4f0479a
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef _VKTNATIVEOBJECTSUTIL_HPP
+#define _VKTNATIVEOBJECTSUTIL_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2019 Valve Corporation.
+ *
+ * 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 WSI Native Objects utility class.
+ *//*--------------------------------------------------------------------*/
+#include "vktTestCase.hpp"
+
+#include "vkDefs.hpp"
+#include "vkWsiPlatform.hpp"
+
+#include "tcuMaybe.hpp"
+#include "tcuVectorType.hpp"
+
+
+namespace vkt
+{
+namespace wsi
+{
+
+class NativeObjects
+{
+public:
+       using Extensions = std::vector<vk::VkExtensionProperties>;
+
+                                                                                               NativeObjects   (Context&                                               context,
+                                                                                                                                const Extensions&                              supportedExtensions,
+                                                                                                                                vk::wsi::Type                                  wsiType,
+                                                                                                                                size_t                                                 windowCount = 1u,
+                                                                                                                                const tcu::Maybe<tcu::UVec2>&  initialWindowSize = tcu::nothing<tcu::UVec2>());
+
+                                                                                               NativeObjects   (NativeObjects&& other);
+
+       vk::wsi::Display&                                                       getDisplay              () const;
+
+       vk::wsi::Window&                                                        getWindow               (size_t index = 0u) const;
+
+       static de::MovePtr<vk::wsi::Window>                     createWindow    (const vk::wsi::Display& display, const tcu::Maybe<tcu::UVec2>& initialSize);
+
+       static de::MovePtr<vk::wsi::Display>            createDisplay   (const vk::Platform&    platform,
+                                                                                                                                const Extensions&              supportedExtensions,
+                                                                                                                                vk::wsi::Type                  wsiType);
+private:
+       de::UniquePtr<vk::wsi::Display>                         display;
+       std::vector<de::MovePtr<vk::wsi::Window>>       windows;
+
+};
+
+} // wsi
+} // vkt
+
+#endif // _VKTNATIVEOBJECTSUTIL_HPP
index 69508fe..9ffd0f2 100644 (file)
@@ -26,6 +26,7 @@
 #include "vktTestCaseUtil.hpp"
 #include "vktTestGroupUtil.hpp"
 #include "vktCustomInstancesDevices.hpp"
+#include "vktNativeObjectsUtil.hpp"
 
 #include "vkDefs.hpp"
 #include "vkPlatform.hpp"
@@ -222,56 +223,6 @@ struct DeviceHelper
        }
 };
 
-MovePtr<Display> createDisplay (const vk::Platform&    platform,
-                                                               const Extensions&       supportedExtensions,
-                                                               Type                            wsiType)
-{
-       try
-       {
-               return MovePtr<Display>(platform.createWsiDisplay(wsiType));
-       }
-       catch (const tcu::NotSupportedError& e)
-       {
-               if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
-                   platform.hasDisplay(wsiType))
-               {
-                       // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
-                       // must support creating native display & window for that WSI type.
-                       throw tcu::TestError(e.getMessage());
-               }
-               else
-                       throw;
-       }
-}
-
-MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
-{
-       try
-       {
-               return MovePtr<Window>(display.createWindow(initialSize));
-       }
-       catch (const tcu::NotSupportedError& e)
-       {
-               // See createDisplay - assuming that wsi::Display was supported platform port
-               // should also support creating a window.
-               throw tcu::TestError(e.getMessage());
-       }
-}
-
-struct NativeObjects
-{
-       const UniquePtr<Display>        display;
-       const UniquePtr<Window>         window;
-
-       NativeObjects (Context&                         context,
-                                  const Extensions&    supportedExtensions,
-                                  Type                                 wsiType,
-                                  const Maybe<UVec2>&  initialWindowSize = tcu::nothing<UVec2>())
-               : display       (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
-               , window        (createWindow(*display, initialWindowSize))
-       {}
-};
-
 enum TestDimension
 {
        TEST_DIMENSION_MIN_IMAGE_COUNT = 0,     //!< Test all supported image counts
@@ -465,8 +416,8 @@ tcu::TestStatus basicExtensionTest (Context& context, Type wsiType)
 {
        const tcu::UVec2                                desiredSize             (256, 256);
        const InstanceHelper                    instHelper              (context, wsiType);
-       const NativeObjects                             native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-       const Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+       const NativeObjects                             native                  (context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+       const Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const DeviceHelper                              devHelper               (context, instHelper.vki, instHelper.instance, *surface);
 
        if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
@@ -507,7 +458,7 @@ tcu::TestStatus colorspaceCompareTest (Context& context, TestParams params)
        const tcu::UVec2                                        desiredSize                             (256, 256);
        const InstanceHelper                            instHelper                              (context, params.wsiType);
        const NativeObjects                                     native                                  (context, instHelper.supportedExtensions, params.wsiType, tcu::just(desiredSize));
-       const Unique<VkSurfaceKHR>                      surface                                 (createSurface(instHelper.vki, instHelper.instance, params.wsiType, *native.display, *native.window));
+       const Unique<VkSurfaceKHR>                      surface                                 (createSurface(instHelper.vki, instHelper.instance, params.wsiType, native.getDisplay(), native.getWindow()));
        const DeviceHelper                                      devHelper                               (context, instHelper.vki, instHelper.instance, *surface);
 
        const vector<VkSurfaceFormatKHR>        queriedFormats          =       getPhysicalDeviceSurfaceFormats(instHelper.vki,
@@ -815,8 +766,8 @@ tcu::TestStatus surfaceFormatRenderTests (Context& context, Type wsiType)
 {
        const tcu::UVec2                                        desiredSize             (256, 256);
        const InstanceHelper                            instHelper              (context, wsiType);
-       const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-       const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+       const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+       const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const DeviceHelper                                      devHelper               (context, instHelper.vki, instHelper.instance, *surface);
 
        if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
@@ -836,8 +787,8 @@ tcu::TestStatus surfaceFormatRenderWithHdrTests (Context& context, Type wsiType)
 {
        const tcu::UVec2                                        desiredSize             (256, 256);
        const InstanceHelper                            instHelper              (context, wsiType);
-       const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
-       const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+       const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
+       const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const DeviceHelper                                      devHelper               (context, instHelper.vki, instHelper.instance, *surface);
 
        if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
index 7fd072e..bf67b8c 100644 (file)
@@ -238,15 +238,15 @@ de::MovePtr<Window> createWindow (const Display& display,
        }
 }
 
-struct NativeObjects
+struct NativeObjectsFS
 {
        const de::UniquePtr<Display>    display;
        tcu::UVec2                                              windowSize;
        const de::UniquePtr<Window>             window;
 
-       NativeObjects (Context&                         context,
-                                  const Extensions&    supportedExtensions,
-                                  Type                                 wsiType)
+       NativeObjectsFS (Context&                               context,
+                                        const Extensions&              supportedExtensions,
+                                        Type                                   wsiType)
                : display               (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
                , windowSize    (getFullScreenSize(wsiType, *display.get(), tcu::UVec2(256U, 256U)))
                , window                (createWindow(*display, windowSize))
@@ -341,7 +341,7 @@ tcu::TestStatus fullScreenExclusiveTest(Context& context,
                TCU_THROW(NotSupportedError, "Extension VK_EXT_full_screen_exclusive not supported");
 
        const InstanceHelper                                            instHelper(context, testParams.wsiType);
-       const NativeObjects                                                     native(context, instHelper.supportedExtensions, testParams.wsiType);
+       const NativeObjectsFS                                           native(context, instHelper.supportedExtensions, testParams.wsiType);
        const Unique<VkSurfaceKHR>                                      surface(createSurface(instHelper.vki, instHelper.instance, testParams.wsiType, *native.display, *native.window));
        const DeviceHelper                                                      devHelper(context, instHelper.vki, instHelper.instance, *surface);
        const std::vector<VkExtensionProperties>        deviceExtensions(enumerateDeviceExtensionProperties(instHelper.vki, devHelper.physicalDevice, DE_NULL));
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiPresentIdWaitTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiPresentIdWaitTests.cpp
new file mode 100644 (file)
index 0000000..f32d7ee
--- /dev/null
@@ -0,0 +1,1102 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2019 Valve Corporation.
+ *
+ * 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 Tests for the present id and present wait extensions.
+ *//*--------------------------------------------------------------------*/
+
+#include "vktWsiPresentIdWaitTests.hpp"
+#include "vktTestCase.hpp"
+#include "vktCustomInstancesDevices.hpp"
+#include "vktNativeObjectsUtil.hpp"
+
+#include "vkQueryUtil.hpp"
+#include "vkDeviceUtil.hpp"
+#include "vkWsiUtil.hpp"
+#include "vkMemUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkRefUtil.hpp"
+
+#include "tcuTestContext.hpp"
+#include "tcuPlatform.hpp"
+#include "tcuCommandLine.hpp"
+#include "tcuTestLog.hpp"
+
+#include "deDefs.hpp"
+
+#include <vector>
+#include <string>
+#include <set>
+#include <sstream>
+#include <chrono>
+#include <algorithm>
+#include <utility>
+#include <limits>
+
+using std::vector;
+using std::string;
+using std::set;
+
+namespace vkt
+{
+namespace wsi
+{
+
+namespace
+{
+
+// Handy time constants in nanoseconds.
+constexpr deUint64 k10sec      = 10000000000ull;
+constexpr deUint64 k1sec       =  1000000000ull;
+
+// 100 milliseconds, way above 1/50 seconds for systems with 50Hz ticks.
+// This should also take into account possible measure deviations due to the machine being loaded.
+constexpr deUint64 kMargin     =   100000000ull;
+
+using TimeoutRange = std::pair<deInt64, deInt64>;
+
+// Calculate acceptable timeout range based on indicated timeout and taking into account kMargin.
+TimeoutRange calcTimeoutRange (deUint64 timeout)
+{
+       constexpr auto kUnsignedMax     = std::numeric_limits<deUint64>::max();
+       constexpr auto kSignedMax       = static_cast<deUint64>(std::numeric_limits<deInt64>::max());
+
+       // Watch for over- and under-flows.
+       deUint64 timeoutMin = ((timeout < kMargin) ? 0ull : (timeout - kMargin));
+       deUint64 timeoutMax = ((kUnsignedMax - timeout < kMargin) ? kUnsignedMax : timeout + kMargin);
+
+       // Make sure casting is safe.
+       timeoutMin = de::min(kSignedMax, timeoutMin);
+       timeoutMax = de::min(kSignedMax, timeoutMax);
+
+       return TimeoutRange(static_cast<deInt64>(timeoutMin), static_cast<deInt64>(timeoutMax));
+}
+
+class PresentIdWaitInstance : public TestInstance
+{
+public:
+                                                               PresentIdWaitInstance   (Context& context, vk::wsi::Type wsiType) : TestInstance(context), m_wsiType(wsiType) {}
+       virtual                                         ~PresentIdWaitInstance  (void) {}
+
+       virtual tcu::TestStatus         iterate                                 (void);
+
+       virtual tcu::TestStatus         run                                             (const vk::DeviceInterface&                             vkd,
+                                                                                                                vk::VkDevice                                                   device,
+                                                                                                                vk::VkQueue                                                    queue,
+                                                                                                                vk::VkCommandPool                                              commandPool,
+                                                                                                                vk::VkSwapchainKHR                                             swapchain,
+                                                                                                                size_t                                                                 swapchainSize,
+                                                                                                                const vk::wsi::WsiTriangleRenderer&    renderer) = 0;
+
+       // Subclasses will need to implement a static method like this one indicating which extensions they need.
+       static vector<const char*>      requiredDeviceExts              (void) { return vector<const char*>(); }
+
+       // Subclasses will also need to implement this nonstatic method returning the same information as above.
+       virtual vector<const char*>     getRequiredDeviceExts   (void) = 0;
+
+protected:
+       vk::wsi::Type                           m_wsiType;
+};
+
+vector<const char*> getRequiredInstanceExtensions (vk::wsi::Type wsiType)
+{
+       vector<const char*> extensions;
+       extensions.push_back("VK_KHR_surface");
+       extensions.push_back(getExtensionName(wsiType));
+       return extensions;
+}
+
+CustomInstance createInstanceWithWsi (Context&                                                 context,
+                                                                         vk::wsi::Type                                         wsiType,
+                                                                         const vk::VkAllocationCallbacks*      pAllocator      = nullptr)
+{
+       const auto version                              = context.getUsedApiVersion();
+       const auto requiredExtensions   = getRequiredInstanceExtensions(wsiType);
+
+       vector<string> requestedExtensions;
+       for (const auto& extensionName : requiredExtensions)
+       {
+               if (!vk::isCoreInstanceExtension(version, extensionName))
+                       requestedExtensions.push_back(extensionName);
+       }
+
+       return vkt::createCustomInstanceWithExtensions(context, requestedExtensions, pAllocator);
+}
+
+struct InstanceHelper
+{
+       const vector<vk::VkExtensionProperties> supportedExtensions;
+       CustomInstance                                                  instance;
+       const vk::InstanceDriver&                               vki;
+
+       InstanceHelper (Context& context, vk::wsi::Type wsiType, const vk::VkAllocationCallbacks* pAllocator = nullptr)
+               : supportedExtensions   (enumerateInstanceExtensionProperties(context.getPlatformInterface(), nullptr))
+               , instance                              (createInstanceWithWsi(context, wsiType, pAllocator))
+               , vki                                   (instance.getDriver())
+       {}
+};
+
+vector<const char*> getMandatoryDeviceExtensions ()
+{
+       vector<const char*> mandatoryExtensions;
+       mandatoryExtensions.push_back("VK_KHR_swapchain");
+       return mandatoryExtensions;
+}
+
+vk::Move<vk::VkDevice> createDeviceWithWsi (const vk::PlatformInterface&                               vkp,
+                                                                                       vk::VkInstance                                                          instance,
+                                                                                       const vk::InstanceInterface&                            vki,
+                                                                                       vk::VkPhysicalDevice                                            physicalDevice,
+                                                                                       const vector<const char*>&                                      extraExtensions,
+                                                                                       const deUint32                                                          queueFamilyIndex,
+                                                                                       bool                                                                            validationEnabled,
+                                                                                       const vk::VkAllocationCallbacks*                        pAllocator = nullptr)
+{
+       const float                                                     queuePriorities[]       = { 1.0f };
+       const vk::VkDeviceQueueCreateInfo       queueInfos[]            =
+       {
+               {
+                       vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+                       nullptr,
+                       (vk::VkDeviceQueueCreateFlags)0,
+                       queueFamilyIndex,
+                       DE_LENGTH_OF_ARRAY(queuePriorities),
+                       &queuePriorities[0]
+               }
+       };
+       vk::VkPhysicalDeviceFeatures            features;
+       std::vector<const char*>                        extensions                      = extraExtensions;
+       const auto                                                      mandatoryExtensions     = getMandatoryDeviceExtensions();
+
+       for (const auto& ext : mandatoryExtensions)
+               extensions.push_back(ext);
+
+       deMemset(&features, 0, sizeof(features));
+       const vk::VkDeviceCreateInfo            deviceParams    =
+       {
+               vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+               nullptr,
+               (vk::VkDeviceCreateFlags)0,
+               DE_LENGTH_OF_ARRAY(queueInfos),
+               &queueInfos[0],
+               0u,                                                                                     // enabledLayerCount
+               nullptr,                                                                        // ppEnabledLayerNames
+               static_cast<deUint32>(extensions.size()),       // enabledExtensionCount
+               extensions.data(),                                                      // ppEnabledExtensionNames
+               &features
+       };
+
+       return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
+}
+
+struct DeviceHelper
+{
+       const vk::VkPhysicalDevice              physicalDevice;
+       const deUint32                                  queueFamilyIndex;
+       const vk::Unique<vk::VkDevice>  device;
+       const vk::DeviceDriver                  vkd;
+       const vk::VkQueue                               queue;
+
+       DeviceHelper (Context&                                          context,
+                                 const vk::InstanceInterface&          vki,
+                                 vk::VkInstance                                        instance,
+                                 const vector<vk::VkSurfaceKHR>&       surfaces,
+                                 const vector<const char*>&            extraExtensions,
+                                 const vk::VkAllocationCallbacks*      pAllocator = nullptr)
+               : physicalDevice        (chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
+               , queueFamilyIndex      (vk::wsi::chooseQueueFamilyIndex(vki, physicalDevice, surfaces))
+               , device                        (createDeviceWithWsi(context.getPlatformInterface(),
+                                                                                                instance,
+                                                                                                vki,
+                                                                                                physicalDevice,
+                                                                                                extraExtensions,
+                                                                                                queueFamilyIndex,
+                                                                                                context.getTestContext().getCommandLine().isValidationEnabled(),
+                                                                                                pAllocator))
+               , vkd                           (context.getPlatformInterface(), instance, *device)
+               , queue                         (getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
+       {
+       }
+};
+
+vk::VkSwapchainCreateInfoKHR getBasicSwapchainParameters (vk::wsi::Type                                        wsiType,
+                                                                                                                 const vk::InstanceInterface&  vki,
+                                                                                                                 vk::VkPhysicalDevice                  physicalDevice,
+                                                                                                                 vk::VkSurfaceKHR                              surface,
+                                                                                                                 const tcu::UVec2&                             desiredSize,
+                                                                                                                 deUint32                                              desiredImageCount)
+{
+       const vk::VkSurfaceCapabilitiesKHR              capabilities            = vk::wsi::getPhysicalDeviceSurfaceCapabilities(vki,
+                                                                                                                                                                                                  physicalDevice,
+                                                                                                                                                                                                  surface);
+       const vector<vk::VkSurfaceFormatKHR>    formats                         = vk::wsi::getPhysicalDeviceSurfaceFormats(vki,
+                                                                                                                                                                                         physicalDevice,
+                                                                                                                                                                                         surface);
+       const vk::wsi::PlatformProperties&              platformProperties      = vk::wsi::getPlatformProperties(wsiType);
+       const vk::VkSurfaceTransformFlagBitsKHR transform                       = (capabilities.supportedTransforms & vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
+       const vk::VkSwapchainCreateInfoKHR              parameters                      =
+       {
+               vk::VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+               nullptr,
+               (vk::VkSwapchainCreateFlagsKHR)0,
+               surface,
+               de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount),
+               formats[0].format,
+               formats[0].colorSpace,
+               (platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
+                       ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),
+               1u,                                                                     // imageArrayLayers
+               vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+               vk::VK_SHARING_MODE_EXCLUSIVE,
+               0u,
+               nullptr,
+               transform,
+               vk::VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+               vk::VK_PRESENT_MODE_FIFO_KHR,
+               VK_FALSE,                                                       // clipped
+               (vk::VkSwapchainKHR)0                           // oldSwapchain
+       };
+
+       return parameters;
+}
+
+using CommandBufferSp  = de::SharedPtr<vk::Unique<vk::VkCommandBuffer>>;
+using FenceSp                  = de::SharedPtr<vk::Unique<vk::VkFence>>;
+using SemaphoreSp              = de::SharedPtr<vk::Unique<vk::VkSemaphore>>;
+
+vector<FenceSp> createFences (const vk::DeviceInterface&       vkd,
+                                                         const vk::VkDevice                    device,
+                                                         size_t                                                numFences)
+{
+       vector<FenceSp> fences(numFences);
+
+       for (size_t ndx = 0; ndx < numFences; ++ndx)
+               fences[ndx] = FenceSp(new vk::Unique<vk::VkFence>(createFence(vkd, device, vk::VK_FENCE_CREATE_SIGNALED_BIT)));
+
+       return fences;
+}
+
+vector<SemaphoreSp> createSemaphores (const vk::DeviceInterface&       vkd,
+                                                                         const vk::VkDevice                    device,
+                                                                         size_t                                                numSemaphores)
+{
+       vector<SemaphoreSp> semaphores(numSemaphores);
+
+       for (size_t ndx = 0; ndx < numSemaphores; ++ndx)
+               semaphores[ndx] = SemaphoreSp(new vk::Unique<vk::VkSemaphore>(createSemaphore(vkd, device)));
+
+       return semaphores;
+}
+
+vector<CommandBufferSp> allocateCommandBuffers (const vk::DeviceInterface&             vkd,
+                                                                                               const vk::VkDevice                              device,
+                                                                                               const vk::VkCommandPool                 commandPool,
+                                                                                               const vk::VkCommandBufferLevel  level,
+                                                                                               const size_t                                    numCommandBuffers)
+{
+       vector<CommandBufferSp>                         buffers         (numCommandBuffers);
+
+       for (size_t ndx = 0; ndx < numCommandBuffers; ++ndx)
+               buffers[ndx] = CommandBufferSp(new vk::Unique<vk::VkCommandBuffer>(allocateCommandBuffer(vkd, device, commandPool, level)));
+
+       return buffers;
+}
+
+class FrameStreamObjects
+{
+public:
+       struct FrameObjects
+       {
+               const vk::VkFence&                      renderCompleteFence;
+               const vk::VkSemaphore&          renderCompleteSemaphore;
+               const vk::VkSemaphore&          imageAvailableSemaphore;
+               const vk::VkCommandBuffer&      commandBuffer;
+       };
+
+       FrameStreamObjects (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkCommandPool cmdPool, size_t maxQueuedFrames)
+               : renderingCompleteFences               (createFences(vkd, device, maxQueuedFrames))
+               , renderingCompleteSemaphores   (createSemaphores(vkd, device, maxQueuedFrames))
+               , imageAvailableSemaphores              (createSemaphores(vkd, device, maxQueuedFrames))
+               , commandBuffers                                (allocateCommandBuffers(vkd, device, cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames))
+               , m_maxQueuedFrames                             (maxQueuedFrames)
+               , m_nextFrame                                   (0u)
+       {}
+
+       size_t frameNumber (void) const { DE_ASSERT(m_nextFrame > 0u); return m_nextFrame - 1u; }
+
+       FrameObjects newFrame ()
+       {
+               const size_t mod = m_nextFrame % m_maxQueuedFrames;
+               FrameObjects ret =
+               {
+                       **renderingCompleteFences[mod],
+                       **renderingCompleteSemaphores[mod],
+                       **imageAvailableSemaphores[mod],
+                       **commandBuffers[mod],
+               };
+               ++m_nextFrame;
+               return ret;
+       }
+
+private:
+       const vector<FenceSp>                   renderingCompleteFences;
+       const vector<SemaphoreSp>               renderingCompleteSemaphores;
+       const vector<SemaphoreSp>               imageAvailableSemaphores;
+       const vector<CommandBufferSp>   commandBuffers;
+
+       const size_t    m_maxQueuedFrames;
+       size_t                  m_nextFrame;
+};
+
+tcu::TestStatus PresentIdWaitInstance::iterate (void)
+{
+       const tcu::UVec2                                                desiredSize                                     (256, 256);
+       const InstanceHelper                                    instHelper                                      (m_context, m_wsiType);
+       const NativeObjects                                             native                                          (m_context, instHelper.supportedExtensions, m_wsiType, 1u, tcu::just(desiredSize));
+       const vk::Unique<vk::VkSurfaceKHR>              surface                                         (createSurface(instHelper.vki, instHelper.instance, m_wsiType, native.getDisplay(), native.getWindow()));
+       const DeviceHelper                                              devHelper                                       (m_context, instHelper.vki, instHelper.instance, vector<vk::VkSurfaceKHR>(1u, surface.get()), getRequiredDeviceExts());
+       const vk::DeviceInterface&                              vkd                                                     = devHelper.vkd;
+       const vk::VkDevice                                              device                                          = *devHelper.device;
+       vk::SimpleAllocator                                             allocator                                       (vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
+       const vk::VkSwapchainCreateInfoKHR              swapchainInfo                           = getBasicSwapchainParameters(m_wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
+       const vk::Unique<vk::VkSwapchainKHR>    swapchain                                       (vk::createSwapchainKHR(vkd, device, &swapchainInfo));
+       const vector<vk::VkImage>                               swapchainImages                         = vk::wsi::getSwapchainImages(vkd, device, *swapchain);
+       const vk::Unique<vk::VkCommandPool>             commandPool                                     (createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
+       const vk::wsi::WsiTriangleRenderer              renderer                                        (vkd,
+                                                                                                                                                device,
+                                                                                                                                                allocator,
+                                                                                                                                                m_context.getBinaryCollection(),
+                                                                                                                                                false,
+                                                                                                                                                swapchainImages,
+                                                                                                                                                swapchainImages,
+                                                                                                                                                swapchainInfo.imageFormat,
+                                                                                                                                                tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
+
+       try
+       {
+               return run(vkd, device, devHelper.queue, commandPool.get(), swapchain.get(), swapchainImages.size(), renderer);
+       }
+       catch (...)
+       {
+               // Make sure device is idle before destroying resources
+               vkd.deviceWaitIdle(device);
+               throw;
+       }
+
+       return tcu::TestStatus(QP_TEST_RESULT_INTERNAL_ERROR, "Reached unreachable code");
+}
+
+struct PresentParameters
+{
+       tcu::Maybe<deUint64>            presentId;
+       tcu::Maybe<vk::VkResult>        expectedResult;
+};
+
+struct WaitParameters
+{
+       deUint64        presentId;
+       deUint64        timeout; // Nanoseconds.
+       bool            timeoutExpected;
+};
+
+// This structure represents a set of present operations to be run followed by a set of wait operations to be run after them.
+// When running the present operations, the present id can be provided, together with an optional expected result to be checked.
+// When runing the wait operations, the present id must be provided together with a timeout and an indication of whether the operation is expected to time out or not.
+struct PresentAndWaitOps
+{
+       vector<PresentParameters>       presentOps;
+       vector<WaitParameters>          waitOps;
+};
+
+// Parent class for VK_KHR_present_id and VK_KHR_present_wait simple tests.
+class PresentIdWaitSimpleInstance : public PresentIdWaitInstance
+{
+public:
+       PresentIdWaitSimpleInstance(Context& context, vk::wsi::Type wsiType, const vector<PresentAndWaitOps>& sequence)
+               : PresentIdWaitInstance(context, wsiType), m_sequence(sequence)
+       {}
+
+       virtual ~PresentIdWaitSimpleInstance() {}
+
+       virtual tcu::TestStatus         run                                             (const vk::DeviceInterface&                             vkd,
+                                                                                                                vk::VkDevice                                                   device,
+                                                                                                                vk::VkQueue                                                    queue,
+                                                                                                                vk::VkCommandPool                                              commandPool,
+                                                                                                                vk::VkSwapchainKHR                                             swapchain,
+                                                                                                                size_t                                                                 swapchainSize,
+                                                                                                                const vk::wsi::WsiTriangleRenderer&    renderer);
+protected:
+       const vector<PresentAndWaitOps> m_sequence;
+};
+
+// Waits for the appropriate fences, acquires swapchain image, records frame and submits it to the given queue, signaling the appropriate frame semaphores.
+// Returns the image index from the swapchain.
+deUint32 recordAndSubmitFrame (FrameStreamObjects::FrameObjects& frameObjects, const vk::wsi::WsiTriangleRenderer& triangleRenderer, const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkSwapchainKHR swapchain, size_t swapchainSize, vk::VkQueue queue, size_t frameNumber, tcu::TestLog& testLog)
+{
+       // Wait and reset the render complete fence to avoid having too many submitted frames.
+       VK_CHECK(vkd.waitForFences(device, 1u, &frameObjects.renderCompleteFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
+       VK_CHECK(vkd.resetFences(device, 1, &frameObjects.renderCompleteFence));
+
+       // Acquire swapchain image.
+       deUint32 imageNdx = std::numeric_limits<deUint32>::max();
+       const vk::VkResult acquireResult = vkd.acquireNextImageKHR(device,
+                                                                                                                               swapchain,
+                                                                                                                               std::numeric_limits<deUint64>::max(),
+                                                                                                                               frameObjects.imageAvailableSemaphore,
+                                                                                                                               (vk::VkFence)0,
+                                                                                                                               &imageNdx);
+
+       if (acquireResult == vk::VK_SUBOPTIMAL_KHR)
+               testLog << tcu::TestLog::Message << "Got " << acquireResult << " at frame " << frameNumber << tcu::TestLog::EndMessage;
+       else
+               VK_CHECK(acquireResult);
+       TCU_CHECK(static_cast<size_t>(imageNdx) < swapchainSize);
+
+       // Submit frame to the queue.
+       const vk::VkPipelineStageFlags  waitDstStage    = vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+       const vk::VkSubmitInfo                  submitInfo              =
+       {
+               vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
+               nullptr,
+               1u,
+               &frameObjects.imageAvailableSemaphore,
+               &waitDstStage,
+               1u,
+               &frameObjects.commandBuffer,
+               1u,
+               &frameObjects.renderCompleteSemaphore,
+       };
+
+       triangleRenderer.recordFrame(frameObjects.commandBuffer, imageNdx, static_cast<deUint32>(frameNumber));
+       VK_CHECK(vkd.queueSubmit(queue, 1u, &submitInfo, frameObjects.renderCompleteFence));
+
+       return imageNdx;
+}
+
+tcu::TestStatus PresentIdWaitSimpleInstance::run (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkQueue queue, vk::VkCommandPool commandPool, vk::VkSwapchainKHR swapchain, size_t swapchainSize, const vk::wsi::WsiTriangleRenderer& renderer)
+{
+       const size_t            maxQueuedFrames         = swapchainSize*2;
+       FrameStreamObjects      frameStreamObjects      (vkd, device, commandPool, maxQueuedFrames);
+
+       for (const auto& step : m_sequence)
+       {
+               for (const auto& presentOp : step.presentOps)
+               {
+                       // Get objects for the next frame.
+                       FrameStreamObjects::FrameObjects frameObjects = frameStreamObjects.newFrame();
+
+                       // Record and submit new frame.
+                       deUint32 imageNdx = recordAndSubmitFrame(frameObjects, renderer, vkd, device, swapchain, swapchainSize, queue, frameStreamObjects.frameNumber(), m_context.getTestContext().getLog());
+
+                       // Present rendered frame.
+                       const vk::VkPresentIdKHR                presentId               =
+                       {
+                               vk::VK_STRUCTURE_TYPE_PRESENT_ID_KHR,                                                   // VkStructureType              sType;
+                               nullptr,                                                                                                                // const void*                  pNext;
+                               (presentOp.presentId ? 1u : 0u),                                                                // deUint32                             swapchainCount;
+                               (presentOp.presentId ? &presentOp.presentId.get() : nullptr ),  // const deUint64*              pPresentIds;
+                       };
+
+                       const vk::VkPresentInfoKHR              presentInfo             =
+                       {
+                               vk::VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+                               (presentOp.presentId ? &presentId : nullptr),
+                               1u,
+                               &frameObjects.renderCompleteSemaphore,
+                               1u,
+                               &swapchain,
+                               &imageNdx,
+                               nullptr,
+                       };
+
+                       vk::VkResult result = vkd.queuePresentKHR(queue, &presentInfo);
+
+                       if (presentOp.expectedResult)
+                       {
+                               const vk::VkResult expected = presentOp.expectedResult.get();
+                               if ((expected == vk::VK_SUCCESS && result != vk::VK_SUCCESS && result != vk::VK_SUBOPTIMAL_KHR) ||
+                                       (expected != vk::VK_SUCCESS && result != expected))
+                               {
+                                       std::ostringstream msg;
+                                       msg << "Got " << result << " while expecting " << expected << " after presenting with ";
+                                       if (presentOp.presentId)
+                                               msg << "id " << presentOp.presentId.get();
+                                       else
+                                               msg << "no id";
+                                       TCU_FAIL(msg.str());
+                               }
+                       }
+               }
+
+               // Wait operations.
+               for (const auto& waitOp : step.waitOps)
+               {
+                       auto                    before          = std::chrono::high_resolution_clock::now();
+                       vk::VkResult    waitResult      = vkd.waitForPresentKHR(device, swapchain, waitOp.presentId, waitOp.timeout);
+                       auto                    after           = std::chrono::high_resolution_clock::now();
+                       auto                    diff            = std::chrono::nanoseconds(after - before).count();
+
+                       if (waitOp.timeoutExpected)
+                       {
+                               if (waitResult != vk::VK_TIMEOUT)
+                               {
+                                       std::ostringstream msg;
+                                       msg << "Got " << waitResult << " while expecting a timeout in vkWaitForPresentKHR call";
+                                       TCU_FAIL(msg.str());
+                               }
+
+                               const auto timeoutRange = calcTimeoutRange(waitOp.timeout);
+
+                               if (diff < timeoutRange.first || diff > timeoutRange.second)
+                               {
+                                       std::ostringstream msg;
+                                       msg << "vkWaitForPresentKHR waited for " << diff << " nanoseconds with a timeout of " << waitOp.timeout << " nanoseconds";
+                                       TCU_FAIL(msg.str());
+                               }
+                       }
+                       else if (waitResult != vk::VK_SUCCESS)
+                       {
+                               std::ostringstream msg;
+                               msg << "Got " << waitResult << " while expecting success in vkWaitForPresentKHR call";
+                               TCU_FAIL(msg.str());
+                       }
+               }
+       }
+
+       // Wait until device is idle.
+       VK_CHECK(vkd.deviceWaitIdle(device));
+
+       return tcu::TestStatus::pass("Pass");
+}
+
+// Parent class for VK_KHR_present_id simple tests.
+class PresentIdInstance : public PresentIdWaitSimpleInstance
+{
+public:
+       PresentIdInstance(Context& context, vk::wsi::Type wsiType, const vector<PresentAndWaitOps>& sequence)
+               : PresentIdWaitSimpleInstance(context, wsiType, sequence)
+       {}
+
+       virtual ~PresentIdInstance() {}
+
+       static vector<const char*>      requiredDeviceExts (void)
+       {
+               vector<const char*> extensions;
+               extensions.push_back("VK_KHR_present_id");
+               return extensions;
+       }
+
+       virtual vector<const char*> getRequiredDeviceExts (void)
+       {
+               return requiredDeviceExts();
+       }
+};
+
+// Parent class for VK_KHR_present_wait simple tests.
+class PresentWaitInstance : public PresentIdWaitSimpleInstance
+{
+public:
+       PresentWaitInstance(Context& context, vk::wsi::Type wsiType, const vector<PresentAndWaitOps>& sequence)
+               : PresentIdWaitSimpleInstance(context, wsiType, sequence)
+       {}
+
+       virtual ~PresentWaitInstance() {}
+
+       static vector<const char*>      requiredDeviceExts (void)
+       {
+               vector<const char*> extensions;
+               extensions.push_back("VK_KHR_present_id");
+               extensions.push_back("VK_KHR_present_wait");
+               return extensions;
+       }
+
+       virtual vector<const char*>     getRequiredDeviceExts (void)
+       {
+               return requiredDeviceExts();
+       }
+};
+
+class PresentIdZeroInstance : public PresentIdInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentIdZeroInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentIdInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentIdZeroInstance::sequence =
+{
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just<deUint64>(0), tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+               },
+       },
+};
+
+class PresentIdIncreasingInstance : public PresentIdInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentIdIncreasingInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentIdInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentIdIncreasingInstance::sequence =
+{
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just<deUint64>(1),                                                       tcu::just(vk::VK_SUCCESS) },
+                       { tcu::just(std::numeric_limits<deUint64>::max()),      tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+               },
+       },
+};
+
+class PresentIdInterleavedInstance : public PresentIdInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentIdInterleavedInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentIdInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentIdInterleavedInstance::sequence =
+{
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just<deUint64>(0),                                                       tcu::just(vk::VK_SUCCESS) },
+                       { tcu::just<deUint64>(1),                                                       tcu::just(vk::VK_SUCCESS) },
+                       { tcu::nothing<deUint64>(),                                                     tcu::just(vk::VK_SUCCESS) },
+                       { tcu::just(std::numeric_limits<deUint64>::max()),      tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+               },
+       },
+};
+
+class PresentWaitSingleFrameInstance : public PresentWaitInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentWaitSingleFrameInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentWaitInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentWaitSingleFrameInstance::sequence =
+{
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just<deUint64>(1), tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+                       { 1ull, k10sec, false },
+               },
+       },
+};
+
+class PresentWaitPastFrameInstance : public PresentWaitInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentWaitPastFrameInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentWaitInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentWaitPastFrameInstance::sequence =
+{
+       // Start with present id 1.
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just<deUint64>(1), tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+                       { 1ull, k10sec, false },
+                       { 1ull, 0ull,   false },
+               },
+       },
+       // Then the maximum value. Both waiting for id 1 and the max id should work.
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just(std::numeric_limits<deUint64>::max()), tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+                       { 1ull,                                 0ull,   false },
+                       { 1ull,                                 k10sec, false },
+                       { std::numeric_limits<deUint64>::max(), k10sec, false },
+                       { std::numeric_limits<deUint64>::max(), 0ull,   false },
+               },
+       },
+       // Submit some frames without id after having used the maximum value. This should also work.
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::nothing<deUint64>(),     tcu::just(vk::VK_SUCCESS) },
+                       { tcu::just<deUint64>(0),       tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+               },
+       },
+};
+
+class PresentWaitNoFramesInstance : public PresentWaitInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentWaitNoFramesInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentWaitInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentWaitNoFramesInstance::sequence =
+{
+       { // PresentAndWaitOps
+               {       // presentOps vector
+               },
+               {       // waitOps vector
+                       { 1ull, 0ull,  true },
+                       { 1ull, k1sec, true },
+               },
+       },
+};
+
+class PresentWaitNoFrameIdInstance : public PresentWaitInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentWaitNoFrameIdInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentWaitInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentWaitNoFrameIdInstance::sequence =
+{
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just<deUint64>(0), tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+                       { 1ull, 0ull,  true },
+                       { 1ull, k1sec, true },
+               },
+       },
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::nothing<deUint64>(), tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+                       { 1ull, 0ull,  true },
+                       { 1ull, k1sec, true },
+               },
+       },
+};
+
+class PresentWaitFutureFrameInstance : public PresentWaitInstance
+{
+public:
+       static const vector<PresentAndWaitOps> sequence;
+
+       PresentWaitFutureFrameInstance (Context& context, vk::wsi::Type wsiType)
+               : PresentWaitInstance(context, wsiType, sequence)
+       {}
+};
+
+const vector<PresentAndWaitOps> PresentWaitFutureFrameInstance::sequence =
+{
+       { // PresentAndWaitOps
+               {       // presentOps vector
+                       { tcu::just<deUint64>(1), tcu::just(vk::VK_SUCCESS) },
+               },
+               {       // waitOps vector
+                       { std::numeric_limits<deUint64>::max(), k1sec, true },
+                       { std::numeric_limits<deUint64>::max(), 0ull,  true },
+                       { 2ull,                                 0ull,  true },
+                       { 2ull,                                 k1sec, true },
+               },
+       },
+};
+
+// Instance with two windows and surfaces to check present ids are not mixed up.
+class PresentWaitDualInstance : public TestInstance
+{
+public:
+                                                               PresentWaitDualInstance         (Context& context, vk::wsi::Type wsiType) : TestInstance(context), m_wsiType(wsiType) {}
+       virtual                                         ~PresentWaitDualInstance        (void) {}
+
+       virtual tcu::TestStatus         iterate                                         (void);
+
+       static vector<const char*>      requiredDeviceExts                      (void)
+       {
+               vector<const char*> extensions;
+               extensions.push_back("VK_KHR_present_id");
+               extensions.push_back("VK_KHR_present_wait");
+               return extensions;
+       }
+
+       virtual vector<const char*>     getRequiredDeviceExts           (void)
+       {
+               return requiredDeviceExts();
+       }
+
+protected:
+       vk::wsi::Type                           m_wsiType;
+};
+
+struct IdAndWait
+{
+       deUint64        presentId;
+       bool            wait;
+};
+
+struct DualIdAndWait
+{
+       IdAndWait idWait1;
+       IdAndWait idWait2;
+};
+
+tcu::TestStatus PresentWaitDualInstance::iterate (void)
+{
+       const tcu::UVec2                                                desiredSize                                     (256, 256);
+       const InstanceHelper                                    instHelper                                      (m_context, m_wsiType);
+       const NativeObjects                                             native                                          (m_context, instHelper.supportedExtensions, m_wsiType, 2u, tcu::just(desiredSize));
+       const vk::Unique<vk::VkSurfaceKHR>              surface1                                        (createSurface(instHelper.vki, instHelper.instance, m_wsiType, native.getDisplay(), native.getWindow(0)));
+       const vk::Unique<vk::VkSurfaceKHR>              surface2                                        (createSurface(instHelper.vki, instHelper.instance, m_wsiType, native.getDisplay(), native.getWindow(1)));
+       const DeviceHelper                                              devHelper                                       (m_context, instHelper.vki, instHelper.instance, vector<vk::VkSurfaceKHR>{surface1.get(), surface2.get()}, getRequiredDeviceExts());
+       const vk::DeviceInterface&                              vkd                                                     = devHelper.vkd;
+       const vk::VkDevice                                              device                                          = *devHelper.device;
+       vk::SimpleAllocator                                             allocator                                       (vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
+       const vk::VkSwapchainCreateInfoKHR              swapchainInfo1                          = getBasicSwapchainParameters(m_wsiType, instHelper.vki, devHelper.physicalDevice, surface1.get(), desiredSize, 2);
+       const vk::VkSwapchainCreateInfoKHR              swapchainInfo2                          = getBasicSwapchainParameters(m_wsiType, instHelper.vki, devHelper.physicalDevice, surface2.get(), desiredSize, 2);
+       const vk::Unique<vk::VkSwapchainKHR>    swapchain1                                      (vk::createSwapchainKHR(vkd, device, &swapchainInfo1));
+       const vk::Unique<vk::VkSwapchainKHR>    swapchain2                                      (vk::createSwapchainKHR(vkd, device, &swapchainInfo2));
+       const vector<vk::VkImage>                               swapchainImages1                        = vk::wsi::getSwapchainImages(vkd, device, swapchain1.get());
+       const vector<vk::VkImage>                               swapchainImages2                        = vk::wsi::getSwapchainImages(vkd, device, swapchain2.get());
+       const vk::Unique<vk::VkCommandPool>             commandPool                                     (createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
+       const vk::wsi::WsiTriangleRenderer              renderer1                                       (vkd,
+                                                                                                                                                device,
+                                                                                                                                                allocator,
+                                                                                                                                                m_context.getBinaryCollection(),
+                                                                                                                                                false,
+                                                                                                                                                swapchainImages1,
+                                                                                                                                                swapchainImages1,
+                                                                                                                                                swapchainInfo1.imageFormat,
+                                                                                                                                                tcu::UVec2(swapchainInfo1.imageExtent.width, swapchainInfo1.imageExtent.height));
+       const vk::wsi::WsiTriangleRenderer              renderer2                                       (vkd,
+                                                                                                                                                device,
+                                                                                                                                                allocator,
+                                                                                                                                                m_context.getBinaryCollection(),
+                                                                                                                                                false,
+                                                                                                                                                swapchainImages2,
+                                                                                                                                                swapchainImages2,
+                                                                                                                                                swapchainInfo2.imageFormat,
+                                                                                                                                                tcu::UVec2(swapchainInfo2.imageExtent.width, swapchainInfo2.imageExtent.height));
+       tcu::TestLog&                                                   testLog                                         = m_context.getTestContext().getLog();
+
+       try
+       {
+               const size_t            maxQueuedFrames         = swapchainImages1.size()*2;
+               FrameStreamObjects      frameStreamObjects1     (vkd, device, commandPool.get(), maxQueuedFrames);
+               FrameStreamObjects      frameStreamObjects2     (vkd, device, commandPool.get(), maxQueuedFrames);
+
+               // Increasing ids for both swapchains, waiting on some to make sure we do not time out unexpectedly.
+               const vector<DualIdAndWait> sequence =
+               {
+                       {
+                               { 1ull, false },
+                               { 2ull, true  },
+                       },
+                       {
+                               { 4ull, true  },
+                               { 3ull, false },
+                       },
+                       {
+                               { 5ull, true  },
+                               { 6ull, true  },
+                       },
+               };
+
+               for (const auto& step : sequence)
+               {
+                       // Get objects for the next frames.
+                       FrameStreamObjects::FrameObjects frameObjects1 = frameStreamObjects1.newFrame();
+                       FrameStreamObjects::FrameObjects frameObjects2 = frameStreamObjects2.newFrame();
+
+                       // Record and submit frame.
+                       deUint32 imageNdx1 = recordAndSubmitFrame(frameObjects1, renderer1, vkd, device, swapchain1.get(), swapchainImages1.size(), devHelper.queue, frameStreamObjects1.frameNumber(), testLog);
+                       deUint32 imageNdx2 = recordAndSubmitFrame(frameObjects2, renderer2, vkd, device, swapchain2.get(), swapchainImages2.size(), devHelper.queue, frameStreamObjects2.frameNumber(), testLog);
+
+                       // Present both images at the same time with their corresponding ids.
+                       const deUint64                          presentIdsArr[] = { step.idWait1.presentId, step.idWait2.presentId };
+                       const vk::VkPresentIdKHR        presentId               =
+                       {
+                               vk::VK_STRUCTURE_TYPE_PRESENT_ID_KHR,                                                   // VkStructureType              sType;
+                               nullptr,                                                                                                                // const void*                  pNext;
+                               static_cast<deUint32>(DE_LENGTH_OF_ARRAY(presentIdsArr)),               // deUint32                             swapchainCount;
+                               presentIdsArr,                                                                                                  // const deUint64*              pPresentIds;
+                       };
+
+                       const vk::VkSemaphore           semaphoreArr[]  = { frameObjects1.renderCompleteSemaphore, frameObjects2.renderCompleteSemaphore };
+                       const vk::VkSwapchainKHR        swapchainArr[]  = { swapchain1.get(), swapchain2.get() };
+                       const deUint32                          imgIndexArr[]   = { imageNdx1, imageNdx2 };
+                       const vk::VkPresentInfoKHR      presentInfo             =
+                       {
+                               vk::VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+                               &presentId,
+                               static_cast<deUint32>(DE_LENGTH_OF_ARRAY(semaphoreArr)),
+                               semaphoreArr,
+                               static_cast<deUint32>(DE_LENGTH_OF_ARRAY(swapchainArr)),
+                               swapchainArr,
+                               imgIndexArr,
+                               nullptr,
+                       };
+
+                       VK_CHECK(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
+
+                       const IdAndWait* idWaitArr[] = { &step.idWait1, &step.idWait2 };
+                       for (int i = 0; i < DE_LENGTH_OF_ARRAY(idWaitArr); ++i)
+                       {
+                               if (idWaitArr[i]->wait)
+                                       VK_CHECK(vkd.waitForPresentKHR(device, swapchainArr[i], idWaitArr[i]->presentId, k10sec));
+                       }
+               }
+
+               // Wait until device is idle.
+               VK_CHECK(vkd.deviceWaitIdle(device));
+
+               return tcu::TestStatus::pass("Pass");
+       }
+       catch (...)
+       {
+               // Make sure device is idle before destroying resources
+               vkd.deviceWaitIdle(device);
+               throw;
+       }
+
+       return tcu::TestStatus(QP_TEST_RESULT_INTERNAL_ERROR, "Reached unreachable code");
+}
+
+// Templated class for every instance type.
+template <class T>     // T is the test instance class.
+class PresentIdWaitCase : public TestCase
+{
+public:
+                                                       PresentIdWaitCase       (vk::wsi::Type wsiType, tcu::TestContext& ctx, const std::string& name, const std::string& description);
+       virtual                                 ~PresentIdWaitCase      (void) {}
+       virtual void                    initPrograms            (vk::SourceCollections& programCollection) const;
+       virtual TestInstance*   createInstance          (Context& context) const;
+       virtual void                    checkSupport            (Context& context) const;
+
+protected:
+       vk::wsi::Type                   m_wsiType;
+};
+
+template <class T>
+PresentIdWaitCase<T>::PresentIdWaitCase (vk::wsi::Type wsiType, tcu::TestContext& ctx, const std::string& name, const std::string& description)
+       : TestCase(ctx, name, description), m_wsiType(wsiType)
+{
+}
+
+template <class T>
+void PresentIdWaitCase<T>::initPrograms (vk::SourceCollections& programCollection) const
+{
+       vk::wsi::WsiTriangleRenderer::getPrograms(programCollection);
+}
+
+template <class T>
+TestInstance* PresentIdWaitCase<T>::createInstance (Context& context) const
+{
+       return new T(context, m_wsiType);
+}
+
+template <class T>
+void PresentIdWaitCase<T>::checkSupport (Context& context) const
+{
+       // Check instance extension support.
+       const auto instanceExtensions = getRequiredInstanceExtensions(m_wsiType);
+       for (const auto& ext : instanceExtensions)
+       {
+               if (!context.isInstanceFunctionalitySupported(ext))
+                       TCU_THROW(NotSupportedError, ext + string(" is not supported"));
+       }
+
+       // Check device extension support.
+       const auto& vki                 = context.getInstanceInterface();
+       const auto  physDev             = context.getPhysicalDevice();
+       const auto  supportedDeviceExts = vk::enumerateDeviceExtensionProperties(vki, physDev, nullptr);
+       const auto  mandatoryDeviceExts = getMandatoryDeviceExtensions();
+
+       auto checkedDeviceExts = T::requiredDeviceExts();
+       for (const auto& ext : mandatoryDeviceExts)
+               checkedDeviceExts.push_back(ext);
+
+       for (const auto& ext : checkedDeviceExts)
+       {
+               if (!vk::isExtensionSupported(supportedDeviceExts, vk::RequiredExtension(ext)))
+                       TCU_THROW(NotSupportedError, ext + string(" is not supported"));
+       }
+}
+
+void createPresentIdTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
+{
+       testGroup->addChild(new PresentIdWaitCase<PresentIdZeroInstance>                (wsiType, testGroup->getTestContext(), "zero",                  "Use present id zero"));
+       testGroup->addChild(new PresentIdWaitCase<PresentIdIncreasingInstance>  (wsiType, testGroup->getTestContext(), "increasing",    "Use increasing present ids"));
+       testGroup->addChild(new PresentIdWaitCase<PresentIdInterleavedInstance> (wsiType, testGroup->getTestContext(), "interleaved",   "Use increasing present ids interleaved with no ids"));
+}
+
+void createPresentWaitTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
+{
+       testGroup->addChild(new PresentIdWaitCase<PresentWaitSingleFrameInstance>       (wsiType, testGroup->getTestContext(), "single_no_timeout",     "Present single frame with no expected timeout"));
+       testGroup->addChild(new PresentIdWaitCase<PresentWaitPastFrameInstance>         (wsiType, testGroup->getTestContext(), "past_no_timeout",       "Wait for past frame with no expected timeout"));
+       testGroup->addChild(new PresentIdWaitCase<PresentWaitNoFramesInstance>          (wsiType, testGroup->getTestContext(), "no_frames",                     "Expect timeout before submitting any frame"));
+       testGroup->addChild(new PresentIdWaitCase<PresentWaitNoFrameIdInstance>         (wsiType, testGroup->getTestContext(), "no_frame_id",           "Expect timeout after submitting frames with no id"));
+       testGroup->addChild(new PresentIdWaitCase<PresentWaitFutureFrameInstance>       (wsiType, testGroup->getTestContext(), "future_frame",          "Expect timeout when waiting for a future frame"));
+       testGroup->addChild(new PresentIdWaitCase<PresentWaitDualInstance>                      (wsiType, testGroup->getTestContext(), "two_swapchains",        "Smoke test using two windows, surfaces and swapchains"));
+}
+
+} // anonymous
+
+void createPresentIdWaitTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
+{
+       de::MovePtr<tcu::TestCaseGroup> idGroup         (new tcu::TestCaseGroup(testGroup->getTestContext(), "id",              "VK_KHR_present_id tests"));
+       de::MovePtr<tcu::TestCaseGroup> waitGroup       (new tcu::TestCaseGroup(testGroup->getTestContext(), "wait",    "VK_KHR_present_wait tests"));
+
+       createPresentIdTests    (idGroup.get(),         wsiType);
+       createPresentWaitTests  (waitGroup.get(),       wsiType);
+
+       testGroup->addChild(idGroup.release());
+       testGroup->addChild(waitGroup.release());
+}
+
+} // wsi
+} // vkt
+
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiPresentIdWaitTests.hpp b/external/vulkancts/modules/vulkan/wsi/vktWsiPresentIdWaitTests.hpp
new file mode 100644 (file)
index 0000000..89b522a
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _VKTWSIPRESENTIDWAITTESTS_HPP
+#define _VKTWSIPRESENTIDWAITTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2019 The Khronos Group Inc.
+ * Copyright (c) 2019 Valve Corporation.
+ *
+ * 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 Tests for the present id and present wait extensions.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+#include "vkDefs.hpp"
+
+namespace vkt
+{
+namespace wsi
+{
+
+void createPresentIdWaitTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType);
+
+} // wsi
+} // vkt
+
+#endif // _VKTWSIPRESENTIDWAITTESTS_HPP
index 861c26c..0cb5455 100644 (file)
@@ -26,6 +26,7 @@
 #include "vktTestCaseUtil.hpp"
 #include "vktTestGroupUtil.hpp"
 #include "vktCustomInstancesDevices.hpp"
+#include "vktNativeObjectsUtil.hpp"
 
 #include "vkDefs.hpp"
 #include "vkPlatform.hpp"
@@ -221,61 +222,11 @@ struct InstanceHelper
        {}
 };
 
-MovePtr<Display> createDisplay (const vk::Platform&    platform,
-                                                               const Extensions&       supportedExtensions,
-                                                               Type                            wsiType)
-{
-       try
-       {
-               return MovePtr<Display>(platform.createWsiDisplay(wsiType));
-       }
-       catch (const tcu::NotSupportedError& e)
-       {
-               if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
-                   platform.hasDisplay(wsiType))
-               {
-                       // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
-                       // must support creating native display & window for that WSI type.
-                       throw tcu::TestError(e.getMessage());
-               }
-               else
-                       throw;
-       }
-}
-
-MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
-{
-       try
-       {
-               return MovePtr<Window>(display.createWindow(initialSize));
-       }
-       catch (const tcu::NotSupportedError& e)
-       {
-               // See createDisplay - assuming that wsi::Display was supported platform port
-               // should also support creating a window.
-               throw tcu::TestError(e.getMessage());
-       }
-}
-
-struct NativeObjects
-{
-       const UniquePtr<Display>        display;
-       const UniquePtr<Window>         window;
-
-       NativeObjects (Context&                         context,
-                                  const Extensions&    supportedExtensions,
-                                  Type                                 wsiType,
-                                  const Maybe<UVec2>&  initialWindowSize = tcu::nothing<UVec2>())
-               : display       (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
-               , window        (createWindow(*display, initialWindowSize))
-       {}
-};
-
 tcu::TestStatus createSurfaceTest (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 Unique<VkSurfaceKHR>      surface         (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
 
        return tcu::TestStatus::pass("Creating surface succeeded");
 }
@@ -284,7 +235,7 @@ tcu::TestStatus querySurfaceCounterTest (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 Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vk::InstanceInterface&    vki                             = context.getInstanceInterface();
        const vk::VkPhysicalDevice              physicalDevice  = context.getPhysicalDevice();
 
@@ -318,8 +269,8 @@ tcu::TestStatus createSurfaceCustomAllocatorTest (Context& context, Type wsiType
                const Unique<VkSurfaceKHR>      surface         (createSurface(instHelper.vki,
                                                                                                                           instHelper.instance,
                                                                                                                           wsiType,
-                                                                                                                          *native.display,
-                                                                                                                          *native.window,
+                                                                                                                          native.getDisplay(),
+                                                                                                                          native.getWindow(),
                                                                                                                           allocationRecorder.getCallbacks()));
 
                if (!validateAndLog(log,
@@ -364,8 +315,8 @@ tcu::TestStatus createSurfaceSimulateOOMTest (Context& context, Type wsiType)
                        const Unique<VkSurfaceKHR>      surface         (createSurface(instHelper.vki,
                                                                                                                                   instHelper.instance,
                                                                                                                                   wsiType,
-                                                                                                                                  *native.display,
-                                                                                                                                  *native.window,
+                                                                                                                                  native.getDisplay(),
+                                                                                                                                  native.getWindow(),
                                                                                                                                   failingAllocator.getCallbacks()));
 
                        if (!validateAndLog(log,
@@ -413,7 +364,7 @@ tcu::TestStatus querySurfaceSupportTest (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 Unique<VkSurfaceKHR>              surface                                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices                 = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
        // On Android surface must be supported by all devices and queue families
@@ -447,9 +398,10 @@ tcu::TestStatus queryPresentationSupportTest(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 Unique<VkSurfaceKHR>              surface                                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices                 = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
+       native.getDisplay();
        for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
        {
                const VkPhysicalDevice          physicalDevice          = physicalDevices[deviceNdx];
@@ -457,7 +409,7 @@ tcu::TestStatus queryPresentationSupportTest(Context& context, Type wsiType)
 
                for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
                {
-                       VkBool32        isPresentationSupported = getPhysicalDevicePresentationSupport(instHelper.vki, physicalDevice, queueFamilyNdx, wsiType, *native.display);
+                       VkBool32        isPresentationSupported = getPhysicalDevicePresentationSupport(instHelper.vki, physicalDevice, queueFamilyNdx, wsiType, native.getDisplay());
                        VkBool32        isSurfaceSupported              = getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
 
                        log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": presentation "
@@ -541,7 +493,7 @@ tcu::TestStatus querySurfaceCapabilitiesTest (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 Unique<VkSurfaceKHR>              surface                                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices                 = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
        for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
@@ -569,7 +521,7 @@ tcu::TestStatus querySurfaceCapabilities2Test (Context& context, Type wsiType)
 
        const InstanceHelper                    instHelper                              (context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
        const NativeObjects                             native                                  (context, instHelper.supportedExtensions, wsiType);
-       const Unique<VkSurfaceKHR>              surface                                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+       const Unique<VkSurfaceKHR>              surface                                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices                 = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
        for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
@@ -630,7 +582,7 @@ tcu::TestStatus querySurfaceProtectedCapabilitiesTest (Context& context, Type ws
        requiredExtensions.push_back("VK_KHR_surface_protected_capabilities");
        const InstanceHelper            instHelper              (context, wsiType, requiredExtensions);
        const NativeObjects             native                  (context, instHelper.supportedExtensions, wsiType);
-       const Unique<VkSurfaceKHR>      surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+       const Unique<VkSurfaceKHR>      surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices         = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
        for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
@@ -723,7 +675,7 @@ tcu::TestStatus querySurfaceFormatsTest (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 Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
        for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
@@ -769,7 +721,7 @@ tcu::TestStatus querySurfaceFormats2Test (Context& context, Type wsiType)
 
        const InstanceHelper                    instHelper              (context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
        const NativeObjects                             native                  (context, instHelper.supportedExtensions, wsiType);
-       const Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+       const Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
        for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
@@ -879,7 +831,7 @@ tcu::TestStatus querySurfacePresentModesTest (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 Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const vector<VkPhysicalDevice>  physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
 
        for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
@@ -1027,7 +979,7 @@ tcu::TestStatus queryDevGroupSurfacePresentModesTest (Context& context, Type wsi
        tcu::ResultCollector                                    results                         (log);
        const InstanceHelper                                    instHelper                      (context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
        const NativeObjects                                             native                          (context, instHelper.supportedExtensions, wsiType);
-       const Unique<VkSurfaceKHR>                              surface                         (createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
+       const Unique<VkSurfaceKHR>                              surface                         (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
        const float                                                             queuePriority           = 1.0f;
        const tcu::CommandLine&                                 cmdLine                         = context.getTestContext().getCommandLine();
        const deUint32                                                  devGroupIdx                     = cmdLine.getVKDeviceGroupId() - 1;
@@ -1180,9 +1132,9 @@ tcu::TestStatus createSurfaceInitialSizeTest (Context& context, Type wsiType)
 
        const InstanceHelper                    instHelper              (context, wsiType);
 
-       const UniquePtr<Display>                nativeDisplay   (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
-                                                                                                                                  instHelper.supportedExtensions,
-                                                                                                                                  wsiType));
+       const UniquePtr<Display>                nativeDisplay   (NativeObjects::createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
+                                                                                                                                                                 instHelper.supportedExtensions,
+                                                                                                                                                                 wsiType));
 
        const vector<VkPhysicalDevice>  physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
        const UVec2                                             sizes[]                 =
@@ -1197,7 +1149,7 @@ tcu::TestStatus createSurfaceInitialSizeTest (Context& context, Type wsiType)
        for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
        {
                const UVec2&                            testSize                = sizes[sizeNdx];
-               const UniquePtr<Window>         nativeWindow    (createWindow(*nativeDisplay, tcu::just(testSize)));
+               const UniquePtr<Window>         nativeWindow    (NativeObjects::createWindow(*nativeDisplay, tcu::just(testSize)));
                const Unique<VkSurfaceKHR>      surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
 
                for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
@@ -1224,10 +1176,10 @@ tcu::TestStatus resizeSurfaceTest (Context& context, Type wsiType)
 
        const InstanceHelper                    instHelper              (context, wsiType);
 
-       const UniquePtr<Display>                nativeDisplay   (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
-                                                                                                                                  instHelper.supportedExtensions,
-                                                                                                                                  wsiType));
-       UniquePtr<Window>                               nativeWindow    (createWindow(*nativeDisplay, tcu::nothing<UVec2>()));
+       const UniquePtr<Display>                nativeDisplay   (NativeObjects::createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
+                                                                                                                                                                 instHelper.supportedExtensions,
+                                                                                                                                                                 wsiType));
+       UniquePtr<Window>                               nativeWindow    (NativeObjects::createWindow(*nativeDisplay, tcu::nothing<UVec2>()));
 
        const vector<VkPhysicalDevice>  physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
        const Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
index bd19e55..8482828 100644 (file)
@@ -26,6 +26,7 @@
 #include "vktTestCaseUtil.hpp"
 #include "vktTestGroupUtil.hpp"
 #include "vktCustomInstancesDevices.hpp"
+#include "vktNativeObjectsUtil.hpp"
 
 #include "vkDefs.hpp"
 #include "vkPlatform.hpp"
@@ -333,80 +334,6 @@ struct MultiQueueDeviceHelper
        }
 };
 
-MovePtr<Display> createDisplay (const vk::Platform&    platform,
-                                                               const Extensions&       supportedExtensions,
-                                                               Type                            wsiType)
-{
-       try
-       {
-               return MovePtr<Display>(platform.createWsiDisplay(wsiType));
-       }
-       catch (const tcu::NotSupportedError& e)
-       {
-               if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
-                       platform.hasDisplay(wsiType))
-               {
-                       // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
-                       // must support creating native display & window for that WSI type.
-                       throw tcu::TestError(e.getMessage());
-               }
-               else
-                       throw;
-       }
-}
-
-MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
-{
-       try
-       {
-               return MovePtr<Window>(display.createWindow(initialSize));
-       }
-       catch (const tcu::NotSupportedError& e)
-       {
-               // See createDisplay - assuming that wsi::Display was supported platform port
-               // should also support creating a window.
-               throw tcu::TestError(e.getMessage());
-       }
-}
-
-class NativeObjects
-{
-private:
-       UniquePtr<Display>              display;
-       vector<MovePtr<Window>> windows;
-
-public:
-       NativeObjects (Context&                         context,
-                                  const Extensions&    supportedExtensions,
-                                  Type                                 wsiType,
-                                  size_t                               windowCount = 1u,
-                                  const Maybe<UVec2>&  initialWindowSize = tcu::nothing<UVec2>())
-               : display       (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
-       {
-               DE_ASSERT(windowCount > 0u);
-               for (size_t i = 0; i < windowCount; ++i)
-                       windows.emplace_back(createWindow(*display, initialWindowSize));
-       }
-
-       NativeObjects (NativeObjects&& other)
-               : display       (other.display.move())
-               , windows       ()
-       {
-               windows.swap(other.windows);
-       }
-
-       Display&        getDisplay      () const
-       {
-               return *display;
-       }
-
-       Window&         getWindow       (size_t index = 0u) const
-       {
-               DE_ASSERT(index < windows.size());
-               return *windows[index];
-       }
-};
-
 enum TestDimension
 {
        TEST_DIMENSION_MIN_IMAGE_COUNT = 0,     //!< Test all supported image counts
index aaa0942..02e5f5c 100644 (file)
@@ -34,6 +34,7 @@
 #include "vktWsiSharedPresentableImageTests.hpp"
 #include "vktWsiColorSpaceTests.hpp"
 #include "vktWsiFullScreenExclusiveTests.hpp"
+#include "vktWsiPresentIdWaitTests.hpp"
 
 namespace vkt
 {
@@ -53,6 +54,7 @@ void createTypeSpecificTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiTy
        addTestGroup(testGroup, "colorspace",                           "ColorSpace tests",                                                     createColorSpaceTests,                          wsiType);
        addTestGroup(testGroup, "colorspace_compare",           "ColorSpace compare tests",                                     createColorspaceCompareTests,           wsiType);
        addTestGroup(testGroup, "full_screen_exclusive",        "VK_EXT_full_screen_exclusive tests",           createFullScreenExclusiveTests,         wsiType);
+       addTestGroup(testGroup, "present_id_wait",                      "VK_KHR_present_(id|wait) tests",                       createPresentIdWaitTests,                       wsiType);
 }
 
 void createWsiTests (tcu::TestCaseGroup* apiTests)
index bf4c7c3..c1f3660 100644 (file)
@@ -440,6 +440,15 @@ dEQP-VK.wsi.xlib.full_screen_exclusive.default
 dEQP-VK.wsi.xlib.full_screen_exclusive.allowed
 dEQP-VK.wsi.xlib.full_screen_exclusive.disallowed
 dEQP-VK.wsi.xlib.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.xlib.present_id_wait.id.zero
+dEQP-VK.wsi.xlib.present_id_wait.id.increasing
+dEQP-VK.wsi.xlib.present_id_wait.id.interleaved
+dEQP-VK.wsi.xlib.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.xlib.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.xlib.present_id_wait.wait.no_frames
+dEQP-VK.wsi.xlib.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.xlib.present_id_wait.wait.future_frame
+dEQP-VK.wsi.xlib.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.xcb.surface.create
 dEQP-VK.wsi.xcb.surface.create_custom_allocator
 dEQP-VK.wsi.xcb.surface.create_simulate_oom
@@ -882,6 +891,15 @@ dEQP-VK.wsi.xcb.full_screen_exclusive.default
 dEQP-VK.wsi.xcb.full_screen_exclusive.allowed
 dEQP-VK.wsi.xcb.full_screen_exclusive.disallowed
 dEQP-VK.wsi.xcb.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.xcb.present_id_wait.id.zero
+dEQP-VK.wsi.xcb.present_id_wait.id.increasing
+dEQP-VK.wsi.xcb.present_id_wait.id.interleaved
+dEQP-VK.wsi.xcb.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.xcb.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.xcb.present_id_wait.wait.no_frames
+dEQP-VK.wsi.xcb.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.xcb.present_id_wait.wait.future_frame
+dEQP-VK.wsi.xcb.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.wayland.surface.create
 dEQP-VK.wsi.wayland.surface.create_custom_allocator
 dEQP-VK.wsi.wayland.surface.create_simulate_oom
@@ -1323,6 +1341,15 @@ dEQP-VK.wsi.wayland.full_screen_exclusive.default
 dEQP-VK.wsi.wayland.full_screen_exclusive.allowed
 dEQP-VK.wsi.wayland.full_screen_exclusive.disallowed
 dEQP-VK.wsi.wayland.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.wayland.present_id_wait.id.zero
+dEQP-VK.wsi.wayland.present_id_wait.id.increasing
+dEQP-VK.wsi.wayland.present_id_wait.id.interleaved
+dEQP-VK.wsi.wayland.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.wayland.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.wayland.present_id_wait.wait.no_frames
+dEQP-VK.wsi.wayland.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.wayland.present_id_wait.wait.future_frame
+dEQP-VK.wsi.wayland.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.android.surface.create
 dEQP-VK.wsi.android.surface.create_custom_allocator
 dEQP-VK.wsi.android.surface.create_simulate_oom
@@ -2485,6 +2512,15 @@ dEQP-VK.wsi.android.full_screen_exclusive.default
 dEQP-VK.wsi.android.full_screen_exclusive.allowed
 dEQP-VK.wsi.android.full_screen_exclusive.disallowed
 dEQP-VK.wsi.android.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.android.present_id_wait.id.zero
+dEQP-VK.wsi.android.present_id_wait.id.increasing
+dEQP-VK.wsi.android.present_id_wait.id.interleaved
+dEQP-VK.wsi.android.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.android.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.android.present_id_wait.wait.no_frames
+dEQP-VK.wsi.android.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.android.present_id_wait.wait.future_frame
+dEQP-VK.wsi.android.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.win32.surface.create
 dEQP-VK.wsi.win32.surface.create_custom_allocator
 dEQP-VK.wsi.win32.surface.create_simulate_oom
@@ -2927,6 +2963,15 @@ dEQP-VK.wsi.win32.full_screen_exclusive.default
 dEQP-VK.wsi.win32.full_screen_exclusive.allowed
 dEQP-VK.wsi.win32.full_screen_exclusive.disallowed
 dEQP-VK.wsi.win32.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.win32.present_id_wait.id.zero
+dEQP-VK.wsi.win32.present_id_wait.id.increasing
+dEQP-VK.wsi.win32.present_id_wait.id.interleaved
+dEQP-VK.wsi.win32.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.win32.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.win32.present_id_wait.wait.no_frames
+dEQP-VK.wsi.win32.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.win32.present_id_wait.wait.future_frame
+dEQP-VK.wsi.win32.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.macos.surface.create
 dEQP-VK.wsi.macos.surface.create_custom_allocator
 dEQP-VK.wsi.macos.surface.create_simulate_oom
@@ -3369,6 +3414,15 @@ dEQP-VK.wsi.macos.full_screen_exclusive.default
 dEQP-VK.wsi.macos.full_screen_exclusive.allowed
 dEQP-VK.wsi.macos.full_screen_exclusive.disallowed
 dEQP-VK.wsi.macos.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.macos.present_id_wait.id.zero
+dEQP-VK.wsi.macos.present_id_wait.id.increasing
+dEQP-VK.wsi.macos.present_id_wait.id.interleaved
+dEQP-VK.wsi.macos.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.macos.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.macos.present_id_wait.wait.no_frames
+dEQP-VK.wsi.macos.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.macos.present_id_wait.wait.future_frame
+dEQP-VK.wsi.macos.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.headless.surface.create
 dEQP-VK.wsi.headless.surface.create_custom_allocator
 dEQP-VK.wsi.headless.surface.create_simulate_oom
@@ -3810,6 +3864,15 @@ dEQP-VK.wsi.headless.full_screen_exclusive.default
 dEQP-VK.wsi.headless.full_screen_exclusive.allowed
 dEQP-VK.wsi.headless.full_screen_exclusive.disallowed
 dEQP-VK.wsi.headless.full_screen_exclusive.application_controlled
+dEQP-VK.wsi.headless.present_id_wait.id.zero
+dEQP-VK.wsi.headless.present_id_wait.id.increasing
+dEQP-VK.wsi.headless.present_id_wait.id.interleaved
+dEQP-VK.wsi.headless.present_id_wait.wait.single_no_timeout
+dEQP-VK.wsi.headless.present_id_wait.wait.past_no_timeout
+dEQP-VK.wsi.headless.present_id_wait.wait.no_frames
+dEQP-VK.wsi.headless.present_id_wait.wait.no_frame_id
+dEQP-VK.wsi.headless.present_id_wait.wait.future_frame
+dEQP-VK.wsi.headless.present_id_wait.wait.two_swapchains
 dEQP-VK.wsi.display.get_display_properties
 dEQP-VK.wsi.display.get_display_plane_properties
 dEQP-VK.wsi.display.get_display_plane_supported_displays
index bd0c693..6526b2f 100644 (file)
@@ -96,3 +96,5 @@ VK_EXT_color_write_enable                                     DEVICE
 VK_VALVE_mutable_descriptor_type                       DEVICE
 VK_EXT_multi_draw                                                      DEVICE
 VK_KHR_shader_subgroup_uniform_control_flow    DEVICE
+VK_KHR_present_id                                                      DEVICE
+VK_KHR_present_wait                                                    DEVICE
index 1f47b7d..f30c336 100644 (file)
@@ -145,4 +145,6 @@ VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT                   FEATURES ( shaderImageInt64A
 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT                           FEATURES ( shaderImageFloat32Atomics )                                                  REQUIREMENTS ( VK_EXT_shader_atomic_float physicalDeviceShaderAtomicFloatFeaturesEXT.sparseImageFloat32Atomics )
 VkPhysicalDeviceShaderAtomicFloatFeaturesEXT                           FEATURES ( shaderImageFloat32AtomicAdd )                                                REQUIREMENTS ( VK_EXT_shader_atomic_float physicalDeviceShaderAtomicFloatFeaturesEXT.sparseImageFloat32AtomicAdd )
 VkPhysicalDeviceMultiDrawFeaturesEXT                                           FEATURES ( multiDraw )                                                                                  REQUIREMENTS ( VK_EXT_multi_draw )
-VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR    FEATURES ( shaderSubgroupUniformControlFlow )                                   REQUIREMENTS ( VK_KHR_shader_subgroup_uniform_control_flow )
\ No newline at end of file
+VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR    FEATURES ( shaderSubgroupUniformControlFlow )                                   REQUIREMENTS ( VK_KHR_shader_subgroup_uniform_control_flow )
+VkPhysicalDevicePresentIdFeaturesKHR                                           FEATURES ( presentId )                                                                                  REQUIREMENTS ( VK_KHR_present_id )
+VkPhysicalDevicePresentWaitFeaturesKHR                                         FEATURES ( presentWait )                                                                                REQUIREMENTS ( VK_KHR_present_wait )