1d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa/*------------------------------------------------------------------------
2d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * Vulkan Conformance Tests
3d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * ------------------------
4d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *
5d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * Copyright (c) 2016 The Khronos Group Inc.
6d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * Copyright (c) 2014 The Android Open Source Project
7d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *
8d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * Licensed under the Apache License, Version 2.0 (the "License");
9d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * you may not use this file except in compliance with the License.
10d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * You may obtain a copy of the License at
11d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *
12d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *      http://www.apache.org/licenses/LICENSE-2.0
13d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *
14d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * Unless required by applicable law or agreed to in writing, software
15d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * distributed under the License is distributed on an "AS IS" BASIS,
16d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * See the License for the specific language governing permissions and
18d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * limitations under the License.
19d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *
20d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *//*!
21d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * \file
22d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa * \brief Geometry shader layered rendering tests
23d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa *//*--------------------------------------------------------------------*/
24d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
25d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vktGeometryLayeredRenderingTests.hpp"
26d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vktTestCase.hpp"
27d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vktTestCaseUtil.hpp"
28d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vktGeometryTestsUtil.hpp"
29d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
30d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vkPrograms.hpp"
31d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vkStrUtil.hpp"
32d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vkQueryUtil.hpp"
33d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vkMemUtil.hpp"
34d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vkRefUtil.hpp"
35d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vkTypeUtil.hpp"
36d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "vkImageUtil.hpp"
37d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
38d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "deStringUtil.hpp"
39d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "deUniquePtr.hpp"
40d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
41d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "tcuTextureUtil.hpp"
42d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa#include "tcuVectorUtil.hpp"
43fa7a45c9bcb909be38ffd55549beb6db5115a65bPyry Haulos#include "tcuTestLog.hpp"
44d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
45d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwanamespace vkt
46d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
47d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwanamespace geometry
48d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
49d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwanamespace
50d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
51d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwausing namespace vk;
52d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwausing de::MovePtr;
53d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwausing de::UniquePtr;
54d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwausing tcu::Vec4;
55d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwausing tcu::IVec3;
56d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
57d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwaenum TestType
58d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
59d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TEST_TYPE_DEFAULT_LAYER,					// !< draw to default layer
60d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TEST_TYPE_SINGLE_LAYER,						// !< draw to single layer
61d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TEST_TYPE_ALL_LAYERS,						// !< draw all layers
62d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TEST_TYPE_DIFFERENT_CONTENT,				// !< draw different content to different layers
63d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TEST_TYPE_LAYER_ID,							// !< draw to all layers, verify gl_Layer fragment input
64d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TEST_TYPE_INVOCATION_PER_LAYER,				// !< draw to all layers, one invocation per layer
65d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION,	// !< draw to all layers, multiple invocations write to multiple layers
66d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa};
67d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
68d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwastruct ImageParams
69d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
70d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	VkImageViewType		viewType;
71d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	VkExtent3D			size;
72d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	deUint32			numLayers;
73d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa};
74d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
75d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwastruct TestParams
76d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
77d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	TestType			testType;
78d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	ImageParams			image;
79d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa};
80d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
81d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwastatic const float s_colors[][4] =
82d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
83d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{ 1.0f, 1.0f, 1.0f, 1.0f },		// white
84d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{ 1.0f, 0.0f, 0.0f, 1.0f },		// red
85d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{ 0.0f, 1.0f, 0.0f, 1.0f },		// green
86d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{ 0.0f, 0.0f, 1.0f, 1.0f },		// blue
87d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{ 1.0f, 1.0f, 0.0f, 1.0f },		// yellow
88d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{ 1.0f, 0.0f, 1.0f, 1.0f },		// magenta
89d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa};
90d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
91d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz SarwadeUint32 getTargetLayer (const ImageParams& imageParams)
92d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
93d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	if (imageParams.viewType == VK_IMAGE_VIEW_TYPE_3D)
94d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return imageParams.size.depth / 2;
95d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	else
96d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return imageParams.numLayers / 2;
97d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
98d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
99d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwastd::string getShortImageViewTypeName (const VkImageViewType imageViewType)
100d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
101d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	std::string s(getImageViewTypeName(imageViewType));
102d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return de::toLower(s.substr(19));
103d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
104d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
105d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz SarwaVkImageType getImageType (const VkImageViewType viewType)
106d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
107d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	switch (viewType)
108d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
109d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case VK_IMAGE_VIEW_TYPE_1D:
110d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
111d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return VK_IMAGE_TYPE_1D;
112d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
113d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case VK_IMAGE_VIEW_TYPE_2D:
114d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
115d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case VK_IMAGE_VIEW_TYPE_CUBE:
116d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
117d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return VK_IMAGE_TYPE_2D;
118d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
119d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case VK_IMAGE_VIEW_TYPE_3D:
120d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return VK_IMAGE_TYPE_3D;
121d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
122d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		default:
123d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_ASSERT(0);
124d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return VK_IMAGE_TYPE_LAST;
125d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
126d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
127d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
128d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwainline bool isCubeImageViewType (const VkImageViewType viewType)
129d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
130d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
131d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
132d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
133d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz SarwaVkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const VkImageUsageFlags usage)
134d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
135d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkImageCreateInfo imageParams =
136d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
137d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
138d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,										// const void*				pNext;
139d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		flags,											// VkImageCreateFlags		flags;
140d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		type,											// VkImageType				imageType;
141d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		format,											// VkFormat					format;
142d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		size,											// VkExtent3D				extent;
143d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,												// deUint32					mipLevels;
144d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		numLayers,										// deUint32					arrayLayers;
145d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
146d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
147d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		usage,											// VkImageUsageFlags		usage;
148d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
149d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,												// deUint32					queueFamilyIndexCount;
150d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
151d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
152d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
153d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return imageParams;
154d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
155d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
156d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz SarwaMove<VkRenderPass> makeRenderPass (const DeviceInterface&	vk,
157d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa								   const VkDevice			device,
158d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa								   const VkFormat			colorFormat)
159d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
160d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkAttachmentDescription colorAttachmentDescription =
161d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
162d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
163d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		colorFormat,										// VkFormat							format;
164d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
165d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
166d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
167d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
168d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
169d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
170d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
171d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
172d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
173d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkAttachmentReference colorAttachmentRef =
174d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
175d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,													// deUint32			attachment;
176d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
177d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
178d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
179d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkSubpassDescription subpassDescription =
180d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
181d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
182d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
183d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,													// deUint32							inputAttachmentCount;
184d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
185d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,													// deUint32							colorAttachmentCount;
186d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&colorAttachmentRef,								// const VkAttachmentReference*		pColorAttachments;
187d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
188d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
189d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,													// deUint32							preserveAttachmentCount;
190d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL												// const deUint32*					pPreserveAttachments;
191d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
192d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
193d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkRenderPassCreateInfo renderPassInfo =
194d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
195d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
196d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// const void*						pNext;
197d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
198d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,													// deUint32							attachmentCount;
199d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
200d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,													// deUint32							subpassCount;
201d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
202d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,													// deUint32							dependencyCount;
203d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL												// const VkSubpassDependency*		pDependencies;
204d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
205d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
206d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return createRenderPass(vk, device, &renderPassInfo);
207d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
208d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
209d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz SarwaMove<VkPipeline> makeGraphicsPipeline (const DeviceInterface&		vk,
210d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   const VkDevice				device,
211d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   const VkPipelineLayout		pipelineLayout,
212d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   const VkRenderPass			renderPass,
213d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   const VkShaderModule			vertexModule,
214d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   const VkShaderModule			geometryModule,
215d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   const VkShaderModule			fragmentModule,
216d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   const VkExtent2D				renderSize)
217d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
218d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
219d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
220d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
221d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const void*                                 pNext;
222d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
223d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,																// uint32_t                                    vertexBindingDescriptionCount;
224d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
225d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,																// uint32_t                                    vertexAttributeDescriptionCount;
226d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
227d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
228d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
229d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
230d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
231d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
232d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const void*                                 pNext;
233d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
234d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_PRIMITIVE_TOPOLOGY_POINT_LIST,								// VkPrimitiveTopology                         topology;
235d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
236d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
237d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
238d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkViewport viewport = makeViewport(
239d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0.0f, 0.0f,
240d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		static_cast<float>(renderSize.width), static_cast<float>(renderSize.height),
241d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0.0f, 1.0f);
242d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkRect2D scissor =
243d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
244d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		makeOffset2D(0, 0),
245d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		makeExtent2D(renderSize.width, renderSize.height),
246d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
247d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
248d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
249d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
250d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType                             sType;
251d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const void*                                 pNext;
252d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags          flags;
253d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,																// uint32_t                                    viewportCount;
254d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&viewport,														// const VkViewport*                           pViewports;
255d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,																// uint32_t                                    scissorCount;
256d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&scissor,														// const VkRect2D*                             pScissors;
257d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
258d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
259d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
260d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
261d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
262d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const void*                              pNext;
263d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
264d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32                                 depthClampEnable;
265d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
266d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
267d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
268d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
269d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32									depthBiasEnable;
270d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0.0f,															// float									depthBiasConstantFactor;
271d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0.0f,															// float									depthBiasClamp;
272d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0.0f,															// float									depthBiasSlopeFactor;
273d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1.0f,															// float									lineWidth;
274d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
275d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
276d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
277d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
278d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
279d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const void*								pNext;
280d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineMultisampleStateCreateFlags)0,						// VkPipelineMultisampleStateCreateFlags	flags;
281d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
282d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32									sampleShadingEnable;
283d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0.0f,															// float									minSampleShading;
284d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const VkSampleMask*						pSampleMask;
285d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32									alphaToCoverageEnable;
286d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE														// VkBool32									alphaToOneEnable;
287d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
288d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
289d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkStencilOpState stencilOpState = makeStencilOpState(
290d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STENCIL_OP_KEEP,				// stencil fail
291d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STENCIL_OP_KEEP,				// depth & stencil pass
292d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STENCIL_OP_KEEP,				// depth only fail
293d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_COMPARE_OP_ALWAYS,			// compare op
294d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,								// compare mask
295d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,								// write mask
296d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u);							// reference
297d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
298d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
299d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
300d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType;
301d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const void*								pNext;
302d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags	flags;
303d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32									depthTestEnable;
304d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32									depthWriteEnable;
305d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_COMPARE_OP_LESS,												// VkCompareOp								depthCompareOp;
306d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32									depthBoundsTestEnable;
307d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32									stencilTestEnable;
308d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		stencilOpState,													// VkStencilOpState							front;
309d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		stencilOpState,													// VkStencilOpState							back;
310d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0.0f,															// float									minDepthBounds;
311d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1.0f,															// float									maxDepthBounds;
312d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
313d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
314d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkColorComponentFlags					colorComponentsAll					= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
315d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineColorBlendAttachmentState	pipelineColorBlendAttachmentState	=
316d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
317d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,						// VkBool32					blendEnable;
318d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcColorBlendFactor;
319d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
320d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
321d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcAlphaBlendFactor;
322d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
323d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
324d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		colorComponentsAll,				// VkColorComponentFlags	colorWriteMask;
325d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
326d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
327d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
328d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
329d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
330d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,														// const void*									pNext;
331d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags			flags;
332d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_FALSE,														// VkBool32										logicOpEnable;
333d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
334d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,																// deUint32										attachmentCount;
335d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&pipelineColorBlendAttachmentState,								// const VkPipelineColorBlendAttachmentState*	pAttachments;
336d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ 0.0f, 0.0f, 0.0f, 0.0f },										// float										blendConstants[4];
337d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
338d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
339d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkPipelineShaderStageCreateInfo pShaderStages[] =
340d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
341d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
342d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
343d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_NULL,													// const void*							pNext;
344d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
345d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
346d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			vertexModule,												// VkShaderModule						module;
347d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			"main",														// const char*							pName;
348d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
349d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		},
350d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
351d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
352d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_NULL,													// const void*							pNext;
353d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
354d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			VK_SHADER_STAGE_GEOMETRY_BIT,								// VkShaderStageFlagBits				stage;
355d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			geometryModule,												// VkShaderModule						module;
356d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			"main",														// const char*							pName;
357d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
358d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		},
359d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
360d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
361d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_NULL,													// const void*							pNext;
362d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
363d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
364d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			fragmentModule,												// VkShaderModule						module;
365d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			"main",														// const char*							pName;
366d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
367d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		},
368d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
369d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
370d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
371d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
372d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
373d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// const void*										pNext;
374d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
375d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_LENGTH_OF_ARRAY(pShaderStages),					// deUint32											stageCount;
376d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
377d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
378d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
379d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
380d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
381d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
382d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
383d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
384d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
385d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
386d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		pipelineLayout,										// VkPipelineLayout									layout;
387d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		renderPass,											// VkRenderPass										renderPass;
388d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0u,													// deUint32											subpass;
389d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,											// VkPipeline										basePipelineHandle;
390d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		0,													// deInt32											basePipelineIndex;
391d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
392d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
393d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
394d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
395d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
396d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa//! Convenience wrapper to access 1D, 2D, and 3D image layers/slices in a uniform way.
397d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwaclass LayeredImageAccess
398d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
399d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwapublic:
400d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	static LayeredImageAccess create (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
401d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
402d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (type == VK_IMAGE_TYPE_1D)
403d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return LayeredImageAccess(format, size.width, numLayers, pData);
404d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else
405d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return LayeredImageAccess(type, format, size, numLayers, pData);
406d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
407d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
408d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	inline tcu::ConstPixelBufferAccess getLayer (const int layer) const
409d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
410d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return tcu::getSubregion(m_wholeImage, 0, (m_1dModifier * layer), ((~m_1dModifier & 1) * layer), m_width, m_height, 1);
411d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
412d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
413d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	inline int getNumLayersOrSlices (void) const
414d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
415d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return m_layers;
416d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
417d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
418d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwaprivate:
419d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	// Specialized for 1D images.
420d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	LayeredImageAccess (const VkFormat format, const deUint32 width, const deUint32 numLayers, const void* pData)
421d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		: m_width		(static_cast<int>(width))
422d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_height		(1)
423d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_1dModifier	(1)
424d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_layers		(numLayers)
425d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_wholeImage	(tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_layers, 1, pData))
426d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
427d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
428d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
429d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	LayeredImageAccess (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
430d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		: m_width		(static_cast<int>(size.width))
431d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_height		(static_cast<int>(size.height))
432d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_1dModifier	(0)
433d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_layers		(static_cast<int>(type == VK_IMAGE_TYPE_3D ? size.depth : numLayers))
434d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		, m_wholeImage	(tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_height, m_layers, pData))
435d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
436d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
437d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
438d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int							m_width;
439d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int							m_height;
440d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int							m_1dModifier;
441d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int							m_layers;
442d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const tcu::ConstPixelBufferAccess	m_wholeImage;
443d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa};
444d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
445d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwainline bool compareColors (const Vec4& colorA, const Vec4& colorB, const Vec4& threshold)
446d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
447d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return tcu::allEqual(
448d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				tcu::lessThan(tcu::abs(colorA - colorB), threshold),
449d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				tcu::BVec4(true, true, true, true));
450d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
451d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
452d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwabool verifyImageSingleColoredRow (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image, const float rowWidthRatio, const tcu::Vec4& barColor)
453d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
454d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	DE_ASSERT(rowWidthRatio > 0.0f);
455d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
456d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4				black				(0.0f, 0.0f, 0.0f, 1.0f);
457d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4				green				(0.0f, 1.0f, 0.0f, 1.0f);
458d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4				red					(1.0f, 0.0f, 0.0f, 1.0f);
459d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4				threshold			(0.02f);
460d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int				barLength			= static_cast<int>(rowWidthRatio * static_cast<float>(image.getWidth()));
461d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int				barLengthThreshold	= 1;
462d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	tcu::TextureLevel		errorMask			(image.getFormat(), image.getWidth(), image.getHeight());
463d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	tcu::PixelBufferAccess	errorMaskAccess		= errorMask.getAccess();
464d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
465d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	tcu::clear(errorMask.getAccess(), green);
466d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
467d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	log << tcu::TestLog::Message
468d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		<< "Expecting all pixels with distance less or equal to (about) " << barLength
469d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		<< " pixels from left border to be of color " << barColor.swizzle(0, 1, 2) << "."
470d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		<< tcu::TestLog::EndMessage;
471d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
472d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	bool allPixelsOk = true;
473d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
474d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	for (int y = 0; y < image.getHeight(); ++y)
475d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	for (int x = 0; x < image.getWidth();  ++x)
476d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
477d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const Vec4	color		= image.getPixel(x, y);
478d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const bool	isBlack		= compareColors(color, black, threshold);
479d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const bool	isColor		= compareColors(color, barColor, threshold);
480d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
481d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		bool isOk;
482d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
483d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (x <= barLength - barLengthThreshold)
484d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			isOk = isColor;
485d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (x >= barLength + barLengthThreshold)
486d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			isOk = isBlack;
487d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else
488d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			isOk = isColor || isBlack;
489d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
490d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		allPixelsOk &= isOk;
491d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
492d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (!isOk)
493d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			errorMaskAccess.setPixel(red, x, y);
494d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
495d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
496d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	if (allPixelsOk)
497d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
498d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage
499d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< tcu::TestLog::ImageSet("LayerContent", "Layer content")
500d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< tcu::TestLog::Image("Layer", "Layer", image)
501d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< tcu::TestLog::EndImageSet;
502d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return true;
503d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
504d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	else
505d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
506d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage
507d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< tcu::TestLog::ImageSet("LayerContent", "Layer content")
508d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< tcu::TestLog::Image("Layer",		"Layer",	image)
509d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< tcu::TestLog::Image("ErrorMask",	"Errors",	errorMask)
510d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< tcu::TestLog::EndImageSet;
511d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return false;
512d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
513d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
514d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	log << tcu::TestLog::Image("LayerContent", "Layer content", image);
515d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
516d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return allPixelsOk;
517d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
518d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
519d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwabool verifyEmptyImage (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image)
520d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
521d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	log << tcu::TestLog::Message << "Expecting empty image" << tcu::TestLog::EndMessage;
522d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
523d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4	black		(0.0f, 0.0f, 0.0f, 1.0f);
524d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4	threshold	(0.02f);
525d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
526d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	for (int y = 0; y < image.getHeight(); ++y)
527d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	for (int x = 0; x < image.getWidth();  ++x)
528d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
529d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const Vec4 color = image.getPixel(x, y);
530d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
531d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (!compareColors(color, black, threshold))
532d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
533d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			log	<< tcu::TestLog::Message
534d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "Found (at least) one bad pixel at " << x << "," << y << ". Pixel color is not background color."
535d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< tcu::TestLog::EndMessage
536d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< tcu::TestLog::ImageSet("LayerContent", "Layer content")
537d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< tcu::TestLog::Image("Layer", "Layer", image)
538d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< tcu::TestLog::EndImageSet;
539d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return false;
540d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
541d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
542d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
543d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	log << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
544d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
545d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return true;
546d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
547d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
548d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwabool verifyLayerContent (tcu::TestLog& log, const TestType testType, const tcu::ConstPixelBufferAccess image, const int layerNdx, const int numLayers)
549d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
550d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4	white				(1.0f, 1.0f, 1.0f, 1.0f);
551d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int	targetLayer			= numLayers / 2;
552d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const float	variableBarRatio	= static_cast<float>(layerNdx) / static_cast<float>(numLayers);
553d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
554d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	switch (testType)
555d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
556d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case TEST_TYPE_DEFAULT_LAYER:
557d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			if (layerNdx == 0)
558d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				return verifyImageSingleColoredRow(log, image, 0.5f, white);
559d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			else
560d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				return verifyEmptyImage(log, image);
561d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
562d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case TEST_TYPE_SINGLE_LAYER:
563d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			if (layerNdx == targetLayer)
564d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				return verifyImageSingleColoredRow(log, image, 0.5f, white);
565d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			else
566d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				return verifyEmptyImage(log, image);
567d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
568d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case TEST_TYPE_ALL_LAYERS:
569d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case TEST_TYPE_INVOCATION_PER_LAYER:
570d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return verifyImageSingleColoredRow(log, image, 0.5f, s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]);
571d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
572d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case TEST_TYPE_DIFFERENT_CONTENT:
573d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION:
574d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			if (layerNdx == 0)
575d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				return verifyEmptyImage(log, image);
576d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			else
577d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				return verifyImageSingleColoredRow(log, image, variableBarRatio, white);
578d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
579d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		case TEST_TYPE_LAYER_ID:
580d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
581d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			// This code must be in sync with the fragment shader.
582d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			const tcu::Vec4 layerColor( (layerNdx    % 2) == 1 ? 1.0f : 0.5f,
583d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									   ((layerNdx/2) % 2) == 1 ? 1.0f : 0.5f,
584d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa									     layerNdx         == 0 ? 1.0f : 0.0f,
585d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa																 1.0f);
586d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return verifyImageSingleColoredRow(log, image, 0.5f, layerColor);
587d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
588d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
589d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		default:
590d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_ASSERT(0);
591d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			return false;
592d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
593d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
594d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
595d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwastd::string getLayerDescription (const VkImageViewType viewType, const int layer)
596d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
597d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	std::ostringstream str;
598d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const int numCubeFaces = 6;
599d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
600d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	if (isCubeImageViewType(viewType))
601d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		str << "cube " << (layer / numCubeFaces) << ", face " << (layer % numCubeFaces);
602d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	else if (viewType == VK_IMAGE_VIEW_TYPE_3D)
603d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		str << "slice z = " << layer;
604d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	else
605d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		str << "layer " << layer;
606d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
607d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return str.str();
608d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
609d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
610d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwabool verifyResults (tcu::TestLog& log, const TestParams& params, const VkFormat colorFormat, const void* resultData)
611d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
612d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const LayeredImageAccess image = LayeredImageAccess::create(getImageType(params.image.viewType), colorFormat, params.image.size, params.image.numLayers, resultData);
613d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
614d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	int numGoodLayers = 0;
615d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
616d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	for (int layerNdx = 0; layerNdx < image.getNumLayersOrSlices(); ++layerNdx)
617d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
618d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const tcu::ConstPixelBufferAccess layerImage = image.getLayer(layerNdx);
619d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
620d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		log << tcu::TestLog::Message << "Verifying " << getLayerDescription(params.image.viewType, layerNdx) << tcu::TestLog::EndMessage;
621d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
622d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (verifyLayerContent(log, params.testType, layerImage, layerNdx, image.getNumLayersOrSlices()))
623d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			++numGoodLayers;
624d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
625d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
626d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return numGoodLayers == image.getNumLayersOrSlices();
627d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
628d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
629d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwastd::string toGlsl (const Vec4& v)
630d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
631d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	std::ostringstream str;
632d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	str << "vec4(";
633d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	for (int i = 0; i < 4; ++i)
634d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		str << (i != 0 ? ", " : "") << de::floatToString(v[i], 1);
635d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	str << ")";
636d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return str.str();
637d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
638d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
639d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwavoid initPrograms (SourceCollections& programCollection, const TestParams params)
640d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
641d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const bool geomOutputColor = (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_INVOCATION_PER_LAYER);
642d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
643d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	// Vertex shader
644d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
645d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		std::ostringstream src;
646d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
647d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "\n"
648d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "void main(void)\n"
649d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "{\n"
650d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "}\n";
651d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
652d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
653d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
654d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
655d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	// Geometry shader
656d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
657b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		const int numLayers		= static_cast<int>(params.image.viewType == VK_IMAGE_VIEW_TYPE_3D ? params.image.size.depth : params.image.numLayers);
658b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa
659b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		const int maxVertices	= (params.testType == TEST_TYPE_DIFFERENT_CONTENT)										? (numLayers + 1) * numLayers :
660b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa								  (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_LAYER_ID)	? numLayers * 4 :
661b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa								  (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)							? 6 : 4;
662d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
663d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		std::ostringstream src;
664d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
665d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "\n";
666d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
667d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
668b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa			src << "layout(points, invocations = " << numLayers << ") in;\n";
669d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else
670d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << "layout(points) in;\n";
671d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
672d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		src << "layout(triangle_strip, max_vertices = " << maxVertices << ") out;\n"
673d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "\n"
674d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< (geomOutputColor ? "layout(location = 0) out vec4 vert_color;\n\n" : "")
675d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "out gl_PerVertex {\n"
676d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "    vec4 gl_Position;\n"
677d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "};\n"
678d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "\n"
679d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "void main(void)\n"
680d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "{\n";
681d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
682d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		std::ostringstream colorTable;
683d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
684d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			const int numColors = DE_LENGTH_OF_ARRAY(s_colors);
685d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
686d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			colorTable << "    const vec4 colors[" << numColors << "] = vec4[" << numColors << "](";
687d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
688d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			const std::string padding(colorTable.str().length(), ' ');
689d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
690d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			for (int i = 0; i < numColors; ++i)
691d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				colorTable << (i != 0 ? ",\n" + padding : "") << toGlsl(s_colors[i]);
692d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
693d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			colorTable << ");\n";
694d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
695d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
696d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (params.testType == TEST_TYPE_DEFAULT_LAYER)
697d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
698d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
699d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
700d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
701d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
702d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
703d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
704d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
705d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
706d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
707d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
708d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n";
709d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
710d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (params.testType == TEST_TYPE_SINGLE_LAYER)
711d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
712d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			const deUint32 targetLayer = getTargetLayer(params.image);
713d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
714d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
715d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = " << targetLayer << ";\n"
716d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
717d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
718d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
719d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = " << targetLayer << ";\n"
720d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
721d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
722d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
723d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = " << targetLayer << ";\n"
724d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
725d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
726d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
727d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = " << targetLayer << ";\n"
728d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n";
729d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
730d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (params.testType == TEST_TYPE_ALL_LAYERS)
731d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
732d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << colorTable.str()
733d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
734b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa				<< "    for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
735d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
736d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
737d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
738d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
739d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        vert_color  = colors[colorNdx];\n"
740d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
741d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
742d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
743d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
744d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        vert_color  = colors[colorNdx];\n"
745d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
746d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
747d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
748d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
749d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        vert_color  = colors[colorNdx];\n"
750d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
751d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
752d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
753d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
754d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        vert_color  = colors[colorNdx];\n"
755d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
756d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EndPrimitive();\n"
757d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    };\n";
758d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
759d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (params.testType == TEST_TYPE_LAYER_ID)
760d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
761b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa			src << "    for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
762d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
763d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
764d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
765d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
766d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
767d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
768d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
769d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
770d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
771d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
772d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
773d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
774d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
775d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        gl_Layer    = layerNdx;\n"
776d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EmitVertex();\n"
777d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EndPrimitive();\n"
778d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    };\n";
779d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
780d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (params.testType == TEST_TYPE_DIFFERENT_CONTENT)
781d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
782b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa			src << "    for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
783d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        for (int colNdx = 0; colNdx <= layerNdx; ++colNdx) {\n"
784b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa				<< "            const float posX = float(colNdx) / float(" << numLayers << ") * 2.0 - 1.0;\n"
785d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
786d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "            gl_Position = vec4(posX,  1.0, 0.0, 1.0);\n"
787d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "            gl_Layer    = layerNdx;\n"
788d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "            EmitVertex();\n"
789d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
790d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "            gl_Position = vec4(posX, -1.0, 0.0, 1.0);\n"
791d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "            gl_Layer    = layerNdx;\n"
792d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "            EmitVertex();\n"
793d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        }\n"
794d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "        EndPrimitive();\n"
795d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    }\n";
796d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
797d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER)
798d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
799d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << colorTable.str()
800d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    const int colorNdx = gl_InvocationID % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
801d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
802d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
803d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = gl_InvocationID;\n"
804d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    vert_color  = colors[colorNdx];\n"
805d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
806d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
807d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
808d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = gl_InvocationID;\n"
809d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    vert_color  = colors[colorNdx];\n"
810d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
811d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
812d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
813d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = gl_InvocationID;\n"
814d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    vert_color  = colors[colorNdx];\n"
815d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
816d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
817d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4( 0.0,  1.0, 0.0, 1.0);\n"
818d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = gl_InvocationID;\n"
819d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    vert_color  = colors[colorNdx];\n"
820d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
821d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EndPrimitive();\n";
822d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
823d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
824d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
825d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << "    const int   layerA = gl_InvocationID;\n"
826b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa				<< "    const int   layerB = (gl_InvocationID + 1) % " << numLayers << ";\n"
827b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa				<< "    const float aEnd   = float(layerA) / float(" << numLayers << ") * 2.0 - 1.0;\n"
828b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa				<< "    const float bEnd   = float(layerB) / float(" << numLayers << ") * 2.0 - 1.0;\n"
829d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
830d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
831d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = layerA;\n"
832d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
833d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
834d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
835d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = layerA;\n"
836d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
837d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
838d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(aEnd, -1.0, 0.0, 1.0);\n"
839d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = layerA;\n"
840d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
841d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EndPrimitive();\n"
842d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
843d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
844d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = layerB;\n"
845d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
846d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
847d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(bEnd,  1.0, 0.0, 1.0);\n"
848d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = layerB;\n"
849d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
850d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "\n"
851d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Position = vec4(bEnd, -1.0, 0.0, 1.0);\n"
852d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    gl_Layer    = layerB;\n"
853d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EmitVertex();\n"
854d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "    EndPrimitive();\n";
855d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
856d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else
857d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			DE_ASSERT(0);
858d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
859d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		src <<	"}\n";	// end main
860d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
861d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
862d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
863d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
864d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	// Fragment shader
865d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
866d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		std::ostringstream src;
867d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
868d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "\n"
869d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "layout(location = 0) out vec4 o_color;\n"
870d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< (geomOutputColor ? "layout(location = 0) in  vec4 vert_color;\n" : "")
871d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "\n"
872d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "void main(void)\n"
873d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			<< "{\n";
874d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
875d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		if (params.testType == TEST_TYPE_LAYER_ID)
876d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
877d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			// This code must be in sync with verifyLayerContent()
878d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << "    o_color = vec4( (gl_Layer    % 2) == 1 ? 1.0 : 0.5,\n"
879d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "                   ((gl_Layer/2) % 2) == 1 ? 1.0 : 0.5,\n"
880d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "                     gl_Layer         == 0 ? 1.0 : 0.0,\n"
881d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				<< "                                             1.0);\n";
882d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
883d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else if (geomOutputColor)
884d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << "    o_color = vert_color;\n";
885d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		else
886d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			src << "    o_color = vec4(1.0);\n";
887d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
888d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		src << "}\n";
889d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
890d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
891d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
892d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
893d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
894d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwatcu::TestStatus test (Context& context, const TestParams params)
895d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
896b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	if (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType &&
897e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		(!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1")))
898b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
899b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa
900b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const DeviceInterface&			vk						= context.getDeviceInterface();
901b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const InstanceInterface&		vki						= context.getInstanceInterface();
902b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const VkDevice					device					= context.getDevice();
903b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const VkPhysicalDevice			physDevice				= context.getPhysicalDevice();
904b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const deUint32					queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
905b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const VkQueue					queue					= context.getUniversalQueue();
906b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	Allocator&						allocator				= context.getDefaultAllocator();
907d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
908d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	checkGeometryShaderSupport(vki, physDevice);
909d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
910d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkFormat					colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
911b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const deUint32					numLayers				= (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers);
912d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const Vec4						clearColor				= Vec4(0.0f, 0.0f, 0.0f, 1.0f);
913d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkDeviceSize				colorBufferSize			= params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * tcu::getPixelSize(mapVkFormat(colorFormat));
914b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const VkImageCreateFlags		imageCreateFlags		= (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) |
915b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa															  (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageCreateFlagBits)0);
916b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const VkImageViewType			viewType				= (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType);
917b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa
918b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkImage>			colorImage				(makeImage				(vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size,
919b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa																					 params.image.numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
920b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const UniquePtr<Allocation>		colorImageAlloc			(bindImage				(vk, device, allocator, *colorImage, MemoryRequirement::Any));
921b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkImageView>		colorAttachment			(makeImageView			(vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers)));
922b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa
923b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkBuffer>			colorBuffer				(makeBuffer				(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
924b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const UniquePtr<Allocation>		colorBufferAlloc		(bindBuffer				(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
925b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa
926b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkShaderModule>	vertexModule			(createShaderModule		(vk, device, context.getBinaryCollection().get("vert"), 0u));
927b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkShaderModule>	geometryModule			(createShaderModule		(vk, device, context.getBinaryCollection().get("geom"), 0u));
928b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkShaderModule>	fragmentModule			(createShaderModule		(vk, device, context.getBinaryCollection().get("frag"), 0u));
929b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa
930b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkRenderPass>		renderPass				(makeRenderPass			(vk, device, colorFormat));
931b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkFramebuffer>		framebuffer				(makeFramebuffer		(vk, device, *renderPass, *colorAttachment, params.image.size.width,  params.image.size.height, numLayers));
932b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkPipelineLayout>	pipelineLayout			(makePipelineLayout		(vk, device));
933b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa	const Unique<VkPipeline>		pipeline				(makeGraphicsPipeline	(vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule,
934b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa																					 makeExtent2D(params.image.size.width, params.image.size.height)));
935da03200a87f51bed33b3c3030ecbb6df06ff4f60Mika Isojärvi	const Unique<VkCommandPool>		cmdPool					(createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
936da03200a87f51bed33b3c3030ecbb6df06ff4f60Mika Isojärvi	const Unique<VkCommandBuffer>	cmdBuffer				(allocateCommandBuffer	(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
937d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
938d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
939d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
940d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	beginCommandBuffer(vk, *cmdBuffer);
941d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
942d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkClearValue			clearValue	= makeClearValueColor(clearColor);
943d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkRect2D				renderArea	=
944d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
945d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		makeOffset2D(0, 0),
946d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		makeExtent2D(params.image.size.width, params.image.size.height),
947d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
948d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const VkRenderPassBeginInfo renderPassBeginInfo =
949d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
950d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
951d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		DE_NULL,										// const void*             pNext;
952d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		*renderPass,									// VkRenderPass            renderPass;
953d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		*framebuffer,									// VkFramebuffer           framebuffer;
954d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		renderArea,										// VkRect2D                renderArea;
955d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		1u,												// uint32_t                clearValueCount;
956d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		&clearValue,									// const VkClearValue*     pClearValues;
957d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
958d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
959d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
960d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
961d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
962d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	vk.cmdEndRenderPass(*cmdBuffer);
963d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
964d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	// Prepare color image for copy
965d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
966b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		const VkImageSubresourceRange	colorSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers);
967b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		const VkImageMemoryBarrier		barriers[] =
968d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
969d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			{
970d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
971d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				DE_NULL,										// const void*				pNext;
972d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			outputMask;
973d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags			inputMask;
974d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			oldLayout;
975d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
976d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
977d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
978d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				*colorImage,									// VkImage					image;
979d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				colorSubresourceRange,							// VkImageSubresourceRange	subresourceRange;
980d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			},
981d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		};
982d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
983d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
984d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
985d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
986d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	// Color image -> host buffer
987d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
988d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const VkBufferImageCopy region =
989d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
990d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			0ull,																						// VkDeviceSize                bufferOffset;
991d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			0u,																							// uint32_t                    bufferRowLength;
992d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			0u,																							// uint32_t                    bufferImageHeight;
993d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, params.image.numLayers),		// VkImageSubresourceLayers    imageSubresource;
994d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			makeOffset3D(0, 0, 0),																		// VkOffset3D                  imageOffset;
995d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			params.image.size,																			// VkExtent3D                  imageExtent;
996d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		};
997d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
998d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
999d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
1000d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	// Buffer write barrier
1001d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
1002d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const VkBufferMemoryBarrier barriers[] =
1003d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
1004d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			{
1005d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType    sType;
1006d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				DE_NULL,										// const void*        pNext;
1007d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags      srcAccessMask;
1008d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_ACCESS_HOST_READ_BIT,						// VkAccessFlags      dstAccessMask;
1009d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_QUEUE_FAMILY_IGNORED,						// uint32_t           srcQueueFamilyIndex;
1010d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_QUEUE_FAMILY_IGNORED,						// uint32_t           dstQueueFamilyIndex;
1011d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				*colorBuffer,									// VkBuffer           buffer;
1012d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				0ull,											// VkDeviceSize       offset;
1013d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				VK_WHOLE_SIZE,									// VkDeviceSize       size;
1014d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			},
1015d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		};
1016d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1017d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1018d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u);
1019d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
1020d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1021d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1022d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1023d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1024d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSize);
1025d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1026d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr()))
1027d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return tcu::TestStatus::fail("Rendered images are incorrect");
1028d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	else
1029d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		return tcu::TestStatus::pass("OK");
1030d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
1031d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1032d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa} // anonymous
1033d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1034d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwatcu::TestCaseGroup* createLayeredRenderingTests (tcu::TestContext& testCtx)
1035d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa{
1036d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "layered", "Layered rendering tests."));
1037d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1038d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const struct
1039d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
1040d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		TestType		test;
1041d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const char*		name;
1042d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		const char*		description;
1043d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	} testTypes[] =
1044d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
1045d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ TEST_TYPE_DEFAULT_LAYER,					"render_to_default_layer",			"Render to the default layer"															},
1046d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ TEST_TYPE_SINGLE_LAYER,					"render_to_one",					"Render to one layer"																	},
1047d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ TEST_TYPE_ALL_LAYERS,						"render_to_all",					"Render to all layers"																	},
1048d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ TEST_TYPE_DIFFERENT_CONTENT,				"render_different_content",			"Render different data to different layers"												},
1049d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ TEST_TYPE_LAYER_ID,						"fragment_layer",					"Read gl_Layer in fragment shader"														},
1050d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ TEST_TYPE_INVOCATION_PER_LAYER,			"invocation_per_layer",				"Render to multiple layers with multiple invocations, one invocation per layer"			},
1051d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{ TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION,	"multiple_layers_per_invocation",	"Render to multiple layers with multiple invocations, multiple layers per invocation",	},
1052d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
1053d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1054d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	const ImageParams imageParams[] =
1055d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
1056b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		{ 64,  1, 1 },	4	},
1057b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		{ 64, 64, 1 },	4	},
1058b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		{ VK_IMAGE_VIEW_TYPE_CUBE,			{ 64, 64, 1 },	6	},
1059b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	{ 64, 64, 1 },	2*6	},
1060b97bfdfcaffb9bc5bd568fa2824d183249f24ae6Arkadiusz Sarwa		{ VK_IMAGE_VIEW_TYPE_3D,			{ 64, 64, 8 },	1	}
1061d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	};
1062d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1063d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	for (int imageParamNdx = 0; imageParamNdx < DE_LENGTH_OF_ARRAY(imageParams); ++imageParamNdx)
1064d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	{
1065d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, getShortImageViewTypeName(imageParams[imageParamNdx].viewType).c_str(), ""));
1066d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1067d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		for (int testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
1068d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		{
1069d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			const TestParams params =
1070d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			{
1071d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				testTypes[testTypeNdx].test,
1072d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa				imageParams[imageParamNdx],
1073d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			};
1074d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa			addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, initPrograms, test, params);
1075d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		}
1076d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1077d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa		group->addChild(viewTypeGroup.release());
1078d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	}
1079d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1080d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa	return group.release();
1081d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa}
1082d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa
1083d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa} // geometry
1084d5c8a7f813ed59d8c01ef9a8aa9a6087c3f946bfArkadiusz Sarwa} // vkt
1085