Add swapchain tests for the VK_KHR_protected_memory extension
authorPeter Gal <pgal.u-szeged@partner.samsung.com>
Fri, 1 Sep 2017 18:12:27 +0000 (20:12 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Tue, 3 Oct 2017 10:48:17 +0000 (06:48 -0400)
New tests:
* dEQP-VK.protected_memory.interaction.wsi.*

Components: Vulkan
VK-GL-CTS issue: 118

Change-Id: Ife48da5098299fd9d747a7b74208136c7f3413e0
(cherry picked from commit 9991ff0e4baea2316a93ec07e06f44ff279d2774)

AndroidGen.mk
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/protected_memory/CMakeLists.txt
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.hpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.hpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.hpp [new file with mode: 0644]
external/vulkancts/mustpass/1.1.0/vk-default.txt

index 862beff..93738d6 100644 (file)
@@ -170,6 +170,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemBlitImageTests.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemBufferValidator.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemClearColorImageTests.cpp \
+       external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemCopyBufferToImageTests.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemCopyImageTests.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemCopyImageToBufferTests.cpp \
@@ -179,6 +180,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStorageBufferTests.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemTests.cpp \
        external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp \
+       external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.cpp \
        external/vulkancts/modules/vulkan/query_pool/vktQueryPoolOcclusionTests.cpp \
        external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp \
        external/vulkancts/modules/vulkan/query_pool/vktQueryPoolTests.cpp \
index 8274f9c..5efc639 100755 (executable)
@@ -273790,3 +273790,69 @@ dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswa
 dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswap_8
 dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswap_9
 dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswap_10
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.render.basic
index c312b9d..d2103f6 100644 (file)
@@ -2,6 +2,7 @@ include_directories(..)
 
 set(DEQP_VK_PROTECTED_MEMORY_SRCS
        vktProtectedMemContext.hpp
+       vktProtectedMemContext.cpp
        vktProtectedMemUtils.cpp
        vktProtectedMemUtils.hpp
        vktProtectedMemTests.cpp
@@ -30,6 +31,8 @@ set(DEQP_VK_PROTECTED_MEMORY_SRCS
        vktProtectedMemStorageBufferTests.hpp
        vktProtectedMemShaderImageAccessTests.cpp
        vktProtectedMemShaderImageAccessTests.hpp
+       vktProtectedMemWsiSwapchainTests.cpp
+       vktProtectedMemWsiSwapchainTests.hpp
        vktProtectedMemTests.cpp
        vktProtectedMemTests.hpp
        )
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.cpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemContext.cpp
new file mode 100644 (file)
index 0000000..e20e619
--- /dev/null
@@ -0,0 +1,68 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 Protected Memory
+ *//*--------------------------------------------------------------------*/
+#include "vktProtectedMemContext.hpp"
+
+namespace vkt
+{
+namespace ProtectedMem
+{
+
+ProtectedContext::ProtectedContext     (Context&                                               ctx,
+                                                                        const std::vector<std::string> instanceExtensions,
+                                                                        const std::vector<std::string> deviceExtensions)
+       : m_context                             (ctx)
+       , m_interface                   (m_context.getPlatformInterface())
+       , m_instance                    (makeProtectedMemInstance(m_interface, m_context, instanceExtensions))
+       , m_vki                                 (m_interface, *m_instance)
+       , m_phyDevice                   (vk::chooseDevice(m_vki, *m_instance, m_context.getTestContext().getCommandLine()))
+       , m_queueFamilyIndex    (chooseProtectedMemQueueFamilyIndex(m_vki, m_phyDevice))
+       , m_device                              (makeProtectedMemDevice(m_vki, m_phyDevice, m_queueFamilyIndex, ctx.getUsedApiVersion(), deviceExtensions))
+       , m_allocator                   (createAllocator())
+       , m_deviceDriver                (m_vki, *m_device)
+       , m_queue                               (getProtectedQueue(m_deviceDriver, *m_device, m_queueFamilyIndex, 0))
+{
+}
+
+ProtectedContext::ProtectedContext     (Context&                                               ctx,
+                                                                        vk::wsi::Type                                  wsiType,
+                                                                        vk::wsi::Display&                              display,
+                                                                        vk::wsi::Window&                               window,
+                                                                        const std::vector<std::string> instanceExtensions,
+                                                                        const std::vector<std::string> deviceExtensions)
+       : m_context                             (ctx)
+       , m_interface                   (m_context.getPlatformInterface())
+       , m_instance                    (makeProtectedMemInstance(m_interface, m_context, instanceExtensions))
+       , m_vki                                 (m_interface, *m_instance)
+       , m_phyDevice                   (vk::chooseDevice(m_vki, *m_instance, m_context.getTestContext().getCommandLine()))
+       , m_surface                             (vk::wsi::createSurface(m_vki, *m_instance, wsiType, display, window))
+       , m_queueFamilyIndex    (chooseProtectedMemQueueFamilyIndex(m_vki, m_phyDevice, *m_surface))
+       , m_device                              (makeProtectedMemDevice(m_vki, m_phyDevice, m_queueFamilyIndex, ctx.getUsedApiVersion(), deviceExtensions))
+       , m_allocator                   (createAllocator())
+       , m_deviceDriver                (m_vki, *m_device)
+       , m_queue                               (getProtectedQueue(m_deviceDriver, *m_device, m_queueFamilyIndex, 0))
+{
+}
+
+} // ProtectedMem
+} // vkt
index c4e4c5e..3f2384f 100644 (file)
 #include "vktProtectedMemUtils.hpp"
 #include "tcuCommandLine.hpp"
 #include "vkMemUtil.hpp"
+#include "vkWsiUtil.hpp"
 
 namespace vkt
 {
 namespace ProtectedMem
 {
 
-
 class ProtectedContext
 {
 public:
-               ProtectedContext        (Context& ctx)
-                       : m_context                             (ctx)
-                       , m_interface                   (m_context.getPlatformInterface())
-                       , m_instance                    (makeProtectedMemInstance(m_interface, m_context))
-                       , m_vki                                 (m_interface, *m_instance)
-                       , m_phyDevice                   (vk::chooseDevice(m_vki, *m_instance, m_context.getTestContext().getCommandLine()))
-                       , m_queueFamilyIndex    (chooseProtectedMemQueueFamilyIndex(m_vki, m_phyDevice))
-                       , m_device                              (makeProtectedMemDevice(m_vki, m_phyDevice, m_queueFamilyIndex, ctx.getUsedApiVersion()))
-                       , m_allocator                   (createAllocator())
-                       , m_deviceDriver                (m_vki, *m_device)
-                       , m_queue                               (getProtectedQueue(m_deviceDriver, *m_device, m_queueFamilyIndex, 0))
-               {}
+               ProtectedContext        (Context&                                               ctx,
+                                                        const std::vector<std::string> instanceExtensions = std::vector<std::string>(),
+                                                        const std::vector<std::string> deviceExtensions = std::vector<std::string>());
+
+               ProtectedContext        (Context&                                               ctx,
+                                                        vk::wsi::Type                                  wsiType,
+                                                        vk::wsi::Display&                              display,
+                                                        vk::wsi::Window&                               window,
+                                                        const std::vector<std::string> instanceExtensions = std::vector<std::string>(),
+                                                        const std::vector<std::string> deviceExtensions = std::vector<std::string>());
 
        const vk::DeviceInterface&                                      getDeviceInterface      (void) const    { return m_deviceDriver;                                        }
        vk::VkDevice                                                            getDevice                       (void) const    { return *m_device;                                                     }
+       const vk::DeviceDriver&                                         getDeviceDriver         (void) const    { return m_deviceDriver;                                        }
+       vk::VkPhysicalDevice                                            getPhysicalDevice       (void) const    { return m_phyDevice;                                           }
        vk::VkQueue                                                                     getQueue                        (void) const    { return m_queue;                                                       }
        deUint32                                                                        getQueueFamilyIndex     (void) const    { return m_queueFamilyIndex;                            }
 
@@ -63,6 +63,11 @@ public:
        vk::BinaryCollection&                                           getBinaryCollection     (void) const    { return m_context.getBinaryCollection();       }
        vk::Allocator&                                                          getDefaultAllocator     (void) const    { return *m_allocator;  }
 
+       const vk::InstanceDriver&                                       getInstanceDriver       (void) const    { return m_vki;                                                         }
+       vk::VkInstance                                                          getInstance                     (void) const    { return *m_instance;                                           }
+       const vk::VkSurfaceKHR                                          getSurface                      (void) const    { return *m_surface;                                            }
+
+
 private:
        vk::Allocator* createAllocator (void)
        {
@@ -73,16 +78,17 @@ private:
                return new vk::SimpleAllocator(getDeviceInterface(), getDevice(), memoryProperties);
        }
 
-       Context&                                                m_context;
-       const vk::PlatformInterface&    m_interface;
-       vk::Move<vk::VkInstance>                m_instance;
-       vk::InstanceDriver                              m_vki;
-       vk::VkPhysicalDevice                    m_phyDevice;
-       deUint32                                                m_queueFamilyIndex;
-       vk::Move<vk::VkDevice>                  m_device;
+       Context&                                                        m_context;
+       const vk::PlatformInterface&            m_interface;
+       vk::Move<vk::VkInstance>                        m_instance;
+       vk::InstanceDriver                                      m_vki;
+       vk::VkPhysicalDevice                            m_phyDevice;
+       const vk::Move<vk::VkSurfaceKHR>        m_surface;
+       deUint32                                                        m_queueFamilyIndex;
+       vk::Move<vk::VkDevice>                          m_device;
        const de::UniquePtr<vk::Allocator>      m_allocator;
-       vk::DeviceDriver                                m_deviceDriver;
-       vk::VkQueue                                             m_queue;
+       vk::DeviceDriver                                        m_deviceDriver;
+       vk::VkQueue                                                     m_queue;
 };
 
 class ProtectedTestInstance : public TestInstance
index f46c57f..aa7d575 100644 (file)
@@ -37,6 +37,7 @@
 #include "vktProtectedMemCopyBufferToImageTests.hpp"
 #include "vktProtectedMemStorageBufferTests.hpp"
 #include "vktProtectedMemShaderImageAccessTests.hpp"
+#include "vktProtectedMemWsiSwapchainTests.hpp"
 
 namespace vkt
 {
@@ -85,6 +86,12 @@ tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
                protectedTests->addChild(ssboTestGroup.release());
        }
 
+       {
+               de::MovePtr<tcu::TestCaseGroup> interactionTestGroup (new tcu::TestCaseGroup(testCtx, "interaction", "Various tests which interacts with other extensions"));
+               interactionTestGroup->addChild(createSwapchainTests(testCtx));
+               protectedTests->addChild(interactionTestGroup.release());
+       }
+
        return protectedTests.release();
 
 }
index 7cae2fe..2ded874 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "vktProtectedMemUtils.hpp"
 
+#include <deString.h>
+
 #include "vkDeviceUtil.hpp"
 #include "vkQueryUtil.hpp"
 #include "vkTypeUtil.hpp"
@@ -32,6 +34,7 @@
 
 #include "vkPlatform.hpp"
 #include "vktProtectedMemContext.hpp"
+#include "vkWsiUtil.hpp"
 
 namespace vkt
 {
@@ -75,11 +78,11 @@ std::vector<std::string> getValidationLayers (const vk::PlatformInterface& vkp)
 }
 
 
-vk::Move<vk::VkInstance> makeProtectedMemInstance (const vk::PlatformInterface& vkp, const vkt::Context& context)
+vk::Move<vk::VkInstance> makeProtectedMemInstance (const vk::PlatformInterface& vkp, const vkt::Context& context, const std::vector<std::string>& extraExtensions)
 {
        const Extensions                        supportedExtensions(vk::enumerateInstanceExtensionProperties(vkp, DE_NULL));
        std::vector<std::string>        enabledLayers;
-       std::vector<std::string>        requiredExtensions;
+       std::vector<std::string>        requiredExtensions = extraExtensions;
        const bool                                      isValidationEnabled     = context.getTestContext().getCommandLine().isValidationEnabled();
 
        if (isValidationEnabled)
@@ -107,7 +110,8 @@ vk::Move<vk::VkInstance> makeProtectedMemInstance (const vk::PlatformInterface&
 }
 
 deUint32 chooseProtectedMemQueueFamilyIndex    (const vk::InstanceDriver&      vkd,
-                                                                                        vk::VkPhysicalDevice           physicalDevice)
+                                                                                        vk::VkPhysicalDevice           physicalDevice,
+                                                                                        vk::VkSurfaceKHR                       surface)
 {
        std::vector<vk::VkQueueFamilyProperties>        properties;
        deUint32                                                                        numFamilies             = 0;
@@ -126,6 +130,10 @@ deUint32 chooseProtectedMemQueueFamilyIndex        (const vk::InstanceDriver&      vkd,
        {
                vk::VkQueueFlags        flags = properties[idx].queueFlags;
 
+               if (surface != DE_NULL
+                       && vk::wsi::getPhysicalDeviceSurfaceSupport(vkd, physicalDevice, (deUint32)idx, surface) == VK_FALSE)
+                       continue; // Skip the queue family index if it does not support the surface
+
                if ((flags & requiredFlags) == requiredFlags)
                        return (deUint32)idx;
        }
@@ -133,29 +141,33 @@ deUint32 chooseProtectedMemQueueFamilyIndex       (const vk::InstanceDriver&      vkd,
        TCU_THROW(NotSupportedError, "No matching universal protected queue found");
 }
 
-vk::Move<vk::VkDevice> makeProtectedMemDevice  (const vk::InstanceDriver&              vkd,
-                                                                                                vk::VkPhysicalDevice                   physicalDevice,
-                                                                                                const deUint32                                 queueFamilyIndex,
-                                                                                                const deUint32                                 apiVersion)
+vk::Move<vk::VkDevice> makeProtectedMemDevice  (const vk::InstanceDriver&                      vkd,
+                                                                                                vk::VkPhysicalDevice                           physicalDevice,
+                                                                                                const deUint32                                         queueFamilyIndex,
+                                                                                                const deUint32                                         apiVersion,
+                                                                                                const std::vector<std::string>&        extraExtensions)
 {
        const Extensions                                        supportedExtensions     (vk::enumerateDeviceExtensionProperties(vkd, physicalDevice, DE_NULL));
-       std::vector<const char*>                        requiredExtensions;
-       deUint32                                                        extensionsCount         = 1;
-       const char* const                                       extensions[]            =
-       {
-               "VK_KHR_protected_memory"
-       };
+       std::vector<std::string>                        requiredExtensions;
+       std::vector<std::string>                        extensions                      = extraExtensions;
+       extensions.push_back("VK_KHR_protected_memory");
 
        // Check if the physical device supports the protected memory extension name
-       for (deUint32 ndx = 0; ndx < extensionsCount; ++ndx)
+       for (deUint32 ndx = 0; ndx < extensions.size(); ++ndx)
        {
                if (!isDeviceExtensionSupported(apiVersion, supportedExtensions, vk::RequiredExtension(extensions[ndx])))
-                       TCU_THROW(NotSupportedError, (std::string(extensions[ndx]) + " is not supported").c_str());
+                       TCU_THROW(NotSupportedError, (extensions[ndx] + " is not supported").c_str());
 
                if (!isCoreDeviceExtension(apiVersion, extensions[ndx]))
                        requiredExtensions.push_back(extensions[ndx]);
        }
 
+       std::vector<const char*>                        enabledExts                     (requiredExtensions.size());
+       for (size_t idx = 0; idx < requiredExtensions.size(); ++idx)
+       {
+               enabledExts[idx] = requiredExtensions[idx].c_str();
+       }
+
        // Check if the protected memory can be enabled on the physical device.
        vk::VkPhysicalDeviceProtectedMemoryFeatures     protectedFeature =
        {
@@ -201,7 +213,7 @@ vk::Move<vk::VkDevice> makeProtectedMemDevice       (const vk::InstanceDriver&              vkd,
                0u,                                                                                                                             // enabledLayerCount
                DE_NULL,                                                                                                                // pEnabledLayerNames
                (deUint32)requiredExtensions.size(),                                                    // enabledExtensionCount
-               requiredExtensions.empty() ? DE_NULL : &requiredExtensions[0],  // pEnabledExtensionNames
+               requiredExtensions.empty() ? DE_NULL : &enabledExts[0],                 // pEnabledExtensionNames
                DE_NULL                                                                                                                 // pEnabledFeatures
        };
 
index 3de495f..57d135f 100644 (file)
@@ -51,14 +51,17 @@ typedef std::vector<vk::VkVertexInputBindingDescription>    VertexBindings;
 typedef std::vector<vk::VkVertexInputAttributeDescription>     VertexAttribs;
 
 vk::Move<vk::VkInstance>                       makeProtectedMemInstance                        (const vk::PlatformInterface&           vkp,
-                                                                                                                                                const vkt::Context&                            context);
+                                                                                                                                                const vkt::Context&                            context,
+                                                                                                                                                const std::vector<std::string>&        extraExtensions = std::vector<std::string>());
 deUint32                                                       chooseProtectedMemQueueFamilyIndex      (const vk::InstanceDriver&                      vkd,
-                                                                                                                                                vk::VkPhysicalDevice                           physicalDevice);
+                                                                                                                                                vk::VkPhysicalDevice                           physicalDevice,
+                                                                                                                                                vk::VkSurfaceKHR                                       surface = DE_NULL);
 
 vk::Move<vk::VkDevice>                         makeProtectedMemDevice                          (const vk::InstanceDriver&                      vkd,
                                                                                                                                                 vk::VkPhysicalDevice                           physicalDevice,
                                                                                                                                                 const deUint32                                         queueFamilyIndex,
-                                                                                                                                                const deUint32                                         apiVersion);
+                                                                                                                                                const deUint32                                         apiVersion,
+                                                                                                                                                const std::vector<std::string>&        extraExtensions = std::vector<std::string>());
 vk::VkQueue                                                    getProtectedQueue                                       (const vk::DeviceInterface&                     vk,
                                                                                                                                                 vk::VkDevice                                           device,
                                                                                                                                                 const deUint32                                         queueFamilyIndex,
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.cpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.cpp
new file mode 100644 (file)
index 0000000..b9f6157
--- /dev/null
@@ -0,0 +1,1203 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 Protected memory interaction with VkSwapchain Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktProtectedMemWsiSwapchainTests.hpp"
+
+#include "vktTestCaseUtil.hpp"
+#include "vktTestGroupUtil.hpp"
+
+#include "vkDefs.hpp"
+#include "vkPlatform.hpp"
+#include "vkStrUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkMemUtil.hpp"
+#include "vkDeviceUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkWsiPlatform.hpp"
+#include "vkWsiUtil.hpp"
+#include "vkAllocationCallbackUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuFormatUtil.hpp"
+#include "tcuPlatform.hpp"
+#include "tcuResultCollector.hpp"
+
+#include "deUniquePtr.hpp"
+#include "deStringUtil.hpp"
+#include "deArrayUtil.hpp"
+#include "deSharedPtr.hpp"
+
+#include <limits>
+
+#include "vktProtectedMemContext.hpp"
+#include "vktProtectedMemUtils.hpp"
+
+namespace vkt
+{
+namespace ProtectedMem
+{
+
+namespace
+{
+
+typedef std::vector<vk::VkExtensionProperties> Extensions;
+
+void checkAllSupported (const Extensions& supportedExtensions, const std::vector<std::string>& requiredExtensions)
+{
+       for (std::vector<std::string>::const_iterator requiredExtName = requiredExtensions.begin();
+                requiredExtName != requiredExtensions.end();
+                ++requiredExtName)
+       {
+               if (!isExtensionSupported(supportedExtensions, vk::RequiredExtension(*requiredExtName)))
+                       TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
+       }
+}
+
+std::vector<std::string> getRequiredWsiExtensions (const Extensions&   supportedExtensions,
+                                                                                                  vk::wsi::Type                wsiType)
+{
+       std::vector<std::string>        extensions;
+
+       extensions.push_back("VK_KHR_surface");
+       extensions.push_back(getExtensionName(wsiType));
+
+       // VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
+       // the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
+       // but using them without enabling the extension is not allowed. Thus we have
+       // two options:
+       //
+       // 1) Filter out non-core formats to stay within valid usage.
+       //
+       // 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
+       //
+       // We opt for (2) as it provides basic coverage for the extension as a bonus.
+       if (isExtensionSupported(supportedExtensions, vk::RequiredExtension("VK_EXT_swapchain_colorspace")))
+               extensions.push_back("VK_EXT_swapchain_colorspace");
+
+       checkAllSupported(supportedExtensions, extensions);
+
+       return extensions;
+}
+
+de::MovePtr<vk::wsi::Display> createDisplay (const vk::Platform&       platform,
+                                                                                        const Extensions&              supportedExtensions,
+                                                                                        vk::wsi::Type                  wsiType)
+{
+       try
+       {
+               return de::MovePtr<vk::wsi::Display>(platform.createWsiDisplay(wsiType));
+       }
+       catch (const tcu::NotSupportedError& e)
+       {
+               if (isExtensionSupported(supportedExtensions, vk::RequiredExtension(getExtensionName(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> 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());
+       }
+}
+
+struct NativeObjects
+{
+       const de::UniquePtr<vk::wsi::Display>   display;
+       const de::UniquePtr<vk::wsi::Window>    window;
+
+       NativeObjects (Context&                                                 context,
+                                  const Extensions&                            supportedExtensions,
+                                  vk::wsi::Type                                        wsiType,
+                                  const tcu::Maybe<tcu::UVec2>&        initialWindowSize = tcu::nothing<tcu::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
+       TEST_DIMENSION_IMAGE_FORMAT,            //!< Test all supported formats
+       TEST_DIMENSION_IMAGE_EXTENT,            //!< Test various (supported) extents
+       TEST_DIMENSION_IMAGE_ARRAY_LAYERS,
+       TEST_DIMENSION_IMAGE_USAGE,
+       TEST_DIMENSION_IMAGE_SHARING_MODE,
+       TEST_DIMENSION_PRE_TRANSFORM,
+       TEST_DIMENSION_COMPOSITE_ALPHA,
+       TEST_DIMENSION_PRESENT_MODE,
+       TEST_DIMENSION_CLIPPED,
+
+       TEST_DIMENSION_LAST
+};
+
+const char* getTestDimensionName (TestDimension dimension)
+{
+       static const char* const s_names[] =
+       {
+               "min_image_count",
+               "image_format",
+               "image_extent",
+               "image_array_layers",
+               "image_usage",
+               "image_sharing_mode",
+               "pre_transform",
+               "composite_alpha",
+               "present_mode",
+               "clipped"
+       };
+       return de::getSizedArrayElement<TEST_DIMENSION_LAST>(s_names, dimension);
+}
+
+struct TestParameters
+{
+       vk::wsi::Type   wsiType;
+       TestDimension   dimension;
+
+       TestParameters (vk::wsi::Type wsiType_, TestDimension dimension_)
+               : wsiType       (wsiType_)
+               , dimension     (dimension_)
+       {}
+
+       TestParameters (void)
+               : wsiType       (vk::wsi::TYPE_LAST)
+               , dimension     (TEST_DIMENSION_LAST)
+       {}
+};
+
+std::vector<vk::VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (vk::wsi::Type                                                               wsiType,
+                                                                                                                                                  TestDimension                                                                dimension,
+                                                                                                                                                  const vk::VkSurfaceCapabilitiesKHR&                  capabilities,
+                                                                                                                                                  const std::vector<vk::VkSurfaceFormatKHR>&   formats,
+                                                                                                                                                  const std::vector<vk::VkPresentModeKHR>&             presentModes)
+{
+       std::vector<vk::VkSwapchainCreateInfoKHR>       cases;
+       const vk::wsi::PlatformProperties&                      platformProperties      = getPlatformProperties(wsiType);
+       const vk::VkSurfaceTransformFlagBitsKHR         defaultTransform        = (capabilities.supportedTransforms & vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
+                                                                                                                                               ? vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
+       const vk::VkSwapchainCreateInfoKHR                      baseParameters          =
+       {
+               vk::VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+               DE_NULL,
+               vk::VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR,
+               (vk::VkSurfaceKHR)0,
+               capabilities.minImageCount,
+               formats[0].format,
+               formats[0].colorSpace,
+               (platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE
+                       ? capabilities.minImageExtent : capabilities.currentExtent),
+               1u,                                                                     // imageArrayLayers
+               vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+               vk::VK_SHARING_MODE_EXCLUSIVE,
+               0u,
+               (const deUint32*)DE_NULL,
+               defaultTransform,
+               vk::VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+               vk::VK_PRESENT_MODE_FIFO_KHR,
+               VK_FALSE,                                                       // clipped
+               (vk::VkSwapchainKHR)0                           // oldSwapchain
+       };
+
+       switch (dimension)
+       {
+               case TEST_DIMENSION_MIN_IMAGE_COUNT:
+               {
+                       const deUint32  maxImageCountToTest     = de::clamp(16u, capabilities.minImageCount, (capabilities.maxImageCount > 0) ? capabilities.maxImageCount : capabilities.minImageCount + 16u);
+
+                       for (deUint32 imageCount = capabilities.minImageCount; imageCount <= maxImageCountToTest; ++imageCount)
+                       {
+                               cases.push_back(baseParameters);
+                               cases.back().minImageCount = imageCount;
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_IMAGE_FORMAT:
+               {
+                       for (std::vector<vk::VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
+                       {
+                               cases.push_back(baseParameters);
+                               cases.back().imageFormat                = curFmt->format;
+                               cases.back().imageColorSpace    = curFmt->colorSpace;
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_IMAGE_EXTENT:
+               {
+                       static const vk::VkExtent2D     s_testSizes[]   =
+                       {
+                               { 1, 1 },
+                               { 16, 32 },
+                               { 32, 16 },
+                               { 632, 231 },
+                               { 117, 998 },
+                       };
+
+                       if (platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE ||
+                               platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE)
+                       {
+                               for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_testSizes); ++ndx)
+                               {
+                                       cases.push_back(baseParameters);
+                                       cases.back().imageExtent.width  = de::clamp(s_testSizes[ndx].width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
+                                       cases.back().imageExtent.height = de::clamp(s_testSizes[ndx].height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
+                               }
+                       }
+
+                       if (platformProperties.swapchainExtent != vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE)
+                       {
+                               cases.push_back(baseParameters);
+                               cases.back().imageExtent = capabilities.currentExtent;
+                       }
+
+                       if (platformProperties.swapchainExtent != vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE)
+                       {
+                               cases.push_back(baseParameters);
+                               cases.back().imageExtent = capabilities.minImageExtent;
+
+                               cases.push_back(baseParameters);
+                               cases.back().imageExtent = capabilities.maxImageExtent;
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_IMAGE_ARRAY_LAYERS:
+               {
+                       const deUint32  maxLayers       = de::min(capabilities.maxImageArrayLayers, 16u);
+
+                       for (deUint32 numLayers = 1; numLayers <= maxLayers; ++numLayers)
+                       {
+                               cases.push_back(baseParameters);
+                               cases.back().imageArrayLayers = numLayers;
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_IMAGE_USAGE:
+               {
+                       for (deUint32 flags = 1u; flags <= capabilities.supportedUsageFlags; ++flags)
+                       {
+                               if ((flags & ~capabilities.supportedUsageFlags) == 0)
+                               {
+                                       cases.push_back(baseParameters);
+                                       cases.back().imageUsage = flags;
+                               }
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_IMAGE_SHARING_MODE:
+               {
+                       cases.push_back(baseParameters);
+                       cases.back().imageSharingMode = vk::VK_SHARING_MODE_EXCLUSIVE;
+
+                       cases.push_back(baseParameters);
+                       cases.back().imageSharingMode = vk::VK_SHARING_MODE_CONCURRENT;
+
+                       break;
+               }
+
+               case TEST_DIMENSION_PRE_TRANSFORM:
+               {
+                       for (deUint32 transform = 1u;
+                                transform <= capabilities.supportedTransforms;
+                                transform = transform<<1u)
+                       {
+                               if ((transform & capabilities.supportedTransforms) != 0)
+                               {
+                                       cases.push_back(baseParameters);
+                                       cases.back().preTransform = (vk::VkSurfaceTransformFlagBitsKHR)transform;
+                               }
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_COMPOSITE_ALPHA:
+               {
+                       for (deUint32 alphaMode = 1u;
+                                alphaMode <= capabilities.supportedCompositeAlpha;
+                                alphaMode = alphaMode<<1u)
+                       {
+                               if ((alphaMode & capabilities.supportedCompositeAlpha) != 0)
+                               {
+                                       cases.push_back(baseParameters);
+                                       cases.back().compositeAlpha = (vk::VkCompositeAlphaFlagBitsKHR)alphaMode;
+                               }
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_PRESENT_MODE:
+               {
+                       for (std::vector<vk::VkPresentModeKHR>::const_iterator curMode = presentModes.begin(); curMode != presentModes.end(); ++curMode)
+                       {
+                               cases.push_back(baseParameters);
+                               cases.back().presentMode = *curMode;
+                       }
+
+                       break;
+               }
+
+               case TEST_DIMENSION_CLIPPED:
+               {
+                       cases.push_back(baseParameters);
+                       cases.back().clipped = VK_FALSE;
+
+                       cases.push_back(baseParameters);
+                       cases.back().clipped = VK_TRUE;
+
+                       break;
+               }
+
+               default:
+                       DE_FATAL("Impossible");
+       }
+
+       DE_ASSERT(!cases.empty());
+       return cases;
+}
+
+std::vector<vk::VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (vk::wsi::Type                                       wsiType,
+                                                                                                                                                  TestDimension                                        dimension,
+                                                                                                                                                  const vk::InstanceInterface&         vki,
+                                                                                                                                                  vk::VkPhysicalDevice                         physicalDevice,
+                                                                                                                                                  vk::VkSurfaceKHR                                     surface)
+{
+       const vk::VkSurfaceCapabilitiesKHR                      capabilities    = vk::wsi::getPhysicalDeviceSurfaceCapabilities(vki,
+                                                                                                                                                                                                                          physicalDevice,
+                                                                                                                                                                                                                          surface);
+       const std::vector<vk::VkSurfaceFormatKHR>       formats                 = vk::wsi::getPhysicalDeviceSurfaceFormats(vki,
+                                                                                                                                                                                                                  physicalDevice,
+                                                                                                                                                                                                                  surface);
+       const std::vector<vk::VkPresentModeKHR>         presentModes    = vk::wsi::getPhysicalDeviceSurfacePresentModes(vki,
+                                                                                                                                                                                                                           physicalDevice,
+                                                                                                                                                                                                                           surface);
+
+       return generateSwapchainParameterCases(wsiType, dimension, capabilities, formats, presentModes);
+}
+
+tcu::TestStatus createSwapchainTest (Context& baseCtx, TestParameters params)
+{
+       std::vector<vk::VkExtensionProperties>                  supportedExtensions (enumerateInstanceExtensionProperties(baseCtx.getPlatformInterface(), DE_NULL));
+       std::vector<std::string>                                                instExts        = getRequiredWsiExtensions(supportedExtensions, params.wsiType);
+       std::vector<std::string>                                                devExts;
+       devExts.push_back("VK_KHR_swapchain");
+
+       const NativeObjects                                                             native          (baseCtx, supportedExtensions, params.wsiType);
+       ProtectedContext                                                                context         (baseCtx, params.wsiType, *native.display, *native.window, instExts, devExts);
+       vk::VkSurfaceKHR                                                                surface         = context.getSurface();
+       const std::vector<vk::VkSwapchainCreateInfoKHR> cases           (generateSwapchainParameterCases(params.wsiType,
+                                                                                                                                                                                params.dimension,
+                                                                                                                                                                                context.getInstanceDriver(),
+                                                                                                                                                                                context.getPhysicalDevice(),
+                                                                                                                                                                                surface));
+       deUint32                                                                                queueIdx        = context.getQueueFamilyIndex();
+       for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
+       {
+               vk::VkSwapchainCreateInfoKHR    curParams       = cases[caseNdx];
+
+               curParams.surface                               = surface;
+               curParams.queueFamilyIndexCount = 1u;
+               curParams.pQueueFamilyIndices   = &queueIdx;
+
+               context.getTestContext().getLog()
+                       << tcu::TestLog::Message << "Sub-case " << (caseNdx+1) << " / " << cases.size() << ": " << curParams << tcu::TestLog::EndMessage;
+
+               {
+                       const vk::Unique<vk::VkSwapchainKHR>    swapchain       (createSwapchainKHR(context.getDeviceDriver(), context.getDevice(), &curParams));
+               }
+       }
+
+       return tcu::TestStatus::pass("Creating swapchain succeeded");
+}
+
+struct GroupParameters
+{
+       typedef FunctionInstance1<TestParameters>::Function     Function;
+
+       vk::wsi::Type   wsiType;
+       Function                function;
+
+       GroupParameters (vk::wsi::Type wsiType_, Function function_)
+               : wsiType       (wsiType_)
+               , function      (function_)
+       {}
+
+       GroupParameters (void)
+               : wsiType       (vk::wsi::TYPE_LAST)
+               , function      ((Function)DE_NULL)
+       {}
+};
+
+void populateSwapchainGroup (tcu::TestCaseGroup* testGroup, GroupParameters params)
+{
+       for (int dimensionNdx = 0; dimensionNdx < TEST_DIMENSION_LAST; ++dimensionNdx)
+       {
+               const TestDimension             testDimension   = (TestDimension)dimensionNdx;
+
+               addFunctionCase(testGroup, getTestDimensionName(testDimension), "", params.function, TestParameters(params.wsiType, testDimension));
+       }
+}
+
+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 std::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,
+               DE_NULL,
+               vk::VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR,
+               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,
+               (const deUint32*)DE_NULL,
+               transform,
+               vk::VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+               vk::VK_PRESENT_MODE_FIFO_KHR,
+               VK_FALSE,                                                       // clipped
+               (vk::VkSwapchainKHR)0                           // oldSwapchain
+       };
+
+       return parameters;
+}
+
+typedef de::SharedPtr<vk::Unique<vk::VkImageView> >            ImageViewSp;
+typedef de::SharedPtr<vk::Unique<vk::VkFramebuffer> >  FramebufferSp;
+
+class TriangleRenderer
+{
+public:
+                                                                                               TriangleRenderer        (ProtectedContext&                              context,
+                                                                                                                                        const vk::BinaryCollection&    binaryRegistry,
+                                                                                                                                        const std::vector<vk::VkImage> swapchainImages,
+                                                                                                                                        const vk::VkFormat                             framebufferFormat,
+                                                                                                                                        const tcu::UVec2&                              renderSize);
+                                                                                               ~TriangleRenderer       (void);
+
+       void                                                                            recordFrame                     (vk::VkCommandBuffer                    cmdBuffer,
+                                                                                                                                        deUint32                                               imageNdx,
+                                                                                                                                        deUint32                                               frameNdx) const;
+
+       static void                                                                     getPrograms                     (vk::SourceCollections&                 dst);
+
+private:
+       static vk::Move<vk::VkRenderPass>                       createRenderPass        (const vk::DeviceInterface&             vkd,
+                                                                                                                                        const vk::VkDevice                             device,
+                                                                                                                                        const vk::VkFormat                             colorAttachmentFormat);
+       static vk::Move<vk::VkPipelineLayout>           createPipelineLayout(const vk::DeviceInterface&         vkd,
+                                                                                                                                        vk::VkDevice                                   device);
+       static vk::Move<vk::VkPipeline>                         createPipeline          (const vk::DeviceInterface&             vkd,
+                                                                                                                                        const vk::VkDevice                             device,
+                                                                                                                                        const vk::VkRenderPass                 renderPass,
+                                                                                                                                        const vk::VkPipelineLayout             pipelineLayout,
+                                                                                                                                        const vk::BinaryCollection&    binaryCollection,
+                                                                                                                                        const tcu::UVec2&                              renderSize);
+
+       const vk::DeviceInterface&                                      m_vkd;
+
+       const std::vector<vk::VkImage>                          m_swapchainImages;
+       const tcu::UVec2                                                        m_renderSize;
+
+       const vk::Unique<vk::VkRenderPass>                      m_renderPass;
+       const vk::Unique<vk::VkPipelineLayout>          m_pipelineLayout;
+       const vk::Unique<vk::VkPipeline>                        m_pipeline;
+
+       const de::UniquePtr<vk::BufferWithMemory>       m_vertexBuffer;
+
+       std::vector<ImageViewSp>                                        m_attachmentViews;
+       std::vector<FramebufferSp>                                      m_framebuffers;
+};
+
+vk::Move<vk::VkRenderPass> TriangleRenderer::createRenderPass (const vk::DeviceInterface&      vkd,
+                                                                                                                          const vk::VkDevice                   device,
+                                                                                                                          const vk::VkFormat                   colorAttachmentFormat)
+{
+       const vk::VkAttachmentDescription       colorAttDesc            =
+       {
+               (vk::VkAttachmentDescriptionFlags)0,
+               colorAttachmentFormat,
+               vk::VK_SAMPLE_COUNT_1_BIT,
+               vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
+               vk::VK_ATTACHMENT_STORE_OP_STORE,
+               vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+               vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
+               vk::VK_IMAGE_LAYOUT_UNDEFINED,
+               vk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+       };
+       const vk::VkAttachmentReference         colorAttRef                     =
+       {
+               0u,
+               vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+       };
+       const vk::VkSubpassDescription          subpassDesc                     =
+       {
+               (vk::VkSubpassDescriptionFlags)0u,
+               vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
+               0u,                                                     // inputAttachmentCount
+               DE_NULL,                                        // pInputAttachments
+               1u,                                                     // colorAttachmentCount
+               &colorAttRef,                           // pColorAttachments
+               DE_NULL,                                        // pResolveAttachments
+               DE_NULL,                                        // depthStencilAttachment
+               0u,                                                     // preserveAttachmentCount
+               DE_NULL,                                        // pPreserveAttachments
+       };
+       const vk::VkSubpassDependency           dependencies[]          =
+       {
+               {
+                       VK_SUBPASS_EXTERNAL,    // srcSubpass
+                       0u,                                             // dstSubpass
+                       vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+                       vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                       vk::VK_ACCESS_MEMORY_READ_BIT,
+                       (vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
+                        vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
+                       vk::VK_DEPENDENCY_BY_REGION_BIT
+               },
+               {
+                       0u,                                             // srcSubpass
+                       VK_SUBPASS_EXTERNAL,    // dstSubpass
+                       vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                       vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+                       (vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
+                        vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
+                       vk::VK_ACCESS_MEMORY_READ_BIT,
+                       vk::VK_DEPENDENCY_BY_REGION_BIT
+               },
+       };
+       const vk::VkRenderPassCreateInfo        renderPassParams        =
+       {
+               vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+               DE_NULL,
+               (vk::VkRenderPassCreateFlags)0,
+               1u,
+               &colorAttDesc,
+               1u,
+               &subpassDesc,
+               DE_LENGTH_OF_ARRAY(dependencies),
+               dependencies,
+       };
+
+       return vk::createRenderPass(vkd, device, &renderPassParams);
+}
+
+vk::Move<vk::VkPipelineLayout> TriangleRenderer::createPipelineLayout (const vk::DeviceInterface&      vkd,
+                                                                                                                                          const vk::VkDevice                   device)
+{
+       const vk::VkPushConstantRange                                   pushConstantRange               =
+       {
+               vk::VK_SHADER_STAGE_VERTEX_BIT,
+               0u,                                                                                     // offset
+               (deUint32)sizeof(deUint32),                                     // size
+       };
+       const vk::VkPipelineLayoutCreateInfo                    pipelineLayoutParams    =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineLayoutCreateFlags)0,
+               0u,                                                                                     // setLayoutCount
+               DE_NULL,                                                                        // pSetLayouts
+               1u,
+               &pushConstantRange,
+       };
+
+       return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
+}
+
+vk::Move<vk::VkPipeline> TriangleRenderer::createPipeline (const vk::DeviceInterface&  vkd,
+                                                                                                                  const vk::VkDevice                   device,
+                                                                                                                  const vk::VkRenderPass               renderPass,
+                                                                                                                  const vk::VkPipelineLayout   pipelineLayout,
+                                                                                                                  const vk::BinaryCollection&  binaryCollection,
+                                                                                                                  const tcu::UVec2&                    renderSize)
+{
+       // \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
+       //               and can be deleted immediately following that call.
+       const vk::Unique<vk::VkShaderModule>                            vertShaderModule                (createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
+       const vk::Unique<vk::VkShaderModule>                            fragShaderModule                (createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
+
+       const vk::VkPipelineShaderStageCreateInfo                       shaderStageParams[]             =
+       {
+               {
+                       vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+                       DE_NULL,
+                       (vk::VkPipelineShaderStageCreateFlags)0,
+                       vk::VK_SHADER_STAGE_VERTEX_BIT,
+                       *vertShaderModule,
+                       "main",
+                       DE_NULL
+               },
+               {
+                       vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+                       DE_NULL,
+                       (vk::VkPipelineShaderStageCreateFlags)0,
+                       vk::VK_SHADER_STAGE_FRAGMENT_BIT,
+                       *fragShaderModule,
+                       "main",
+                       DE_NULL
+               }
+       };
+       const vk::VkPipelineDepthStencilStateCreateInfo         depthStencilParams              =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineDepthStencilStateCreateFlags)0,
+               DE_FALSE,                                                                       // depthTestEnable
+               DE_FALSE,                                                                       // depthWriteEnable
+               vk::VK_COMPARE_OP_ALWAYS,                                       // depthCompareOp
+               DE_FALSE,                                                                       // depthBoundsTestEnable
+               DE_FALSE,                                                                       // stencilTestEnable
+               {
+                       vk::VK_STENCIL_OP_KEEP,                                         // failOp
+                       vk::VK_STENCIL_OP_KEEP,                                         // passOp
+                       vk::VK_STENCIL_OP_KEEP,                                         // depthFailOp
+                       vk::VK_COMPARE_OP_ALWAYS,                                       // compareOp
+                       0u,                                                                                     // compareMask
+                       0u,                                                                                     // writeMask
+                       0u,                                                                                     // reference
+               },                                                                                      // front
+               {
+                       vk::VK_STENCIL_OP_KEEP,                                         // failOp
+                       vk::VK_STENCIL_OP_KEEP,                                         // passOp
+                       vk::VK_STENCIL_OP_KEEP,                                         // depthFailOp
+                       vk::VK_COMPARE_OP_ALWAYS,                                       // compareOp
+                       0u,                                                                                     // compareMask
+                       0u,                                                                                     // writeMask
+                       0u,                                                                                     // reference
+               },                                                                                      // back
+               -1.0f,                                                                          // minDepthBounds
+               +1.0f,                                                                          // maxDepthBounds
+       };
+       const vk::VkViewport                                                            viewport0                               =
+       {
+               0.0f,                                                                           // x
+               0.0f,                                                                           // y
+               (float)renderSize.x(),                                          // width
+               (float)renderSize.y(),                                          // height
+               0.0f,                                                                           // minDepth
+               1.0f,                                                                           // maxDepth
+       };
+       const vk::VkRect2D                                                                      scissor0                                =
+       {
+               { 0u, 0u, },                                                            // offset
+               { renderSize.x(), renderSize.y() },                     // extent
+       };
+       const vk::VkPipelineViewportStateCreateInfo                     viewportParams                  =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineViewportStateCreateFlags)0,
+               1u,
+               &viewport0,
+               1u,
+               &scissor0
+       };
+       const vk::VkPipelineMultisampleStateCreateInfo          multisampleParams               =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineMultisampleStateCreateFlags)0,
+               vk::VK_SAMPLE_COUNT_1_BIT,                                      // rasterizationSamples
+               VK_FALSE,                                                                       // sampleShadingEnable
+               0.0f,                                                                           // minSampleShading
+               (const vk::VkSampleMask*)DE_NULL,                       // sampleMask
+               VK_FALSE,                                                                       // alphaToCoverageEnable
+               VK_FALSE,                                                                       // alphaToOneEnable
+       };
+       const vk::VkPipelineRasterizationStateCreateInfo        rasterParams                    =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineRasterizationStateCreateFlags)0,
+               VK_FALSE,                                                                               // depthClampEnable
+               VK_FALSE,                                                                               // rasterizerDiscardEnable
+               vk::VK_POLYGON_MODE_FILL,                                               // polygonMode
+               vk::VK_CULL_MODE_NONE,                                                  // cullMode
+               vk::VK_FRONT_FACE_COUNTER_CLOCKWISE,                    // frontFace
+               VK_FALSE,                                                                               // depthBiasEnable
+               0.0f,                                                                                   // depthBiasConstantFactor
+               0.0f,                                                                                   // depthBiasClamp
+               0.0f,                                                                                   // depthBiasSlopeFactor
+               1.0f,                                                                                   // lineWidth
+       };
+       const vk::VkPipelineInputAssemblyStateCreateInfo        inputAssemblyParams             =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineInputAssemblyStateCreateFlags)0,
+               vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+               DE_FALSE,                                                                       // primitiveRestartEnable
+       };
+       const vk::VkVertexInputBindingDescription                       vertexBinding0                  =
+       {
+               0u,                                                                                     // binding
+               (deUint32)sizeof(tcu::Vec4),                            // stride
+               vk::VK_VERTEX_INPUT_RATE_VERTEX,                        // inputRate
+       };
+       const vk::VkVertexInputAttributeDescription                     vertexAttrib0                   =
+       {
+               0u,                                                                                     // location
+               0u,                                                                                     // binding
+               vk::VK_FORMAT_R32G32B32A32_SFLOAT,                      // format
+               0u,                                                                                     // offset
+       };
+       const vk::VkPipelineVertexInputStateCreateInfo          vertexInputStateParams  =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineVertexInputStateCreateFlags)0,
+               1u,
+               &vertexBinding0,
+               1u,
+               &vertexAttrib0,
+       };
+       const vk::VkPipelineColorBlendAttachmentState           attBlendParams0                 =
+       {
+               VK_FALSE,                                                                       // blendEnable
+               vk::VK_BLEND_FACTOR_ONE,                                        // srcColorBlendFactor
+               vk::VK_BLEND_FACTOR_ZERO,                                       // dstColorBlendFactor
+               vk::VK_BLEND_OP_ADD,                                            // colorBlendOp
+               vk::VK_BLEND_FACTOR_ONE,                                        // srcAlphaBlendFactor
+               vk::VK_BLEND_FACTOR_ZERO,                                       // dstAlphaBlendFactor
+               vk::VK_BLEND_OP_ADD,                                            // alphaBlendOp
+               (vk::VK_COLOR_COMPONENT_R_BIT|
+                vk::VK_COLOR_COMPONENT_G_BIT|
+                vk::VK_COLOR_COMPONENT_B_BIT|
+                vk::VK_COLOR_COMPONENT_A_BIT),                         // colorWriteMask
+       };
+       const vk::VkPipelineColorBlendStateCreateInfo           blendParams                             =
+       {
+               vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineColorBlendStateCreateFlags)0,
+               VK_FALSE,                                                                       // logicOpEnable
+               vk::VK_LOGIC_OP_COPY,
+               1u,
+               &attBlendParams0,
+               { 0.0f, 0.0f, 0.0f, 0.0f },                                     // blendConstants[4]
+       };
+       const vk::VkGraphicsPipelineCreateInfo                          pipelineParams                  =
+       {
+               vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+               DE_NULL,
+               (vk::VkPipelineCreateFlags)0,
+               (deUint32)DE_LENGTH_OF_ARRAY(shaderStageParams),
+               shaderStageParams,
+               &vertexInputStateParams,
+               &inputAssemblyParams,
+               (const vk::VkPipelineTessellationStateCreateInfo*)DE_NULL,
+               &viewportParams,
+               &rasterParams,
+               &multisampleParams,
+               &depthStencilParams,
+               &blendParams,
+               (const vk::VkPipelineDynamicStateCreateInfo*)DE_NULL,
+               pipelineLayout,
+               renderPass,
+               0u,                                                                                     // subpass
+               DE_NULL,                                                                        // basePipelineHandle
+               0u,                                                                                     // basePipelineIndex
+       };
+
+       return vk::createGraphicsPipeline(vkd, device, (vk::VkPipelineCache)0, &pipelineParams);
+}
+
+TriangleRenderer::TriangleRenderer (ProtectedContext&                          context,
+                                                                       const vk::BinaryCollection&             binaryRegistry,
+                                                                       const std::vector<vk::VkImage>  swapchainImages,
+                                                                       const vk::VkFormat                              framebufferFormat,
+                                                                       const tcu::UVec2&                               renderSize)
+       : m_vkd                                 (context.getDeviceInterface())
+       , m_swapchainImages             (swapchainImages)
+       , m_renderSize                  (renderSize)
+       , m_renderPass                  (createRenderPass(m_vkd, context.getDevice(), framebufferFormat))
+       , m_pipelineLayout              (createPipelineLayout(m_vkd, context.getDevice()))
+       , m_pipeline                    (createPipeline(m_vkd, context.getDevice(), *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
+       , m_vertexBuffer                (makeBuffer(context,
+                                                                       PROTECTION_DISABLED,
+                                                                       context.getQueueFamilyIndex(),
+                                                                       (deUint32)(sizeof(float)*4*3),
+                                                                       vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+                                                                       vk::MemoryRequirement::HostVisible))
+{
+       m_attachmentViews.resize(swapchainImages.size());
+       m_framebuffers.resize(swapchainImages.size());
+
+       for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
+       {
+               m_attachmentViews[imageNdx]     = ImageViewSp(new vk::Unique<vk::VkImageView>(createImageView(context, swapchainImages[imageNdx], framebufferFormat)));
+               m_framebuffers[imageNdx]        = FramebufferSp(new vk::Unique<vk::VkFramebuffer>(createFramebuffer(context,
+                                                                                                                                                                                                               renderSize.x(),
+                                                                                                                                                                                                               renderSize.y(),
+                                                                                                                                                                                                               *m_renderPass,
+                                                                                                                                                                                                               **m_attachmentViews[imageNdx])));
+       }
+
+       // Upload vertex data
+       {
+               const tcu::Vec4                         vertices[]      =
+               {
+                       tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
+                       tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
+                       tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
+               };
+               DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);
+
+               deMemcpy(m_vertexBuffer->getAllocation().getHostPtr(), &vertices[0], sizeof(vertices));
+               vk::flushMappedMemoryRange(m_vkd, context.getDevice(), m_vertexBuffer->getAllocation().getMemory(), m_vertexBuffer->getAllocation().getOffset(), sizeof(vertices));
+       }
+}
+
+TriangleRenderer::~TriangleRenderer (void)
+{
+}
+
+void TriangleRenderer::recordFrame (vk::VkCommandBuffer        cmdBuffer,
+                                                                       deUint32                        imageNdx,
+                                                                       deUint32                        frameNdx) const
+{
+       const vk::VkFramebuffer curFramebuffer  = **m_framebuffers[imageNdx];
+
+       beginCommandBuffer(m_vkd, cmdBuffer);
+
+       {
+               const vk::VkClearValue                  clearValue              = vk::makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f);
+               const vk::VkRenderPassBeginInfo passBeginParams =
+               {
+                       vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+                       DE_NULL,
+                       *m_renderPass,
+                       curFramebuffer,
+                       {
+                               { 0, 0 },
+                               { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
+                       },                                                                                                      // renderArea
+                       1u,                                                                                                     // clearValueCount
+                       &clearValue,                                                                            // pClearValues
+               };
+               m_vkd.cmdBeginRenderPass(cmdBuffer, &passBeginParams, vk::VK_SUBPASS_CONTENTS_INLINE);
+       }
+
+       m_vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+
+       {
+               const vk::VkDeviceSize bindingOffset = 0;
+               m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &bindingOffset);
+       }
+
+       m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, vk::VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
+       m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
+       m_vkd.cmdEndRenderPass(cmdBuffer);
+
+       VK_CHECK(m_vkd.endCommandBuffer(cmdBuffer));
+}
+
+void TriangleRenderer::getPrograms (vk::SourceCollections& dst)
+{
+       dst.glslSources.add("tri-vert") << glu::VertexSource(
+               "#version 310 es\n"
+               "layout(location = 0) in highp vec4 a_position;\n"
+               "layout(push_constant) uniform FrameData\n"
+               "{\n"
+               "    highp uint frameNdx;\n"
+               "} frameData;\n"
+               "void main (void)\n"
+               "{\n"
+               "    highp float angle = float(frameData.frameNdx) / 100.0;\n"
+               "    highp float c     = cos(angle);\n"
+               "    highp float s     = sin(angle);\n"
+               "    highp mat4  t     = mat4( c, -s,  0,  0,\n"
+               "                              s,  c,  0,  0,\n"
+               "                              0,  0,  1,  0,\n"
+               "                              0,  0,  0,  1);\n"
+               "    gl_Position = t * a_position;\n"
+               "}\n");
+       dst.glslSources.add("tri-frag") << glu::FragmentSource(
+               "#version 310 es\n"
+               "layout(location = 0) out lowp vec4 o_color;\n"
+               "void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
+}
+
+typedef de::SharedPtr<vk::Unique<vk::VkCommandBuffer> >        CommandBufferSp;
+typedef de::SharedPtr<vk::Unique<vk::VkFence> >                        FenceSp;
+typedef de::SharedPtr<vk::Unique<vk::VkSemaphore> >            SemaphoreSp;
+
+std::vector<FenceSp> createFences (const vk::DeviceInterface&  vkd,
+                                                                  const vk::VkDevice                   device,
+                                                                  size_t                                               numFences)
+{
+       std::vector<FenceSp> fences(numFences);
+
+       for (size_t ndx = 0; ndx < numFences; ++ndx)
+               fences[ndx] = FenceSp(new vk::Unique<vk::VkFence>(createFence(vkd, device)));
+
+       return fences;
+}
+
+std::vector<SemaphoreSp> createSemaphores (const vk::DeviceInterface&  vkd,
+                                                                                  const vk::VkDevice                   device,
+                                                                                  size_t                                               numSemaphores)
+{
+       std::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;
+}
+
+std::vector<CommandBufferSp> allocateCommandBuffers (const vk::DeviceInterface&                vkd,
+                                                                                                        const vk::VkDevice                             device,
+                                                                                                        const vk::VkCommandPool                commandPool,
+                                                                                                        const vk::VkCommandBufferLevel level,
+                                                                                                        const size_t                                   numCommandBuffers)
+{
+       std::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;
+}
+
+tcu::TestStatus basicRenderTest (Context& baseCtx, vk::wsi::Type wsiType)
+{
+       std::vector<vk::VkExtensionProperties>  supportedExtensions                     (enumerateInstanceExtensionProperties(baseCtx.getPlatformInterface(), DE_NULL));
+       std::vector<std::string>                                instExts                                        = getRequiredWsiExtensions(supportedExtensions, wsiType);
+       std::vector<std::string>                                devExts;
+       devExts.push_back("VK_KHR_swapchain");
+
+       const tcu::UVec2                                                desiredSize                                     (256, 256);
+       const NativeObjects                                             native                                          (baseCtx,  supportedExtensions, wsiType, tcu::just(desiredSize));
+       ProtectedContext                                                context                                         (baseCtx, wsiType, *native.display, *native.window, instExts, devExts);
+       vk::VkSurfaceKHR                                                surface                                         = context.getSurface();
+       const vk::DeviceInterface&                              vkd                                                     = context.getDeviceInterface();
+       const vk::VkDevice                                              device                                          = context.getDevice();
+       const vk::VkSwapchainCreateInfoKHR              swapchainInfo                           = getBasicSwapchainParameters(wsiType,
+                                                                                                                                                                                                 context.getInstanceDriver(),
+                                                                                                                                                                                                 context.getPhysicalDevice(),
+                                                                                                                                                                                                 surface,
+                                                                                                                                                                                                 desiredSize,
+                                                                                                                                                                                                 2);
+       const vk::Unique<vk::VkSwapchainKHR>    swapchain                                       (createSwapchainKHR(vkd, device, &swapchainInfo));
+       const std::vector<vk::VkImage>                  swapchainImages                         = vk::wsi::getSwapchainImages(vkd, device, *swapchain);
+
+       const TriangleRenderer                                  renderer                                        (context,
+                                                                                                                                                context.getBinaryCollection(),
+                                                                                                                                                swapchainImages,
+                                                                                                                                                swapchainInfo.imageFormat,
+                                                                                                                                                tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
+
+       const vk::Unique<vk::VkCommandPool>             commandPool                                     (makeCommandPool(vkd, device, PROTECTION_ENABLED,
+                                                                                                                                                                        context.getQueueFamilyIndex()));
+
+       const size_t                                                    maxQueuedFrames                         = swapchainImages.size()*2;
+
+       // We need to keep hold of fences from vkAcquireNextImageKHR to actually
+       // limit number of frames we allow to be queued.
+       const std::vector<FenceSp>                              imageReadyFences                        (createFences(vkd, device, maxQueuedFrames));
+
+       // We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to pass
+       // the semaphore in same time as the fence we use to meter rendering.
+       const std::vector<SemaphoreSp>                  imageReadySemaphores            (createSemaphores(vkd, device, maxQueuedFrames+1));
+
+       // For rest we simply need maxQueuedFrames as we will wait for image
+       // from frameNdx-maxQueuedFrames to become available to us, guaranteeing that
+       // previous uses must have completed.
+       const std::vector<SemaphoreSp>                  renderingCompleteSemaphores     (createSemaphores(vkd, device, maxQueuedFrames));
+       const std::vector<CommandBufferSp>              commandBuffers                          (allocateCommandBuffers(vkd,
+                                                                                                                                                                                               device,
+                                                                                                                                                                                               *commandPool,
+                                                                                                                                                                                               vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+                                                                                                                                                                                               maxQueuedFrames));
+
+       try
+       {
+               const deUint32  numFramesToRender       = 60*10;
+
+               for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
+               {
+                       const vk::VkFence               imageReadyFence         = **imageReadyFences[frameNdx%imageReadyFences.size()];
+                       const vk::VkSemaphore   imageReadySemaphore     = **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
+                       deUint32                                imageNdx                        = ~0u;
+
+                       if (frameNdx >= maxQueuedFrames)
+                               VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
+
+                       VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));
+
+                       {
+                               const vk::VkResult      acquireResult   = vkd.acquireNextImageKHR(device,
+                                                                                                                                                         *swapchain,
+                                                                                                                                                         std::numeric_limits<deUint64>::max(),
+                                                                                                                                                         imageReadySemaphore,
+                                                                                                                                                         imageReadyFence,
+                                                                                                                                                         &imageNdx);
+
+                               if (acquireResult == vk::VK_SUBOPTIMAL_KHR)
+                                       context.getTestContext().getLog() << tcu::TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << tcu::TestLog::EndMessage;
+                               else
+                                       VK_CHECK(acquireResult);
+                       }
+
+                       TCU_CHECK((size_t)imageNdx < swapchainImages.size());
+
+                       {
+                               const vk::VkSemaphore                   renderingCompleteSemaphore      = **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
+                               const vk::VkCommandBuffer               commandBuffer                           = **commandBuffers[frameNdx%commandBuffers.size()];
+                               const vk::VkPipelineStageFlags  waitDstStage                            = vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+                               vk::VkSubmitInfo                                submitInfo                                      =
+                               {
+                                       vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
+                                       DE_NULL,
+                                       1u,
+                                       &imageReadySemaphore,
+                                       &waitDstStage,
+                                       1u,
+                                       &commandBuffer,
+                                       1u,
+                                       &renderingCompleteSemaphore
+                               };
+
+                               const vk::VkProtectedSubmitInfoKHR  protectedInfo   =
+                               {
+                                       vk::VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO_KHR,        // sType
+                                       DE_NULL,                                                                                        // pNext
+                                       VK_TRUE,                                                                                        // protectedSubmit
+                               };
+                               submitInfo.pNext = &protectedInfo;
+
+                               const vk::VkPresentInfoKHR              presentInfo                                     =
+                               {
+                                       vk::VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+                                       DE_NULL,
+                                       1u,
+                                       &renderingCompleteSemaphore,
+                                       1u,
+                                       &*swapchain,
+                                       &imageNdx,
+                                       (vk::VkResult*)DE_NULL
+                               };
+
+                               renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
+                               VK_CHECK(vkd.queueSubmit(context.getQueue(), 1u, &submitInfo, (vk::VkFence)0));
+                               VK_CHECK(vkd.queuePresentKHR(context.getQueue(), &presentInfo));
+                       }
+               }
+
+               VK_CHECK(vkd.deviceWaitIdle(device));
+       }
+       catch (...)
+       {
+               // Make sure device is idle before destroying resources
+               vkd.deviceWaitIdle(device);
+               throw;
+       }
+
+       return tcu::TestStatus::pass("Rendering tests succeeded");
+}
+
+void getBasicRenderPrograms (vk::SourceCollections& dst, vk::wsi::Type)
+{
+       TriangleRenderer::getPrograms(dst);
+}
+
+void populateRenderGroup (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
+{
+       addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Test", getBasicRenderPrograms, basicRenderTest, wsiType);
+}
+
+void createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
+{
+       addTestGroup(testGroup, "create",                       "Create VkSwapchain with various parameters",                                   populateSwapchainGroup,         GroupParameters(wsiType, createSwapchainTest));
+       addTestGroup(testGroup, "render",                       "Rendering Tests",                                                                                              populateRenderGroup,            wsiType);
+}
+
+void createTypeSpecificTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
+{
+       addTestGroup(testGroup, "swapchain", "VkSwapchain Tests", createSwapchainTests, wsiType);
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createSwapchainTests (tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> wsiTestGroup (new tcu::TestCaseGroup(testCtx, "wsi", "WSI Tests"));
+
+       for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
+       {
+               const vk::wsi::Type     wsiType         = (vk::wsi::Type)typeNdx;
+
+               addTestGroup(&*wsiTestGroup, getName(wsiType), "", createTypeSpecificTests, wsiType);
+       }
+
+       return wsiTestGroup.release();
+}
+
+} // wsi
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.hpp b/external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.hpp
new file mode 100644 (file)
index 0000000..c89094f
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _VKTPROTECTEDMEMWSISWAPCHAINTESTS_HPP
+#define _VKTPROTECTEDMEMWSISWAPCHAINTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 Protected memory interaction with VkSwapchain Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+#include "vkDefs.hpp"
+
+namespace vkt
+{
+namespace ProtectedMem
+{
+
+tcu::TestCaseGroup* createSwapchainTests (tcu::TestContext& testCtx);
+
+} // wsi
+} // vkt
+
+#endif // _VKTPROTECTEDMEMWSISWAPCHAINTESTS_HPP
index 13bd952..e6c6d20 100755 (executable)
@@ -274072,3 +274072,69 @@ dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswa
 dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswap_8
 dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswap_9
 dEQP-VK.protected_memory.ssbo.ssbo_atomic.compute.compswap.random.atomic_compswap_10
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.xlib.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.xcb.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.wayland.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.mir.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.android.swapchain.render.basic
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.min_image_count
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_format
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_extent
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_array_layers
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_usage
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.image_sharing_mode
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.pre_transform
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.composite_alpha
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.present_mode
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.create.clipped
+dEQP-VK.protected_memory.interaction.wsi.win32.swapchain.render.basic