Add VK_KHX_multiview tests
authorArkadiusz Sarwa <arkadiusz.sarwa@mobica.com>
Wed, 18 Jan 2017 14:36:19 +0000 (15:36 +0100)
committerPyry Haulos <phaulos@google.com>
Tue, 28 Mar 2017 19:37:56 +0000 (12:37 -0700)
New tests:

dEQP-VK.multiview*

VK-GL-CTS issue: 70
Components: Vulkan

Change-Id: Ie90ca9607db3eb36bfd3d85d42537e97517ef828

18 files changed:
AndroidGen.mk
android/cts/master/vk-master.txt
external/fetch_sources.py
external/vulkancts/framework/vulkan/vkBasicTypes.inl
external/vulkancts/framework/vulkan/vkStrUtil.inl
external/vulkancts/framework/vulkan/vkStrUtilImpl.inl
external/vulkancts/framework/vulkan/vkStructTypes.inl
external/vulkancts/modules/vulkan/CMakeLists.txt
external/vulkancts/modules/vulkan/multiview/CMakeLists.txt [new file with mode: 0644]
external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/vktTestPackage.cpp
external/vulkancts/mustpass/1.0.3/vk-default.txt
external/vulkancts/scripts/src/vulkan.h.in

index a5403e2..428804b 100644 (file)
@@ -124,6 +124,9 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp \
        external/vulkancts/modules/vulkan/memory/vktMemoryRequirementsTests.cpp \
        external/vulkancts/modules/vulkan/memory/vktMemoryTests.cpp \
+       external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.cpp \
+       external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.cpp \
+       external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.cpp \
        external/vulkancts/modules/vulkan/pipeline/vktPipelineBlendTests.cpp \
        external/vulkancts/modules/vulkan/pipeline/vktPipelineCacheTests.cpp \
        external/vulkancts/modules/vulkan/pipeline/vktPipelineClearUtil.cpp \
@@ -945,6 +948,7 @@ LOCAL_C_INCLUDES := \
        $(deqp_dir)/external/vulkancts/modules/vulkan/geometry \
        $(deqp_dir)/external/vulkancts/modules/vulkan/image \
        $(deqp_dir)/external/vulkancts/modules/vulkan/memory \
+       $(deqp_dir)/external/vulkancts/modules/vulkan/multiview \
        $(deqp_dir)/external/vulkancts/modules/vulkan/pipeline \
        $(deqp_dir)/external/vulkancts/modules/vulkan/query_pool \
        $(deqp_dir)/external/vulkancts/modules/vulkan/rasterization \
index ccf5812..d5b0b5e 100644 (file)
@@ -179958,3 +179958,33 @@ dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw.instance_out_of_b
 dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw_indexed.last_index_out_of_bounds
 dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw_indexed.indices_out_of_bounds
 dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw_indexed.triangle_out_of_bounds
+dEQP-VK.multiview.masks.15
+dEQP-VK.multiview.masks.8
+dEQP-VK.multiview.masks.1_2_4_8
+dEQP-VK.multiview.masks.15_15_15_15
+dEQP-VK.multiview.masks.8_1_1_8
+dEQP-VK.multiview.masks.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.vertex_shader.15
+dEQP-VK.multiview.index.vertex_shader.8
+dEQP-VK.multiview.index.vertex_shader.1_2_4_8
+dEQP-VK.multiview.index.vertex_shader.15_15_15_15
+dEQP-VK.multiview.index.vertex_shader.8_1_1_8
+dEQP-VK.multiview.index.vertex_shader.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.fragment_shader.15
+dEQP-VK.multiview.index.fragment_shader.8
+dEQP-VK.multiview.index.fragment_shader.1_2_4_8
+dEQP-VK.multiview.index.fragment_shader.15_15_15_15
+dEQP-VK.multiview.index.fragment_shader.8_1_1_8
+dEQP-VK.multiview.index.fragment_shader.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.geometry_shader.15
+dEQP-VK.multiview.index.geometry_shader.8
+dEQP-VK.multiview.index.geometry_shader.1_2_4_8
+dEQP-VK.multiview.index.geometry_shader.15_15_15_15
+dEQP-VK.multiview.index.geometry_shader.8_1_1_8
+dEQP-VK.multiview.index.geometry_shader.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.tesellation_shader.15
+dEQP-VK.multiview.index.tesellation_shader.8
+dEQP-VK.multiview.index.tesellation_shader.1_2_4_8
+dEQP-VK.multiview.index.tesellation_shader.15_15_15_15
+dEQP-VK.multiview.index.tesellation_shader.8_1_1_8
+dEQP-VK.multiview.index.tesellation_shader.1_2_4_8_16_32_64_128_256_512
index 0d7c8e5..0bde658 100644 (file)
@@ -243,17 +243,17 @@ PACKAGES = [
        GitRepo(
                "https://github.com/KhronosGroup/SPIRV-Tools.git",
                None,
-               "ab03b879cab5d09147c257035145f0ad36c45064",
+               "11fbe5dc1f764d99e27a7049e2cbcd59915846c5",
                "spirv-tools"),
        GitRepo(
                "https://github.com/KhronosGroup/glslang.git",
                None,
-               "36852b838d05b2a1d5a0dd311b86c4971656fe36",
+               "c08fb8ab9c0d3aeafe11a8eeeed177c882ef76a9",
                "glslang"),
        GitRepo(
                "https://github.com/KhronosGroup/SPIRV-Headers.git",
                None,
-               "bd47a9abaefac00be692eae677daed1b977e625c",
+               "88d9403777e2b9dd08d6304d562f990e2e9d36a4",
                "spirv-headers"),
 ]
 
index c859439..a5275ad 100644 (file)
@@ -158,6 +158,9 @@ enum VkStructureType
        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV                             = 1000026000,
        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV                    = 1000026001,
        VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV                  = 1000026002,
+       VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX                                 = 1000053000,
+       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX                                = 1000053001,
+       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHX                              = 1000053002,
        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV                                  = 1000056000,
        VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV                                                = 1000056001,
        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV                                    = 1000057000,
@@ -1053,9 +1056,10 @@ typedef deUint32 VkBufferUsageFlags;
 
 enum VkPipelineCreateFlagBits
 {
-       VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT     = 0x00000001,
-       VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT        = 0x00000002,
-       VK_PIPELINE_CREATE_DERIVATIVE_BIT                       = 0x00000004,
+       VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT                             = 0x00000001,
+       VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT                                = 0x00000002,
+       VK_PIPELINE_CREATE_DERIVATIVE_BIT                                               = 0x00000004,
+       VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHX = 0x00000008,
 };
 typedef deUint32 VkPipelineCreateFlags;
 
@@ -1132,7 +1136,8 @@ typedef deUint32 VkAccessFlags;
 
 enum VkDependencyFlagBits
 {
-       VK_DEPENDENCY_BY_REGION_BIT     = 0x00000001,
+       VK_DEPENDENCY_BY_REGION_BIT                     = 0x00000001,
+       VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX        = 0x00000002,
 };
 typedef deUint32 VkDependencyFlags;
 
index 7f663bf..75b7b83 100644 (file)
@@ -363,6 +363,9 @@ std::ostream&       operator<<      (std::ostream& s, const VkDebugMarkerMarkerInfoEXT& val
 std::ostream&  operator<<      (std::ostream& s, const VkDedicatedAllocationImageCreateInfoNV& value);
 std::ostream&  operator<<      (std::ostream& s, const VkDedicatedAllocationBufferCreateInfoNV& value);
 std::ostream&  operator<<      (std::ostream& s, const VkDedicatedAllocationMemoryAllocateInfoNV& value);
+std::ostream&  operator<<      (std::ostream& s, const VkRenderPassMultiviewCreateInfoKHX& value);
+std::ostream&  operator<<      (std::ostream& s, const VkPhysicalDeviceMultiviewFeaturesKHX& value);
+std::ostream&  operator<<      (std::ostream& s, const VkPhysicalDeviceMultiviewPropertiesKHX& value);
 std::ostream&  operator<<      (std::ostream& s, const VkExternalImageFormatPropertiesNV& value);
 std::ostream&  operator<<      (std::ostream& s, const VkExternalMemoryImageCreateInfoNV& value);
 std::ostream&  operator<<      (std::ostream& s, const VkExportMemoryAllocateInfoNV& value);
index 3a1cead..9ac97dd 100644 (file)
@@ -169,6 +169,9 @@ const char* getStructureTypeName (VkStructureType value)
                case VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV:                               return "VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV";
                case VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV:                              return "VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV";
                case VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV:                    return "VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV";
+               case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX:                                   return "VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX";
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX:                                  return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX";
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHX:                                return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHX";
                case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV:                                    return "VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV";
                case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV:                                                  return "VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV";
                case VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV:                                              return "VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV";
@@ -1206,9 +1209,10 @@ tcu::Format::Bitfield<32> getPipelineCreateFlagsStr (VkPipelineCreateFlags value
 {
        static const tcu::Format::BitDesc s_desc[] =
        {
-               tcu::Format::BitDesc(VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,       "VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT"),
-               tcu::Format::BitDesc(VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,          "VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT"),
-               tcu::Format::BitDesc(VK_PIPELINE_CREATE_DERIVATIVE_BIT,                         "VK_PIPELINE_CREATE_DERIVATIVE_BIT"),
+               tcu::Format::BitDesc(VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,                               "VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT"),
+               tcu::Format::BitDesc(VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,                                  "VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT"),
+               tcu::Format::BitDesc(VK_PIPELINE_CREATE_DERIVATIVE_BIT,                                                 "VK_PIPELINE_CREATE_DERIVATIVE_BIT"),
+               tcu::Format::BitDesc(VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHX,   "VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHX"),
        };
        return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
 }
@@ -1309,7 +1313,8 @@ tcu::Format::Bitfield<32> getDependencyFlagsStr (VkDependencyFlags value)
 {
        static const tcu::Format::BitDesc s_desc[] =
        {
-               tcu::Format::BitDesc(VK_DEPENDENCY_BY_REGION_BIT,       "VK_DEPENDENCY_BY_REGION_BIT"),
+               tcu::Format::BitDesc(VK_DEPENDENCY_BY_REGION_BIT,               "VK_DEPENDENCY_BY_REGION_BIT"),
+               tcu::Format::BitDesc(VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX,  "VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX"),
        };
        return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));
 }
@@ -3666,6 +3671,44 @@ std::ostream& operator<< (std::ostream& s, const VkDedicatedAllocationMemoryAllo
        return s;
 }
 
+std::ostream& operator<< (std::ostream& s, const VkRenderPassMultiviewCreateInfoKHX& value)
+{
+       s << "VkRenderPassMultiviewCreateInfoKHX = {\n";
+       s << "\tsType = " << value.sType << '\n';
+       s << "\tpNext = " << value.pNext << '\n';
+       s << "\tsubpassCount = " << value.subpassCount << '\n';
+       s << "\tpViewMasks = " << value.pViewMasks << '\n';
+       s << "\tdependencyCount = " << value.dependencyCount << '\n';
+       s << "\tpViewOffsets = " << value.pViewOffsets << '\n';
+       s << "\tcorrelationMaskCount = " << value.correlationMaskCount << '\n';
+       s << "\tpCorrelationMasks = " << value.pCorrelationMasks << '\n';
+       s << '}';
+       return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceMultiviewFeaturesKHX& value)
+{
+       s << "VkPhysicalDeviceMultiviewFeaturesKHX = {\n";
+       s << "\tsType = " << value.sType << '\n';
+       s << "\tpNext = " << value.pNext << '\n';
+       s << "\tmultiview = " << value.multiview << '\n';
+       s << "\tmultiviewGeometryShader = " << value.multiviewGeometryShader << '\n';
+       s << "\tmultiviewTessellationShader = " << value.multiviewTessellationShader << '\n';
+       s << '}';
+       return s;
+}
+
+std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceMultiviewPropertiesKHX& value)
+{
+       s << "VkPhysicalDeviceMultiviewPropertiesKHX = {\n";
+       s << "\tsType = " << value.sType << '\n';
+       s << "\tpNext = " << value.pNext << '\n';
+       s << "\tmaxMultiviewViewCount = " << value.maxMultiviewViewCount << '\n';
+       s << "\tmaxMultiviewInstanceIndex = " << value.maxMultiviewInstanceIndex << '\n';
+       s << '}';
+       return s;
+}
+
 std::ostream& operator<< (std::ostream& s, const VkExternalImageFormatPropertiesNV& value)
 {
        s << "VkExternalImageFormatPropertiesNV = {\n";
index 17d33ff..813a7cf 100644 (file)
@@ -1521,6 +1521,35 @@ struct VkDedicatedAllocationMemoryAllocateInfoNV
        VkBuffer                buffer;
 };
 
+struct VkRenderPassMultiviewCreateInfoKHX
+{
+       VkStructureType sType;
+       const void*             pNext;
+       deUint32                subpassCount;
+       const deUint32* pViewMasks;
+       deUint32                dependencyCount;
+       const deInt32*  pViewOffsets;
+       deUint32                correlationMaskCount;
+       const deUint32* pCorrelationMasks;
+};
+
+struct VkPhysicalDeviceMultiviewFeaturesKHX
+{
+       VkStructureType sType;
+       void*                   pNext;
+       VkBool32                multiview;
+       VkBool32                multiviewGeometryShader;
+       VkBool32                multiviewTessellationShader;
+};
+
+struct VkPhysicalDeviceMultiviewPropertiesKHX
+{
+       VkStructureType sType;
+       void*                   pNext;
+       deUint32                maxMultiviewViewCount;
+       deUint32                maxMultiviewInstanceIndex;
+};
+
 struct VkExternalImageFormatPropertiesNV
 {
        VkImageFormatProperties                         imageFormatProperties;
index 4c3e1b9..c245554 100644 (file)
@@ -24,6 +24,7 @@ add_subdirectory(fragment_ops)
 add_subdirectory(geometry)
 add_subdirectory(texture)
 add_subdirectory(robustness)
+add_subdirectory(multiview)
 
 include_directories(
        api
@@ -50,6 +51,7 @@ include_directories(
        texture
        geometry
        robustness
+       multiview
        )
 
 set(DEQP_VK_SRCS
@@ -101,6 +103,7 @@ set(DEQP_VK_LIBS
        deqp-vk-texture
        deqp-vk-geometry
        deqp-vk-robustness
+       deqp-vk-multiview
        )
 
 if (DE_COMPILER_IS_MSC AND (DE_PTR_SIZE EQUAL 4))
diff --git a/external/vulkancts/modules/vulkan/multiview/CMakeLists.txt b/external/vulkancts/modules/vulkan/multiview/CMakeLists.txt
new file mode 100644 (file)
index 0000000..95344dc
--- /dev/null
@@ -0,0 +1,18 @@
+include_directories(..)
+
+set(DEQP_VK_MULTI_VIEW_SRCS
+       vktMultiViewTests.hpp
+       vktMultiViewTests.cpp
+       vktMultiViewRenderTests.hpp
+       vktMultiViewRenderTests.cpp
+       vktMultiViewRenderUtil.hpp
+       vktMultiViewRenderUtil.cpp
+)
+
+set(DEQP_VK_MULTI_VIEW_LIBS
+       tcutil
+       vkutil
+)
+
+add_library(deqp-vk-multiview STATIC ${DEQP_VK_MULTI_VIEW_SRCS})
+target_link_libraries(deqp-vk-multiview ${DEQP_VK_MULTI_VIEW_LIBS})
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.cpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.cpp
new file mode 100644 (file)
index 0000000..ef618f3
--- /dev/null
@@ -0,0 +1,967 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Multi View Render Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktMultiViewRenderTests.hpp"
+#include "vktMultiViewRenderUtil.hpp"
+
+#include "vktTestCase.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkPlatform.hpp"
+#include "vkMemUtil.hpp"
+#include "vkImageUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuResource.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuCommandLine.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuRGBA.hpp"
+
+#include "deSharedPtr.hpp"
+
+namespace vkt
+{
+namespace MultiView
+{
+namespace
+{
+
+using namespace vk;
+using de::MovePtr;
+using de::UniquePtr;
+using std::vector;
+using std::map;
+using std::string;
+
+enum ViewIndex
+{
+       VIEW_INDEX_NOT_USE,
+       VIEW_INDEX_IN_VERTEX,
+       VIEW_INDEX_IN_FRAGMENT,
+       VIEW_INDEX_IN_GEOMETRY,
+       VIEW_INDEX_IN_TESELLATION,
+       VIEW_INDEX_LAST
+};
+
+struct TestParameters
+{
+       VkExtent3D                      extent;
+       vector<deUint32>        viewMasks;
+       ViewIndex                       viewIndex;
+};
+
+class MultiViewRenderTestInstance : public TestInstance
+{
+public:
+                                                                       MultiViewRenderTestInstance             (Context& context, const TestParameters& parameters);
+private:
+       typedef de::SharedPtr<Unique<VkPipeline> >              PipelineSp;
+       typedef de::SharedPtr<Unique<VkShaderModule> >  ShaderModuleSP;
+
+       struct VertexData
+       {
+               VertexData (const tcu::Vec4 position_, const tcu::Vec4 color_)
+                       : position      (position_)
+                       , color         (color_)
+               {}
+               tcu::Vec4       position;
+               tcu::Vec4       color;
+       };
+
+       tcu::TestStatus                                 iterate                                                 (void);
+       void                                                    createMultiViewDevices                  (void);
+       void                                                    madeShaderModule                                (map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams);
+       Move<VkPipeline>                                makeGraphicsPipeline                    (const VkRenderPass                                                     renderPass,
+                                                                                                                                        const VkPipelineLayout                                         pipelineLayout,
+                                                                                                                                        const deUint32                                                         pipelineShaderStageCount,
+                                                                                                                                        const VkPipelineShaderStageCreateInfo*         pipelineShaderStageCreate,
+                                                                                                                                        const deUint32                                                         subpass);
+       void                                                    readImage                                               (VkImage image, const tcu::PixelBufferAccess& dst);
+       bool                                                    checkImage                                              (tcu::ConstPixelBufferAccess& dst);
+
+       const TestParameters&                   m_parameters;
+       VkFormat                                                m_colorFormat;
+       const deUint32                                  m_squareCount;
+       Move<VkDevice>                                  m_logicalDevice;
+       MovePtr<DeviceDriver>                   m_deviceDriver;
+       MovePtr<Allocator>                              m_allocator;
+       deUint32                                                m_queueFamilyIndex;
+       VkQueue                                                 m_queue;
+       vector<VertexData>                              m_data;
+       Move<VkCommandPool>                             m_cmdPool;
+       Move<VkCommandBuffer>                   m_cmdBuffer;
+};
+
+MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters)
+       : TestInstance          (context)
+       , m_parameters          (parameters)
+       , m_colorFormat         (VK_FORMAT_R8G8B8A8_UNORM)
+       , m_squareCount         (4u)
+{
+       if(!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHX_multiview"))
+               throw tcu::NotSupportedError("VK_KHX_multiview is not supported");
+
+       createMultiViewDevices();
+       {
+               tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
+               m_data.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
+
+               color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
+               m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color));
+
+               color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color));
+
+               color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color));
+               m_data.push_back(VertexData(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color));
+       }
+}
+
+tcu::TestStatus MultiViewRenderTestInstance::iterate (void)
+{
+       const deUint32                                                  subpassCount                            = static_cast<deUint32>(m_parameters.viewMasks.size());
+       // Color attachment
+       const VkImageSubresourceRange                   colorImageSubresourceRange      = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_parameters.extent.depth);
+       const VkImageCreateInfo                                 colorAttachmentImageInfo        = makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_parameters.extent, m_colorFormat,VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
+       Unique<VkImage>                                                 colorAttachmentImage            (createImage(*m_deviceDriver, *m_logicalDevice, &colorAttachmentImageInfo));
+       const de::UniquePtr<Allocation>                 allocationImage                         (m_allocator->allocate(getImageMemoryRequirements(*m_deviceDriver, *m_logicalDevice, *colorAttachmentImage), MemoryRequirement::Any));
+       VK_CHECK(m_deviceDriver->bindImageMemory(*m_logicalDevice, *colorAttachmentImage, allocationImage->getMemory(), allocationImage->getOffset()));
+       Unique<VkImageView>                                             colorAttachmentView                     (makeImageView(*m_deviceDriver, *m_logicalDevice, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_colorFormat, colorImageSubresourceRange));
+
+       // FrameBuffer & renderPass
+       Unique<VkRenderPass>                                    renderPass                                      (makeRenderPass (*m_deviceDriver, *m_logicalDevice, m_colorFormat, m_parameters.viewMasks));
+       Unique<VkFramebuffer>                                   frameBuffer                                     (makeFramebuffer(*m_deviceDriver, *m_logicalDevice, *renderPass, *colorAttachmentView, m_parameters.extent.width, m_parameters.extent.height, 1u));
+
+       // vertexBuffer
+       const VkDeviceSize                                              vertexDataSize                          = static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>( m_data.size() * sizeof(VertexData)),
+                                                                                                                                               static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
+       const VkBufferCreateInfo                                bufferInfo                                      = makeBufferCreateInfo(vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
+       Unique<VkBuffer>                                                vertexBuffer                            (createBuffer(*m_deviceDriver, *m_logicalDevice, &bufferInfo));
+       const de::UniquePtr<Allocation>                 allocationBuffer                        (m_allocator->allocate(getBufferMemoryRequirements(*m_deviceDriver, *m_logicalDevice, *vertexBuffer),  MemoryRequirement::HostVisible));
+
+       // pipelineLayout
+       Unique<VkPipelineLayout>                                pipelineLayout                          (makePipelineLayout(*m_deviceDriver, *m_logicalDevice));
+
+       // pipelines
+       map<VkShaderStageFlagBits, ShaderModuleSP>      shaderModule;
+       vector<PipelineSp>                                              pipelines(subpassCount);
+
+       {
+               vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
+               madeShaderModule(shaderModule, shaderStageParams);
+               for(deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
+                       pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
+       }
+
+       // cmdPool
+       {
+               const VkCommandPoolCreateInfo                   cmdPoolParams                           =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType              sType;
+                       DE_NULL,                                                                                        // const void*                  pNext;
+                       VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCmdPoolCreateFlags flags;
+                       m_queueFamilyIndex,                                                                     // deUint32                             queueFamilyIndex;
+               };
+               m_cmdPool = createCommandPool(*m_deviceDriver, *m_logicalDevice, &cmdPoolParams);
+       }
+
+       // Init host buffer data
+       VK_CHECK(m_deviceDriver->bindBufferMemory(*m_logicalDevice, *vertexBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset()));
+       deMemcpy(allocationBuffer->getHostPtr(), m_data.data(), static_cast<size_t>(vertexDataSize));
+       flushMappedMemoryRange(*m_deviceDriver, *m_logicalDevice, allocationBuffer->getMemory(), allocationBuffer->getOffset(), static_cast<size_t>(vertexDataSize));
+
+       // cmdBuffer
+       {
+               const VkCommandBufferAllocateInfo       cmdBufferAllocateInfo           =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
+                       VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
+                       1u,                                                                                             // deUint32                                     bufferCount;
+               };
+               m_cmdBuffer     = allocateCommandBuffer(*m_deviceDriver, *m_logicalDevice, &cmdBufferAllocateInfo);
+       }
+
+       beginCommandBuffer(*m_deviceDriver, *m_cmdBuffer);
+
+       {
+               const VkRect2D                                  renderArea                              = { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
+               const VkClearValue                              renderPassClearValue    = makeClearValueColor(tcu::Vec4(0.0f));
+               const VkDeviceSize                              vertexBufferOffset              = 0u;
+               const deUint32                                  drawCountPerSubpass             = (subpassCount == 1) ? m_squareCount : 1u;
+
+               const VkRenderPassBeginInfo             renderPassBeginInfo =
+               {
+                       VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
+                       DE_NULL,                                                                        // const void*                  pNext;
+                       *renderPass,                                                            // VkRenderPass                 renderPass;
+                       *frameBuffer,                                                           // VkFramebuffer                framebuffer;
+                       renderArea,                                                                     // VkRect2D                             renderArea;
+                       1u,                                                                                     // uint32_t                             clearValueCount;
+                       &renderPassClearValue,                                          // const VkClearValue*  pClearValues;
+               };
+
+               const VkImageSubresourceRange   subresourceRange        =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,      //VkImageAspectFlags    aspectMask;
+                       0u,                                                     //deUint32                              baseMipLevel;
+                       1u,                                                     //deUint32                              levelCount;
+                       0u,                                                     //deUint32                              baseArrayLayer;
+                       m_parameters.extent.depth,      //deUint32                              layerCount;
+               };
+
+               imageBarrier(*m_deviceDriver, *m_cmdBuffer, *colorAttachmentImage, subresourceRange, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
+               m_deviceDriver->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+               m_deviceDriver->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*vertexBuffer), &vertexBufferOffset);
+
+               for(deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
+               {
+                       m_deviceDriver->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
+
+                       for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
+                               m_deviceDriver->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
+
+                       if (subpassNdx < subpassCount - 1u)
+                               m_deviceDriver->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
+               }
+
+               m_deviceDriver->cmdEndRenderPass(*m_cmdBuffer);
+               imageBarrier(*m_deviceDriver, *m_cmdBuffer, *colorAttachmentImage,
+                       subresourceRange, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
+       }
+
+       m_deviceDriver->endCommandBuffer(*m_cmdBuffer);
+       submitCommandsAndWait(*m_deviceDriver, *m_logicalDevice, m_queue, *m_cmdBuffer);
+
+       std::vector<deUint8>            pixelAccessData;
+       pixelAccessData.resize(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_colorFormat).getPixelSize());
+       deMemset(pixelAccessData.data(), 0, pixelAccessData.size());
+       tcu::PixelBufferAccess dst (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
+       readImage (*colorAttachmentImage, dst);
+
+       if (!checkImage(dst))
+               return tcu::TestStatus::fail("Fail");
+       return tcu::TestStatus::pass("Pass");
+}
+
+void MultiViewRenderTestInstance::createMultiViewDevices (void)
+{
+       const InstanceInterface&                                instance                                = m_context.getInstanceInterface();
+       const VkPhysicalDevice                                  physicalDevice                  = m_context.getPhysicalDevice();
+       const vector<VkQueueFamilyProperties>   queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
+
+       deUint32 queuePropertiesNdx = 0;
+       for (; queuePropertiesNdx < queueFamilyProperties.size(); ++queuePropertiesNdx)
+       {
+               if (queueFamilyProperties[queuePropertiesNdx].queueFlags | VK_QUEUE_GRAPHICS_BIT )
+                       break;
+       }
+
+       m_queueFamilyIndex      = queuePropertiesNdx;
+       const float                                                             queuePriorities                 = 1.0f;
+       const VkDeviceQueueCreateInfo                   queueInfo                               =
+       {
+               VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,     //VkStructureType                       sType;
+               DE_NULL,                                                                        //const void*                           pNext;
+               (VkDeviceQueueCreateFlags)0u,                           //VkDeviceQueueCreateFlags      flags;
+               m_queueFamilyIndex,                                                     //deUint32                                      queueFamilyIndex;
+               1u,                                                                                     //deUint32                                      queueCount;
+               &queuePriorities                                                        //const float*                          pQueuePriorities;
+       };
+
+       VkPhysicalDeviceMultiviewFeaturesKHX    multiviewFeatures               =
+       {
+               VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX,       // VkStructureType      sType;
+               DE_NULL,                                                                                                        // void*                        pNext;
+               DE_FALSE,                                                                                                       // VkBool32                     multiview;
+               DE_FALSE,                                                                                                       // VkBool32                     multiviewGeometryShader;
+               DE_FALSE,                                                                                                       // VkBool32                     multiviewTessellationShader;
+       };
+
+       VkPhysicalDeviceFeatures2KHR                    enabledFeatures;
+       enabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
+       enabledFeatures.pNext = &multiviewFeatures;
+
+       instance.getPhysicalDeviceFeatures2KHR(physicalDevice, &enabledFeatures);
+
+       if (!multiviewFeatures.multiview)
+               TCU_THROW(NotSupportedError, "MultiView not supported");
+
+       if (VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex && !multiviewFeatures.multiviewGeometryShader)
+               TCU_THROW(NotSupportedError, "Geometry shader is not supported");
+
+       if (VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader)
+               TCU_THROW(NotSupportedError, "Tessellation shader is not supported");
+
+       {
+               const std::vector<std::string>& deviceExtensions        = m_context.getDeviceExtensions();
+               std::vector<const char*>                charDevExtensions;
+
+               for (std::size_t ndx = 0; ndx < deviceExtensions.size(); ++ndx)
+                       charDevExtensions.push_back(deviceExtensions[ndx].c_str());
+
+               const VkDeviceCreateInfo                deviceInfo              =
+               {
+                       VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                                   //VkStructureType                                       sType;
+                       &enabledFeatures,                                                                                               //const void*                                           pNext;
+                       0u,                                                                                                                             //VkDeviceCreateFlags                           flags;
+                       1u,                                                                                                                             //deUint32                                                      queueCreateInfoCount;
+                       &queueInfo,                                                                                                             //const VkDeviceQueueCreateInfo*        pQueueCreateInfos;
+                       0u,                                                                                                                             //deUint32                                                      enabledLayerCount;
+                       DE_NULL,                                                                                                                //const char* const*                            ppEnabledLayerNames;
+                       static_cast<deUint32>(deviceExtensions.size()),                                 //deUint32                                                      enabledExtensionCount;
+                       charDevExtensions.empty() ? DE_NULL : &charDevExtensions[0],    //const char* const*                            pEnabledExtensionNames;
+                       DE_NULL                                                                                                                 //const VkPhysicalDeviceFeatures*       pEnabledFeatures;
+               };
+
+               m_logicalDevice = createDevice(instance, physicalDevice, &deviceInfo);
+               m_deviceDriver  = MovePtr<DeviceDriver>(new DeviceDriver(instance, *m_logicalDevice));
+               m_allocator             = MovePtr<Allocator>(new SimpleAllocator(*m_deviceDriver, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice)));
+               m_deviceDriver->getDeviceQueue(*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue);
+       }
+}
+
+void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams)
+{
+       // create shaders modules
+       switch (m_parameters.viewIndex)
+       {
+               case VIEW_INDEX_NOT_USE:
+               case VIEW_INDEX_IN_VERTEX:
+               case VIEW_INDEX_IN_FRAGMENT:
+                       shaderModule[VK_SHADER_STAGE_VERTEX_BIT]                                        = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
+                       shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
+                       break;
+               case VIEW_INDEX_IN_GEOMETRY:
+                       shaderModule[VK_SHADER_STAGE_VERTEX_BIT]                                        = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
+                       shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0))));
+                       shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
+                       break;
+               case VIEW_INDEX_IN_TESELLATION:
+                       shaderModule[VK_SHADER_STAGE_VERTEX_BIT]                                        = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
+                       shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT]          = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0))));
+                       shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT]       = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0))));
+                       shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]                                      = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_deviceDriver, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
+                       break;
+               default:
+                       DE_ASSERT(0);
+               break;
+       };
+
+       VkPipelineShaderStageCreateInfo pipelineShaderStage             =
+       {
+                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                // const void*                                                  pNext;
+                       (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
+                       (VkShaderStageFlagBits)0,                                                               // VkShaderStageFlagBits                                stage;
+                       (VkShaderModule)0,                                                                              // VkShaderModule                                               module;
+                       "main",                                                                                                 // const char*                                                  pName;
+                       (const VkSpecializationInfo*)DE_NULL,                                   // const VkSpecializationInfo*                  pSpecializationInfo;
+       };
+
+       for(map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it)
+       {
+               pipelineShaderStage.stage       = it->first;
+               pipelineShaderStage.module      = **it->second;
+               shaderStageParams.push_back(pipelineShaderStage);
+       }
+}
+
+Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass                                                 renderPass,
+                                                                                                                                       const VkPipelineLayout                                          pipelineLayout,
+                                                                                                                                       const deUint32                                                          pipelineShaderStageCount,
+                                                                                                                                       const VkPipelineShaderStageCreateInfo*          pipelineShaderStageCreate,
+                                                                                                                                       const deUint32                                                          subpass)
+{
+       const VkVertexInputBindingDescription                   vertexInputBindingDescription           =
+       {
+               0u,                                                                                     // binding;
+               static_cast<deUint32>(sizeof(VertexData)),      // stride;
+               VK_VERTEX_INPUT_RATE_VERTEX                                     // inputRate
+       };
+
+       const VkVertexInputAttributeDescription                 vertexInputAttributeDescriptions[]      =
+       {
+               {
+                       0u,
+                       0u,
+                       VK_FORMAT_R32G32B32A32_SFLOAT,
+                       0u
+               },      // VertexElementData::position
+               {
+                       1u,
+                       0u,
+                       VK_FORMAT_R32G32B32A32_SFLOAT,
+                       static_cast<deUint32>(sizeof(tcu::Vec4))
+               },      // VertexElementData::color
+       };
+
+       const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams                  =
+       {                                                                                                                                       // sType;
+               VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // pNext;
+               NULL,                                                                                                                   // flags;
+               0u,                                                                                                                             // vertexBindingDescriptionCount;
+               1u,                                                                                                                             // pVertexBindingDescriptions;
+               &vertexInputBindingDescription,                                                                 // vertexAttributeDescriptionCount;
+               2u,                                                                                                                             // pVertexAttributeDescriptions;
+               vertexInputAttributeDescriptions
+       };
+
+
+       const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams                =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,                                                                                                                                            // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                                                                                                                                                                        // const void*                                                          pNext;
+               0u,                                                                                                                                                                                                                                                                     // VkPipelineInputAssemblyStateCreateFlags      flags;
+               (VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,        // VkPrimitiveTopology                                          topology;
+               VK_FALSE,                                                                                                                                                                                                                                                       // VkBool32                                                                     primitiveRestartEnable;
+       };
+
+       const VkViewport                                                                viewport                                                =
+       {
+               0.0f,                                                           // float        originX;
+               0.0f,                                                           // float        originY;
+               (float)m_parameters.extent.width,       // float        width;
+               (float)m_parameters.extent.height,      // float        height;
+               0.0f,                                                           // float        minDepth;
+               1.0f                                                            // float        maxDepth;
+       };
+
+       const VkRect2D                                                          scissor                                                         =
+       {
+               { 0, 0 },                                                                                                       // VkOffset2D   offset;
+               { m_parameters.extent.width, m_parameters.extent.height }       // VkExtent2D   extent;
+       };
+
+       const VkPipelineViewportStateCreateInfo         viewportStateParams                                     =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                              sType;
+               DE_NULL,                                                                                                // const void*                                                  pNext;
+               0u,                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
+               1u,                                                                                                             // deUint32                                                             viewportCount;
+               &viewport,                                                                                              // const VkViewport*                                    pViewports;
+               1u,                                                                                                             // deUint32                                                             scissorCount;
+               &scissor                                                                                                // const VkRect2D*                                              pScissors;
+       };
+
+       const VkPipelineRasterizationStateCreateInfo    rasterStateParams                               =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                        // const void*                                                          pNext;
+               0u,                                                                                                                     // VkPipelineRasterizationStateCreateFlags      flags;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     depthClampEnable;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     rasterizerDiscardEnable;
+               VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                                                        polygonMode;                            //[TODO]
+               VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                                                      cullMode;
+               VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                                          frontFace;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     depthBiasEnable;
+               0.0f,                                                                                                           // float                                                                        depthBiasConstantFactor;
+               0.0f,                                                                                                           // float                                                                        depthBiasClamp;
+               0.0f,                                                                                                           // float                                                                        depthBiasSlopeFactor;
+               1.0f,                                                                                                           // float                                                                        lineWidth;
+       };
+
+       const VkPipelineMultisampleStateCreateInfo      multisampleStateParams                          =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                        // const void*                                                          pNext;
+               0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
+               VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
+               0.0f,                                                                                                           // float                                                                        minSampleShading;
+               DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToOneEnable;
+       };
+
+       VkPipelineDepthStencilStateCreateInfo           depthStencilStateParams                         =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                        // const void*                                                          pNext;
+               0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
+               VK_TRUE,                                                                                                        // VkBool32                                                                     depthTestEnable;
+               VK_TRUE,                                                                                                        // VkBool32                                                                     depthWriteEnable;
+               VK_COMPARE_OP_LESS_OR_EQUAL,                                                            // VkCompareOp                                                          depthCompareOp;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
+               VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
+               // VkStencilOpState front;
+               {
+                       VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
+                       VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
+                       VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
+                       VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
+                       0u,                                             // deUint32             compareMask;
+                       0u,                                             // deUint32             writeMask;
+                       0u,                                             // deUint32             reference;
+               },
+               // VkStencilOpState back;
+               {
+                       VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
+                       VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
+                       VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
+                       VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
+                       0u,                                             // deUint32             compareMask;
+                       0u,                                             // deUint32             writeMask;
+                       0u,                                             // deUint32             reference;
+               },
+               0.0f,   // float        minDepthBounds;
+               1.0f,   // float        maxDepthBounds;
+       };
+
+       const VkPipelineColorBlendAttachmentState       colorBlendAttachmentState                       =
+       {
+               VK_FALSE,                               // VkBool32                     blendEnable;
+               VK_BLEND_FACTOR_ONE,    // VkBlendFactor        srcColorBlendFactor;
+               VK_BLEND_FACTOR_ZERO,   // VkBlendFactor        dstColorBlendFactor;
+               VK_BLEND_OP_ADD,                // VkBlendOp            colorBlendOp;
+               VK_BLEND_FACTOR_ONE,    // VkBlendFactor        srcAlphaBlendFactor;
+               VK_BLEND_FACTOR_ZERO,   // VkBlendFactor        dstAlphaBlendFactor;
+               VK_BLEND_OP_ADD,                // VkBlendOp            alphaBlendOp;
+               VK_COLOR_COMPONENT_R_BIT |
+               VK_COLOR_COMPONENT_G_BIT |
+               VK_COLOR_COMPONENT_B_BIT |
+               VK_COLOR_COMPONENT_A_BIT        // VkColorComponentFlags        colorWriteMask;
+       };
+
+       const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams                           =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
+               DE_NULL,                                                                                                        // const void*                                                                  pNext;
+               0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
+               VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
+               VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
+               1u,                                                                                                                     // deUint32                                                                             attachmentCount;
+               &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
+               { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
+       };
+
+       VkPipelineTessellationStateCreateInfo           TessellationState                                       =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                        // const void*                                                          pNext;
+               (VkPipelineTessellationStateCreateFlags)0,                                      // VkPipelineTessellationStateCreateFlags       flags;
+               4u                                                                                                                      // deUint32                                                                     patchControlPoints;
+       };
+
+       const VkGraphicsPipelineCreateInfo                      graphicsPipelineParams                          =
+       {
+               VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                                                // VkStructureType                                                                      sType;
+               DE_NULL,                                                                                                                                                                // const void*                                                                          pNext;
+               (VkPipelineCreateFlags)0u,                                                                                                                              // VkPipelineCreateFlags                                                        flags;
+               pipelineShaderStageCount,                                                                                                                               // deUint32                                                                                     stageCount;
+               pipelineShaderStageCreate,                                                                                                                              // const VkPipelineShaderStageCreateInfo*                       pStages;
+               &vertexInputStateParams,                                                                                                                                // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
+               &inputAssemblyStateParams,                                                                                                                              // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
+               (VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL,    // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
+               &viewportStateParams,                                                                                                                                   // const VkPipelineViewportStateCreateInfo*                     pViewportState;
+               &rasterStateParams,                                                                                                                                             // const VkPipelineRasterizationStateCreateInfo*        pRasterState;
+               &multisampleStateParams,                                                                                                                                // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
+               &depthStencilStateParams,                                                                                                                               // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
+               &colorBlendStateParams,                                                                                                                                 // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
+               (const VkPipelineDynamicStateCreateInfo*)DE_NULL,                                                                               // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
+               pipelineLayout,                                                                                                                                                 // VkPipelineLayout                                                                     layout;
+               renderPass,                                                                                                                                                             // VkRenderPass                                                                         renderPass;
+               subpass,                                                                                                                                                                // deUint32                                                                                     subpass;
+               0u,                                                                                                                                                                             // VkPipeline                                                                           basePipelineHandle;
+               0,                                                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
+       };
+
+       return createGraphicsPipeline(*m_deviceDriver, *m_logicalDevice, DE_NULL, &graphicsPipelineParams);
+}
+
+void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
+{
+       Move<VkBuffer>                          buffer;
+       de::MovePtr<Allocation>         bufferAlloc;
+       const VkDeviceSize                      pixelDataSize   = dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_colorFormat).getPixelSize();
+
+       // Create destination buffer
+       {
+               const VkBufferCreateInfo bufferParams =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
+                       DE_NULL,                                                                // const void*                  pNext;
+                       0u,                                                                             // VkBufferCreateFlags  flags;
+                       pixelDataSize,                                                  // VkDeviceSize                 size;
+                       VK_BUFFER_USAGE_TRANSFER_DST_BIT,               // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+                       1u,                                                                             // deUint32                             queueFamilyIndexCount;
+                       &m_queueFamilyIndex,                                    // const deUint32*              pQueueFamilyIndices;
+               };
+
+               buffer          = createBuffer(*m_deviceDriver, *m_logicalDevice, &bufferParams);
+               bufferAlloc     = m_allocator->allocate(getBufferMemoryRequirements(*m_deviceDriver, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
+               VK_CHECK(m_deviceDriver->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
+
+               deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
+               flushMappedMemoryRange(*m_deviceDriver, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
+       }
+
+       const VkBufferMemoryBarrier     bufferBarrier   =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
+               DE_NULL,                                                                        // const void*          pNext;
+               VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
+               VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
+               *buffer,                                                                        // VkBuffer                     buffer;
+               0u,                                                                                     // VkDeviceSize         offset;
+               pixelDataSize                                                           // VkDeviceSize         size;
+       };
+
+       // Copy image to buffer
+       const VkImageAspectFlags        aspect                  = getAspectFlags(dst.getFormat());
+       const VkBufferImageCopy         copyRegion              =
+       {
+               0u,                                                                             // VkDeviceSize                         bufferOffset;
+               (deUint32)dst.getWidth(),                               // deUint32                                     bufferRowLength;
+               (deUint32)dst.getHeight(),                              // deUint32                                     bufferImageHeight;
+               {
+                       aspect,                                                         // VkImageAspectFlags           aspect;
+                       0u,                                                                     // deUint32                                     mipLevel;
+                       0u,                                                                     // deUint32                                     baseArrayLayer;
+                       m_parameters.extent.depth,                      // deUint32                                     layerCount;
+               },                                                                              // VkImageSubresourceLayers     imageSubresource;
+               { 0, 0, 0 },                                                    // VkOffset3D                           imageOffset;
+               { m_parameters.extent.width, m_parameters.extent.height, 1u }   // VkExtent3D                           imageExtent;
+       };
+
+       beginCommandBuffer (*m_deviceDriver, *m_cmdBuffer);
+       {
+               VkImageSubresourceRange subresourceRange        =
+               {
+                       aspect,                                         // VkImageAspectFlags   aspectMask;
+                       0u,                                                     // deUint32                             baseMipLevel;
+                       1u,                                                     // deUint32                             mipLevels;
+                       0u,                                                     // deUint32                             baseArraySlice;
+                       m_parameters.extent.depth,      // deUint32                             arraySize;
+               };
+
+               imageBarrier (*m_deviceDriver, *m_cmdBuffer, image, subresourceRange, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+               m_deviceDriver->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
+               m_deviceDriver->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
+       }
+       VK_CHECK(m_deviceDriver->endCommandBuffer(*m_cmdBuffer));
+       submitCommandsAndWait(*m_deviceDriver, *m_logicalDevice, m_queue, *m_cmdBuffer);
+
+       // Read buffer data
+       invalidateMappedMemoryRange(*m_deviceDriver, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
+       tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
+}
+
+bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame)
+{
+       tcu::Texture2DArray                                     referenceFrame  (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth);
+       const deUint32                                          subpassCount    = static_cast<deUint32>(m_parameters.viewMasks.size());
+       referenceFrame.allocLevel(0);
+
+       deMemset (referenceFrame.getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_colorFormat).getPixelSize());
+
+       for(deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
+       {
+               int                     layerNdx        = 0;
+               deUint32        mask            = m_parameters.viewMasks[subpassNdx];
+
+               while (mask > 0u)
+               {
+                       int colorNdx    = 0;
+                       if (mask & 1u)
+                       {
+                               const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount;
+                               if (subpassQuarterNdx == 0u)
+                               {
+                                       const tcu::Vec4 color = (VIEW_INDEX_NOT_USE == m_parameters.viewIndex) ? m_data[colorNdx].color : m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
+                                       for (deUint32 y = 0u; y < m_parameters.extent.height/2u; ++y)
+                                       for (deUint32 x = 0u; x < m_parameters.extent.width/2u; ++x)
+                                                       referenceFrame.getLevel(0).setPixel(color, x, y, layerNdx);
+                               }
+
+                               colorNdx += 4;
+                               if (subpassQuarterNdx == 1u || subpassCount == 1u)
+                               {
+                                       const tcu::Vec4 color = (VIEW_INDEX_NOT_USE == m_parameters.viewIndex) ? m_data[colorNdx].color : m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
+                                       for (deUint32 y = m_parameters.extent.height/2u; y < m_parameters.extent.height; ++y)
+                                       for (deUint32 x = 0u; x < m_parameters.extent.width/2u; ++x)
+                                               referenceFrame.getLevel(0).setPixel(color , x, y, layerNdx);
+                               }
+
+                               colorNdx += 4;
+                               if (subpassQuarterNdx == 2u || subpassCount == 1u)
+                               {
+                                       const tcu::Vec4 color = (VIEW_INDEX_NOT_USE == m_parameters.viewIndex) ? m_data[colorNdx].color : m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
+                                       for (deUint32 y = 0u; y < m_parameters.extent.height/2u; ++y)
+                                       for (deUint32 x =  m_parameters.extent.width/2u; x < m_parameters.extent.width; ++x)
+                                                       referenceFrame.getLevel(0).setPixel(color, x, y, layerNdx);
+                               }
+
+                               colorNdx += 4;
+                               if (subpassQuarterNdx == 3u || subpassCount == 1u)
+                               {
+                                       const tcu::Vec4 color = (VIEW_INDEX_NOT_USE == m_parameters.viewIndex) ? m_data[colorNdx].color : m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
+                                       for (deUint32 y =  m_parameters.extent.height/2u; y < m_parameters.extent.height; ++y)
+                                       for (deUint32 x =  m_parameters.extent.width/2u; x < m_parameters.extent.width; ++x)
+                                                       referenceFrame.getLevel(0).setPixel(color, x, y, layerNdx);
+                               }
+                       }
+                       mask = mask >> 1;
+                       ++layerNdx;
+               }
+       }
+
+       if (tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", referenceFrame.getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
+               return true;
+
+       for(deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++)
+       {
+               tcu::ConstPixelBufferAccess ref (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame.getLevel(0).getPixelPtr(0, 0, layerNdx));
+               tcu::ConstPixelBufferAccess dst (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx));
+               tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING);
+       }
+
+       return false;
+}
+
+class MultiViewRenderTestsCase : public vkt::TestCase
+{
+public:
+       MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const char *description, TestParameters parameters)
+               : TestCase                      (context, name, description)
+               , m_parameters          (parameters)
+       {
+       }
+private:
+       const TestParameters    m_parameters;
+
+       vkt::TestInstance*      createInstance          (vkt::Context& context) const
+       {
+               return new MultiViewRenderTestInstance(context, m_parameters);
+       }
+
+       void                            initPrograms            (SourceCollections& programCollection) const
+       {
+               {// Create vertex shader
+                       std::ostringstream source;
+                       source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+                                       << "#extension GL_EXT_multiview : enable\n"
+                                       << "layout(location = 0) in highp vec4 in_position;\n"
+                                       << "layout(location = 1) in vec4 in_color;\n"
+                                       << "layout(location = 0) out vec4 out_color;\n"
+                                       << "void main (void)\n"
+                                       << "{\n"
+                                       << "    gl_Position = in_position;\n";
+                               if (VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex)
+                                       source << "     out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
+                               else
+                                       source << "     out_color = in_color;\n";
+                       source  << "}\n";
+                       programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
+               }
+
+               if (VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)
+               {// Tessellation control & evaluation
+                       std::ostringstream source_tc;
+                       source_tc       << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                                               << "#extension GL_EXT_multiview : enable\n"
+                                               << "#extension GL_EXT_tessellation_shader : require\n"
+                                               << "layout(vertices = 4) out;\n"
+                                               << "layout(location = 0) in vec4 in_color[];\n"
+                                               << "layout(location = 0) out vec4 out_color[];\n"
+                                               << "\n"
+                                               << "void main (void)\n"
+                                               << "{\n"
+                                               << "    if( gl_InvocationID == 0 )\n"
+                                               << "    {\n"
+                                               << "            gl_TessLevelInner[0] = 4.0f;\n"
+                                               << "            gl_TessLevelInner[1] = 4.0f;\n"
+                                               << "            gl_TessLevelOuter[0] = 4.0f;\n"
+                                               << "            gl_TessLevelOuter[1] = 4.0f;\n"
+                                               << "            gl_TessLevelOuter[2] = 4.0f;\n"
+                                               << "            gl_TessLevelOuter[3] = 4.0f;\n"
+                                               << "    }\n"
+                                               << "    out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
+                                               << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                               << "}\n";
+                       programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str());
+
+                       std::ostringstream source_te;
+                       source_te       << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                                               << "#extension GL_EXT_multiview : enable\n"
+                                               << "#extension GL_EXT_tessellation_shader : require\n"
+                                               << "layout( quads, equal_spacing, ccw ) in;\n"
+                                               << "layout(location = 0) in vec4 in_color[];\n"
+                                               << "layout(location = 0) out vec4 out_color;\n"
+                                               << "void main (void)\n"
+                                               << "{\n"
+                                               << "    const float u = gl_TessCoord.x;\n"
+                                               << "    const float v = gl_TessCoord.y;\n"
+                                               << "    const float w = gl_TessCoord.z;\n"
+                                               << "    gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n"
+                                               << "    out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
+                                               << "}\n";
+                       programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str());
+               }
+
+               if (VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex)
+               {// Geometry Shader
+                       std::ostringstream      source;
+                       source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+                                       << "#extension GL_EXT_multiview : enable\n"
+                                       << "layout(triangles) in;\n"
+                                       << "layout(triangle_strip, max_vertices = 16) out;\n"
+                                       << "layout(location = 0) in vec4 in_color[];\n"
+                                       << "layout(location = 0) out vec4 out_color;\n"
+                                       << "void main (void)\n"
+                                       << "{\n"
+                                       << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
+                                       << "    gl_Position = gl_in[0].gl_Position;\n"
+                                       << "    EmitVertex();\n"
+                                       << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
+                                       << "    gl_Position = gl_in[1].gl_Position;\n"
+                                       << "    EmitVertex();\n"
+                                       << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
+                                       << "    gl_Position = gl_in[2].gl_Position;\n"
+                                       << "    EmitVertex();\n"
+                                       << "    out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
+                                       << "    gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
+                                       << "    EmitVertex();\n"
+                                       << "    EndPrimitive();\n"
+                                       << "}\n";
+                       programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str());
+               }
+
+               {// Create fragment shader
+                       std::ostringstream source;
+                       source  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+                                       << "#extension GL_EXT_multiview : enable\n"
+                                       << "layout(location = 0) in vec4 in_color;\n"
+                                       << "layout(location = 0) out vec4 out_color;\n"
+                                       << "void main()\n"
+                                       <<"{\n";
+                               if (VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex)
+                                       source << "     out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
+                               else
+                                       source << "     out_color = in_color;\n";
+                       source  << "}\n";
+                       programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
+               }
+       }
+};
+} //anonymous
+
+void multiViewRenderCreateTests (tcu::TestCaseGroup* group)
+{
+       tcu::TestContext&                       testCtx                                         = group->getTestContext();
+       const deUint32                          testCaseCount                           = 6u;
+       MovePtr<tcu::TestCaseGroup>     groupViewIndex                          (new tcu::TestCaseGroup(testCtx, "index", "ViewIndex rendering tests."));
+       const string                            shaderName[VIEW_INDEX_LAST]     =
+       {
+               "masks",
+               "vertex_shader",
+               "fragment_shader",
+               "geometry_shader",
+               "tesellation_shader"
+       };
+       const VkExtent3D                        extent3D[testCaseCount]         =
+       {
+               {16u,   16u,    4u},
+               {64u,   64u,    8u},
+               {128u,  128u,   4u},
+               {32u,   32u,    5u},
+               {64u,   64u,    6u},
+               {16u,   16u,    10u},
+       };
+       vector<deUint32>                        viewMasks[testCaseCount];
+
+       viewMasks[0].push_back(15u);    //1111
+
+       viewMasks[1].push_back(8u);             //1000
+
+       viewMasks[2].push_back(1u);             //0001
+       viewMasks[2].push_back(2u);             //0010
+       viewMasks[2].push_back(4u);             //0100
+       viewMasks[2].push_back(8u);             //1000
+
+       viewMasks[3].push_back(15u);    //1111
+       viewMasks[3].push_back(15u);    //1111
+       viewMasks[3].push_back(15u);    //1111
+       viewMasks[3].push_back(15u);    //1111
+
+       viewMasks[4].push_back(8u);             //1000
+       viewMasks[4].push_back(1u);             //0001
+       viewMasks[4].push_back(1u);             //0001
+       viewMasks[4].push_back(8u);             //1000
+
+       for(deUint32 mask = 1u; mask < 1024u; mask = mask << 1u)
+               viewMasks[5].push_back(mask);
+
+       for(int shaderTypeNdx = VIEW_INDEX_NOT_USE; shaderTypeNdx < VIEW_INDEX_LAST; ++shaderTypeNdx)
+       {
+               MovePtr<tcu::TestCaseGroup>     groupShader     (new tcu::TestCaseGroup(testCtx, shaderName[shaderTypeNdx].c_str(), ""));
+               for(deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx)
+               {
+                       const TestParameters    parameters              = {extent3D[testCaseNdx], viewMasks[testCaseNdx], (ViewIndex)shaderTypeNdx};
+                       std::ostringstream              masks;
+                       const deUint32                  viewMaksSize    = static_cast<deUint32>(viewMasks[testCaseNdx].size());
+
+                       for(deUint32 ndx = 0u; ndx < viewMaksSize; ++ndx)
+                       {
+                               masks<<viewMasks[testCaseNdx][ndx];
+                               if (viewMaksSize - 1 != ndx)
+                                       masks<<"_";
+                       }
+                       groupShader->addChild(new MultiViewRenderTestsCase(testCtx, masks.str().c_str(), "", parameters));
+               }
+
+               if (VIEW_INDEX_NOT_USE == shaderTypeNdx)
+                       group->addChild(groupShader.release());
+               else
+                       groupViewIndex->addChild(groupShader.release());
+       }
+
+       group->addChild(groupViewIndex.release());
+}
+
+} //MultiView
+} //vkt
+
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.hpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderTests.hpp
new file mode 100644 (file)
index 0000000..3584b97
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _VKTMULTIVIEWRENDERTESTS_HPP
+#define _VKTMULTIVIEWRENDERTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Multi View Render Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace MultiView
+{
+
+void multiViewRenderCreateTests (tcu::TestCaseGroup* group);
+
+} // MultiView
+} // vkt
+
+#endif // _VKTMULTIVIEWRENDERTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.cpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.cpp
new file mode 100644 (file)
index 0000000..d528ebc
--- /dev/null
@@ -0,0 +1,325 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Multi View Render Util
+ *//*--------------------------------------------------------------------*/
+
+#include "vktMultiViewRenderUtil.hpp"
+
+#include "vktTestCase.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkRefUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkPlatform.hpp"
+#include "vkMemUtil.hpp"
+#include "vkImageUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuResource.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuCommandLine.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuRGBA.hpp"
+
+namespace vkt
+{
+namespace MultiView
+{
+using namespace vk;
+using de::MovePtr;
+using de::UniquePtr;
+using std::vector;
+
+VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
+{
+       VkImageAspectFlags      aspectFlag      = 0;
+       aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
+       aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
+
+       if (!aspectFlag)
+               aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
+
+       return aspectFlag;
+}
+
+VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
+{
+       const VkBufferCreateInfo bufferCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
+               DE_NULL,                                                                // const void*                  pNext;
+               (VkBufferCreateFlags)0,                                 // VkBufferCreateFlags  flags;
+               bufferSize,                                                             // VkDeviceSize                 size;
+               usage,                                                                  // VkBufferUsageFlags   usage;
+               VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+               0u,                                                                             // deUint32                             queueFamilyIndexCount;
+               DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
+       };
+       return bufferCreateInfo;
+}
+
+VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
+{
+       const VkImageCreateInfo imageInfo =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
+               DE_NULL,                                                                        // const void*              pNext;
+               (VkImageCreateFlags)0,                                          // VkImageCreateFlags       flags;
+               imageType,                                                                      // VkImageType              imageType;
+               format,                                                                         // VkFormat                 format;
+               {extent.width, extent.height, 1u},                      // VkExtent3D               extent;
+               1u,                                                                                     // uint32_t                 mipLevels;
+               extent.depth,                                                           // uint32_t                 arrayLayers;
+               VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits    samples;
+               VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling            tiling;
+               usage,                                                                          // VkImageUsageFlags        usage;
+               VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
+               0u,                                                                                     // uint32_t                 queueFamilyIndexCount;
+               DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
+               VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
+       };
+       return imageInfo;
+}
+
+Move<VkImageView> makeImageView (const DeviceInterface&                        vk,
+                                                                const VkDevice                                 device,
+                                                                const VkImage                                  image,
+                                                                const VkImageViewType                  viewType,
+                                                                const VkFormat                                 format,
+                                                                const VkImageSubresourceRange  subresourceRange)
+{
+       const VkImageViewCreateInfo imageViewParams =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+               DE_NULL,                                                                                // const void*                          pNext;
+               (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
+               image,                                                                                  // VkImage                                      image;
+               viewType,                                                                               // VkImageViewType                      viewType;
+               format,                                                                                 // VkFormat                                     format;
+               makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
+               subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
+       };
+       return createImageView(vk, device, &imageViewParams);
+}
+
+Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&            vk,
+                                                                        const VkDevice                         device,
+                                                                        const VkRenderPass                     renderPass,
+                                                                        const VkImageView                      colorAttachment,
+                                                                        const deUint32                         width,
+                                                                        const deUint32                         height,
+                                                                        const deUint32                         layers)
+{
+       const VkFramebufferCreateInfo framebufferInfo = {
+               VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                      sType;
+               DE_NULL,                                                                                // const void*                          pNext;
+               (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags     flags;
+               renderPass,                                                                             // VkRenderPass                         renderPass;
+               1u,                                                                                             // uint32_t                                     attachmentCount;
+               &colorAttachment,                                                               // const VkImageView*           pAttachments;
+               width,                                                                                  // uint32_t                                     width;
+               height,                                                                                 // uint32_t                                     height;
+               layers,                                                                                 // uint32_t                                     layers;
+       };
+
+       return createFramebuffer(vk, device, &framebufferInfo);
+}
+
+Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&              vk,
+                                                                                  const VkDevice                               device)
+{
+       const VkPipelineLayoutCreateInfo info =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                              sType;
+               DE_NULL,                                                                                // const void*                                  pNext;
+               (VkPipelineLayoutCreateFlags)0,                                 // VkPipelineLayoutCreateFlags  flags;
+               0u,                                                                                             // deUint32                                             setLayoutCount;
+               DE_NULL,                                                                                // const VkDescriptorSetLayout* pSetLayouts;
+               0u,                                                                                             // deUint32                                             pushConstantRangeCount;
+               DE_NULL,                                                                                // const VkPushConstantRange*   pPushConstantRanges;
+       };
+       return createPipelineLayout(vk, device, &info);
+}
+
+Move<VkRenderPass> makeRenderPass (const DeviceInterface&      vk,
+                                                                  const VkDevice                       device,
+                                                                  const VkFormat                       colorFormat,
+                                                                  const vector<deUint32>&      viewMasks)
+{
+       const deUint32                                                          subpassCount                            = static_cast<deUint32>(viewMasks.size());
+       const VkAttachmentDescription                           colorAttachmentDescription      =
+       {
+               (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags;
+               colorFormat,                                                            // VkFormat                                                     format;
+               VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples;
+               VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
+               VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
+               VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
+               VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
+       };
+
+       const VkAttachmentReference                                     colorAttachmentReference        =
+       {
+               0u,                                                                                     // deUint32                     attachment;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
+       };
+
+       const VkAttachmentReference                                     depthAttachmentReference        =
+       {
+               VK_ATTACHMENT_UNUSED,           // deUint32                     attachment;
+               VK_IMAGE_LAYOUT_UNDEFINED       // VkImageLayout        layout;
+       };
+
+       const VkSubpassDescription                                      subpassDescription                      =
+       {
+               (VkSubpassDescriptionFlags)0,           // VkSubpassDescriptionFlags            flags;
+               VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                          pipelineBindPoint;
+               0u,                                                                     // deUint32                                                     inputAttachmentCount;
+               DE_NULL,                                                        // const VkAttachmentReference*         pInputAttachments;
+               1u,                                                                     // deUint32                                                     colorAttachmentCount;
+               &colorAttachmentReference,                      // const VkAttachmentReference*         pColorAttachments;
+               DE_NULL,                                                        // const VkAttachmentReference*         pResolveAttachments;
+               &depthAttachmentReference,                      // const VkAttachmentReference*         pDepthStencilAttachment;
+               0u,                                                                     // deUint32                                                     preserveAttachmentCount;
+               DE_NULL                                                         // const deUint32*                                      pPreserveAttachments;
+       };
+       vector <VkSubpassDescription>                           subpassDescriptions                     (subpassCount, subpassDescription);
+
+       const VkRenderPassMultiviewCreateInfoKHX        renderPassMultiviewInfo         =
+       {
+               VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX,        //VkStructureType       sType;
+               DE_NULL,                                                                                                        //const void*           pNext;
+               subpassCount,                                                                                           //uint32_t                      subpassCount;
+               &viewMasks[0],                                                                                          //const uint32_t*       pViewMasks;
+               0u,                                                                                                                     //uint32_t                      dependencyCount;
+               DE_NULL,                                                                                                        //const int32_t*        pViewOffsets;
+               0u,                                                                                                                     //uint32_t                      correlationMaskCount;
+               DE_NULL,                                                                                                        //const uint32_t*       pCorrelationMasks;
+       };
+
+       vector <VkSubpassDependency>                            subpassDependencies;
+       for(deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
+       {
+               const VkSubpassDependency subpassDependency =
+               {
+                       subpassNdx,                                                                                                             // deUint32                             srcSubpass;
+                       (subpassNdx ==subpassCount - 1u) ? subpassNdx : subpassNdx+1u,  // deUint32                             dstSubpass;
+                       VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,                                  // VkPipelineStageFlags srcStageMask;
+                       VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                                                  // VkPipelineStageFlags dstStageMask;
+                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                                   // VkAccessFlags                srcAccessMask;
+                       VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                                                    // VkAccessFlags                dstAccessMask;
+                       VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX,                                                               // VkDependencyFlags    dependencyFlags;
+               };
+               subpassDependencies.push_back(subpassDependency);
+       }
+
+       const VkRenderPassCreateInfo                            renderPassInfo          =
+       {
+               VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureType                                      sType;
+               &renderPassMultiviewInfo,                                       // const void*                                          pNext;
+               (VkRenderPassCreateFlags)0,                                     // VkRenderPassCreateFlags                      flags;
+               1u,                                                                                     // deUint32                                                     attachmentCount;
+               &colorAttachmentDescription,                            // const VkAttachmentDescription*       pAttachments;
+               subpassCount,                                                           // deUint32                                                     subpassCount;
+               &subpassDescriptions[0],                                        // const VkSubpassDescription*          pSubpasses;
+               subpassCount,                                                           // deUint32                                                     dependencyCount;
+               &subpassDependencies[0]                                         // const VkSubpassDependency*           pDependencies;
+       };
+
+       return createRenderPass(vk, device, &renderPassInfo);
+}
+
+void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
+{
+       const VkCommandBufferBeginInfo info =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,            // VkStructureType                                                      sType;
+               DE_NULL,                                                                                        // const void*                                                          pNext;
+               VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,            // VkCommandBufferUsageFlags                            flags;
+               DE_NULL,                                                                                        // const VkCommandBufferInheritanceInfo*        pInheritanceInfo;
+       };
+       VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
+}
+
+void imageBarrier (const DeviceInterface&                      vk,
+                                  const VkCommandBuffer                        cmdBuffer,
+                                  const VkImage                                        image,
+                                  const VkImageSubresourceRange        subresourceRange,
+                                  const VkImageLayout                          oldLayout,
+                                  const VkImageLayout                          newLayout,
+                                  const VkAccessFlags                          srcAccessMask,
+                                  const VkAccessFlags                          dstAccessMask,
+                                  const VkPipelineStageFlags           srcStageMask,
+                                  const VkPipelineStageFlags           dstStageMask)
+{
+       const VkImageMemoryBarrier              barrier                         =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
+               DE_NULL,                                                                // const void*                          pNext;
+               srcAccessMask,                                                  // VkAccessFlags                        srcAccessMask;
+               dstAccessMask,                                                  // VkAccessFlags                        dstAccessMask;
+               oldLayout,                                                              // VkImageLayout                        oldLayout;
+               newLayout,                                                              // VkImageLayout                        newLayout;
+               VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
+               image,                                                                  // VkImage                                      image;
+               subresourceRange,                                               // VkImageSubresourceRange      subresourceRange;
+       };
+
+       vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL,
+               0u, (const VkBufferMemoryBarrier*)DE_NULL,
+               1u, &barrier);
+}
+
+void submitCommandsAndWait (const DeviceInterface&     vk,
+                                                       const VkDevice                  device,
+                                                       const VkQueue                   queue,
+                                                       const VkCommandBuffer   commandBuffer)
+{
+       const VkFenceCreateInfo fenceInfo       =
+       {
+               VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
+               DE_NULL,                                                                // const void*                  pNext;
+               (VkFenceCreateFlags)0,                                  // VkFenceCreateFlags   flags;
+       };
+       const Unique<VkFence>   fence           (createFence(vk, device, &fenceInfo));
+
+       const VkSubmitInfo              submitInfo      =
+       {
+               VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                              sType;
+               DE_NULL,                                                // const void*                                  pNext;
+               0u,                                                             // uint32_t                                             waitSemaphoreCount;
+               DE_NULL,                                                // const VkSemaphore*                   pWaitSemaphores;
+               DE_NULL,                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
+               1u,                                                             // uint32_t                                             commandBufferCount;
+               &commandBuffer,                                 // const VkCommandBuffer*               pCommandBuffers;
+               0u,                                                             // uint32_t                                             signalSemaphoreCount;
+               DE_NULL,                                                // const VkSemaphore*                   pSignalSemaphores;
+       };
+       VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
+       VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
+}
+
+} // MultiView
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.hpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewRenderUtil.hpp
new file mode 100644 (file)
index 0000000..080eaf3
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _VKTMULTIVIEWRENDERUTIL_HPP
+#define _VKTMULTIVIEWRENDERUTIL_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Multi View Render Util
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "vkRefUtil.hpp"
+#include "tcuTexture.hpp"
+
+namespace vkt
+{
+namespace MultiView
+{
+
+vk::VkImageAspectFlags                 getAspectFlags                  (tcu::TextureFormat format);
+vk::VkBufferCreateInfo                 makeBufferCreateInfo    (const vk::VkDeviceSize bufferSize, const vk::VkBufferUsageFlags usage);
+vk::VkImageCreateInfo                  makeImageCreateInfo             (const vk::VkImageType imageType, const vk::VkExtent3D& extent, const vk::VkFormat format, const vk::VkImageUsageFlags usage);
+vk::Move<vk::VkImageView>              makeImageView                   (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkImage image, const vk::VkImageViewType viewType, const vk::VkFormat format, const vk::VkImageSubresourceRange subresourceRange);
+vk::Move<vk::VkFramebuffer>            makeFramebuffer                 (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkRenderPass renderPass, const vk::VkImageView colorAttachment, const deUint32 width, const deUint32 height, const deUint32 layers);
+vk::Move<vk::VkPipelineLayout> makePipelineLayout              (const vk::DeviceInterface& vk, const vk::VkDevice device);
+vk::Move<vk::VkRenderPass>             makeRenderPass                  (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkFormat colorFormat, const std::vector<deUint32>& viewMasks);
+void                                                   beginCommandBuffer              (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer);
+void                                                   imageBarrier                    (const vk::DeviceInterface& vk, const vk::VkCommandBuffer cmdBuffer, const vk::VkImage image, const vk::VkImageSubresourceRange subresourceRange, const vk::VkImageLayout oldLayout, const vk::VkImageLayout newLayout, const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask, const vk::VkPipelineStageFlags srcStageMask = vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, const vk::VkPipelineStageFlags dstStageMas = vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
+void                                                   submitCommandsAndWait   (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkQueue queue, const vk::VkCommandBuffer commandBuffer);
+
+} // MultiView
+} // vkt
+
+#endif // _VKTMULTIVIEWRENDERUTIL_HPP
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.cpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.cpp
new file mode 100644 (file)
index 0000000..e819fe8
--- /dev/null
@@ -0,0 +1,40 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief  Vulkan Multi View Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktMultiViewTests.hpp"
+#include "vktMultiViewRenderTests.hpp"
+
+#include "vktTestGroupUtil.hpp"
+
+namespace vkt
+{
+namespace MultiView
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
+{
+       return createTestGroup(testCtx, "multiview", "MultiView render tests", multiViewRenderCreateTests);
+}
+
+} // MultiView
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.hpp b/external/vulkancts/modules/vulkan/multiview/vktMultiViewTests.hpp
new file mode 100644 (file)
index 0000000..a6f9b91
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _VKTMULTIVIEWTESTS_HPP
+#define _VKTMULTIVIEWTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Multi View Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace MultiView
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx);
+
+} // MultiView
+} // vkt
+
+#endif // _VKTMULTIVIEWTESTS_HPP
index a55cc06..faa1ada 100644 (file)
@@ -77,6 +77,7 @@
 #include "vktTextureTests.hpp"
 #include "vktGeometryTests.hpp"
 #include "vktRobustnessTests.hpp"
+#include "vktMultiViewTests.hpp"
 
 #include <vector>
 #include <sstream>
@@ -400,6 +401,7 @@ void TestPackage::init (void)
        addChild(texture::createTests                   (m_testCtx));
        addChild(geometry::createTests                  (m_testCtx));
        addChild(robustness::createTests                (m_testCtx));
+       addChild(MultiView::createTests                 (m_testCtx));
 }
 
 } // vkt
index 9f28385..ef8ba7f 100644 (file)
@@ -202348,3 +202348,33 @@ dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw.instance_out_of_b
 dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw_indexed.last_index_out_of_bounds
 dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw_indexed.indices_out_of_bounds
 dEQP-VK.robustness.vertex_access.a2b10g10r10_unorm_pack32.draw_indexed.triangle_out_of_bounds
+dEQP-VK.multiview.masks.15
+dEQP-VK.multiview.masks.8
+dEQP-VK.multiview.masks.1_2_4_8
+dEQP-VK.multiview.masks.15_15_15_15
+dEQP-VK.multiview.masks.8_1_1_8
+dEQP-VK.multiview.masks.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.vertex_shader.15
+dEQP-VK.multiview.index.vertex_shader.8
+dEQP-VK.multiview.index.vertex_shader.1_2_4_8
+dEQP-VK.multiview.index.vertex_shader.15_15_15_15
+dEQP-VK.multiview.index.vertex_shader.8_1_1_8
+dEQP-VK.multiview.index.vertex_shader.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.fragment_shader.15
+dEQP-VK.multiview.index.fragment_shader.8
+dEQP-VK.multiview.index.fragment_shader.1_2_4_8
+dEQP-VK.multiview.index.fragment_shader.15_15_15_15
+dEQP-VK.multiview.index.fragment_shader.8_1_1_8
+dEQP-VK.multiview.index.fragment_shader.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.geometry_shader.15
+dEQP-VK.multiview.index.geometry_shader.8
+dEQP-VK.multiview.index.geometry_shader.1_2_4_8
+dEQP-VK.multiview.index.geometry_shader.15_15_15_15
+dEQP-VK.multiview.index.geometry_shader.8_1_1_8
+dEQP-VK.multiview.index.geometry_shader.1_2_4_8_16_32_64_128_256_512
+dEQP-VK.multiview.index.tesellation_shader.15
+dEQP-VK.multiview.index.tesellation_shader.8
+dEQP-VK.multiview.index.tesellation_shader.1_2_4_8
+dEQP-VK.multiview.index.tesellation_shader.15_15_15_15
+dEQP-VK.multiview.index.tesellation_shader.8_1_1_8
+dEQP-VK.multiview.index.tesellation_shader.1_2_4_8_16_32_64_128_256_512
index 8df8389..f1f5872 100644 (file)
@@ -221,6 +221,9 @@ typedef enum VkStructureType {
     VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
     VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
     VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
+    VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX = 1000053000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX = 1000053001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHX = 1000053002,
     VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
     VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
@@ -1053,6 +1056,7 @@ typedef enum VkPipelineCreateFlagBits {
     VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001,
     VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002,
     VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004,
+    VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHX = 0x00000008,
     VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkPipelineCreateFlagBits;
 typedef VkFlags VkPipelineCreateFlags;
@@ -1146,6 +1150,7 @@ typedef VkFlags VkAccessFlags;
 
 typedef enum VkDependencyFlagBits {
     VK_DEPENDENCY_BY_REGION_BIT = 0x00000001,
+    VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX = 0x00000002,
     VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkDependencyFlagBits;
 typedef VkFlags VkDependencyFlags;
@@ -4222,6 +4227,38 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD(
 #define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot"
 
 
+#define VK_KHX_multiview 1
+#define VK_KHX_MULTIVIEW_SPEC_VERSION     1
+#define VK_KHX_MULTIVIEW_EXTENSION_NAME   "VK_KHX_multiview"
+
+typedef struct VkRenderPassMultiviewCreateInfoKHX {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint32_t           subpassCount;
+    const uint32_t*    pViewMasks;
+    uint32_t           dependencyCount;
+    const int32_t*     pViewOffsets;
+    uint32_t           correlationMaskCount;
+    const uint32_t*    pCorrelationMasks;
+} VkRenderPassMultiviewCreateInfoKHX;
+
+typedef struct VkPhysicalDeviceMultiviewFeaturesKHX {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           multiview;
+    VkBool32           multiviewGeometryShader;
+    VkBool32           multiviewTessellationShader;
+} VkPhysicalDeviceMultiviewFeaturesKHX;
+
+typedef struct VkPhysicalDeviceMultiviewPropertiesKHX {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           maxMultiviewViewCount;
+    uint32_t           maxMultiviewInstanceIndex;
+} VkPhysicalDeviceMultiviewPropertiesKHX;
+
+
+
 #define VK_IMG_format_pvrtc 1
 #define VK_IMG_FORMAT_PVRTC_SPEC_VERSION  1
 #define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"