Home | History | Annotate | Download | only in multiview
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2017 The Khronos Group Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Vulkan Multi View Render Tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktMultiViewRenderTests.hpp"
     25 #include "vktMultiViewRenderUtil.hpp"
     26 
     27 #include "vktTestCase.hpp"
     28 #include "vkBuilderUtil.hpp"
     29 #include "vkRefUtil.hpp"
     30 #include "vkQueryUtil.hpp"
     31 #include "vkTypeUtil.hpp"
     32 #include "vkPrograms.hpp"
     33 #include "vkPlatform.hpp"
     34 #include "vkMemUtil.hpp"
     35 #include "vkImageUtil.hpp"
     36 
     37 #include "tcuTestLog.hpp"
     38 #include "tcuResource.hpp"
     39 #include "tcuImageCompare.hpp"
     40 #include "tcuCommandLine.hpp"
     41 #include "tcuTextureUtil.hpp"
     42 #include "tcuRGBA.hpp"
     43 
     44 #include "deSharedPtr.hpp"
     45 
     46 namespace vkt
     47 {
     48 namespace MultiView
     49 {
     50 namespace
     51 {
     52 
     53 using namespace vk;
     54 using de::MovePtr;
     55 using de::UniquePtr;
     56 using std::vector;
     57 using std::map;
     58 using std::string;
     59 
     60 enum TestType
     61 {
     62 	TEST_TYPE_VIEW_MASK,
     63 	TEST_TYPE_VIEW_INDEX_IN_VERTEX,
     64 	TEST_TYPE_VIEW_INDEX_IN_FRAGMENT,
     65 	TEST_TYPE_VIEW_INDEX_IN_GEOMETRY,
     66 	TEST_TYPE_VIEW_INDEX_IN_TESELLATION,
     67 	TEST_TYPE_INPUT_ATTACHMENTS,
     68 	TEST_TYPE_INSTANCED_RENDERING,
     69 	TEST_TYPE_INPUT_RATE_INSTANCE,
     70 	TEST_TYPE_DRAW_INDIRECT,
     71 	TEST_TYPE_CLEAR_ATTACHMENTS,
     72 	TEST_TYPE_SECONDARY_CMD_BUFFER,
     73 	TEST_TYPE_LAST
     74 };
     75 
     76 struct TestParameters
     77 {
     78 	VkExtent3D			extent;
     79 	vector<deUint32>	viewMasks;
     80 	TestType			viewIndex;
     81 };
     82 
     83 class ImageAttachment
     84 {
     85 public:
     86 				ImageAttachment	(VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat);
     87 	VkImageView	getImageView	(void) const
     88 	{
     89 		return *m_imageView;
     90 	}
     91 	VkImage		getImage		(void) const
     92 	{
     93 		return *m_image;
     94 	}
     95 private:
     96 	Move<VkImage>			m_image;
     97 	MovePtr<Allocation>		m_allocationImage;
     98 	Move<VkImageView>		m_imageView;
     99 };
    100 
    101 ImageAttachment::ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat)
    102 {
    103 	const VkImageSubresourceRange	colorImageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, extent.depth);
    104 	const VkImageCreateInfo			colorAttachmentImageInfo	= makeImageCreateInfo(VK_IMAGE_TYPE_2D, extent, colorFormat,
    105 																VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    106 
    107 	m_image							= createImage(device, logicalDevice, &colorAttachmentImageInfo);
    108 	m_allocationImage				= allocator.allocate(getImageMemoryRequirements(device, logicalDevice, *m_image), MemoryRequirement::Any);
    109 	VK_CHECK(device.bindImageMemory(logicalDevice, *m_image, m_allocationImage->getMemory(), m_allocationImage->getOffset()));
    110 	m_imageView						= makeImageView(device, logicalDevice, *m_image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, colorFormat, colorImageSubresourceRange);
    111 }
    112 
    113 class MultiViewRenderTestInstance : public TestInstance
    114 {
    115 public:
    116 									MultiViewRenderTestInstance	(Context& context, const TestParameters& parameters);
    117 protected:
    118 	typedef de::SharedPtr<Unique<VkPipeline> >		PipelineSp;
    119 	typedef de::SharedPtr<Unique<VkShaderModule> >	ShaderModuleSP;
    120 
    121 	struct VertexData
    122 	{
    123 		VertexData (const tcu::Vec4 position_, const tcu::Vec4 color_)
    124 			: position	(position_)
    125 			, color		(color_)
    126 		{}
    127 		tcu::Vec4	position;
    128 		tcu::Vec4	color;
    129 	};
    130 
    131 	virtual tcu::TestStatus			iterate					(void);
    132 	virtual void					beforeDraw				(void);
    133 	virtual void					afterDraw				(void);
    134 	virtual void					draw					(const deUint32			subpassCount,
    135 															 VkRenderPass			renderPass,
    136 															 VkFramebuffer			frameBuffer,
    137 															 vector<PipelineSp>&	pipelines);
    138 	virtual void					createVertexData		(void);
    139 	TestParameters					fillMissingParameters	(const TestParameters&	parameters);
    140 	void							createVertexBuffer		(void);
    141 	void							createMultiViewDevices	(void);
    142 	void							createCommandBuffer		(void);
    143 	void							madeShaderModule		(map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams);
    144 	Move<VkPipeline>				makeGraphicsPipeline	(const VkRenderPass							renderPass,
    145 															 const VkPipelineLayout						pipelineLayout,
    146 															 const deUint32								pipelineShaderStageCount,
    147 															 const VkPipelineShaderStageCreateInfo*		pipelineShaderStageCreate,
    148 															 const deUint32								subpass,
    149 															 const VkVertexInputRate					vertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX);
    150 	void							readImage				(VkImage image, const tcu::PixelBufferAccess& dst);
    151 	bool							checkImage				(tcu::ConstPixelBufferAccess& dst);
    152 	MovePtr<tcu::Texture2DArray>	imageData				(void);
    153 
    154 	const TestParameters			m_parameters;
    155 	VkFormat						m_colorFormat;
    156 	const deUint32					m_squareCount;
    157 	Move<VkDevice>					m_logicalDevice;
    158 	MovePtr<DeviceInterface>		m_device;
    159 	MovePtr<Allocator>				m_allocator;
    160 	deUint32						m_queueFamilyIndex;
    161 	VkQueue							m_queue;
    162 	vector<VertexData>				m_data;
    163 	Move<VkBuffer>					m_vertexBuffer;
    164 	MovePtr<Allocation>				m_allocationBuffer;
    165 	Move<VkCommandPool>				m_cmdPool;
    166 	Move<VkCommandBuffer>			m_cmdBuffer;
    167 	de::SharedPtr<ImageAttachment>	m_colorAttachment;
    168 	VkBool32						m_hasMultiDrawIndirect;
    169 };
    170 
    171 MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters)
    172 	: TestInstance		(context)
    173 	, m_parameters		(fillMissingParameters(parameters))
    174 	, m_colorFormat		(VK_FORMAT_R8G8B8A8_UNORM)
    175 	, m_squareCount		(4u)
    176 	,m_queueFamilyIndex	(0u)
    177 {
    178 	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_multiview"))
    179 		throw tcu::NotSupportedError("VK_KHR_multiview is not supported");
    180 
    181 	createMultiViewDevices();
    182 
    183 	// Color attachment
    184 	m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_colorFormat));
    185 }
    186 
    187 tcu::TestStatus MultiViewRenderTestInstance::iterate (void)
    188 {
    189 	const deUint32								subpassCount				= static_cast<deUint32>(m_parameters.viewMasks.size());
    190 
    191 	// FrameBuffer & renderPass
    192 	Unique<VkRenderPass>						renderPass					(makeRenderPass (*m_device, *m_logicalDevice, m_colorFormat, m_parameters.viewMasks));
    193 
    194 	vector<VkImageView>							attachments;
    195 	attachments.push_back(m_colorAttachment->getImageView());
    196 	Unique<VkFramebuffer>						frameBuffer					(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, attachments, m_parameters.extent.width, m_parameters.extent.height, 1u));
    197 
    198 	// pipelineLayout
    199 	Unique<VkPipelineLayout>					pipelineLayout				(makePipelineLayout(*m_device, *m_logicalDevice));
    200 
    201 	// pipelines
    202 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
    203 	vector<PipelineSp>							pipelines(subpassCount);
    204 	const VkVertexInputRate						vertexInputRate				= (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
    205 
    206 	{
    207 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
    208 		madeShaderModule(shaderModule, shaderStageParams);
    209 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
    210 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
    211 	}
    212 
    213 	createCommandBuffer();
    214 	createVertexData();
    215 	createVertexBuffer();
    216 
    217 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
    218 
    219 	{
    220 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_colorFormat).getPixelSize());
    221 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
    222 
    223 		readImage(m_colorAttachment->getImage(), dst);
    224 		if (!checkImage(dst))
    225 			return tcu::TestStatus::fail("Fail");
    226 	}
    227 
    228 	return tcu::TestStatus::pass("Pass");
    229 }
    230 
    231 void MultiViewRenderTestInstance::beforeDraw (void)
    232 {
    233 	const VkImageSubresourceRange	subresourceRange		=
    234 	{
    235 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
    236 		0u,							//deUint32				baseMipLevel;
    237 		1u,							//deUint32				levelCount;
    238 		0u,							//deUint32				baseArrayLayer;
    239 		m_parameters.extent.depth,	//deUint32				layerCount;
    240 	};
    241 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
    242 
    243 	const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
    244 	m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);
    245 
    246 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
    247 
    248 }
    249 
    250 void MultiViewRenderTestInstance::afterDraw (void)
    251 {
    252 	const VkImageSubresourceRange	subresourceRange		=
    253 	{
    254 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
    255 		0u,							//deUint32				baseMipLevel;
    256 		1u,							//deUint32				levelCount;
    257 		0u,							//deUint32				baseArrayLayer;
    258 		m_parameters.extent.depth,	//deUint32				layerCount;
    259 	};
    260 
    261 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(),
    262 		subresourceRange, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
    263 }
    264 
    265 void MultiViewRenderTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
    266 {
    267 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
    268 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
    269 	const VkDeviceSize				vertexBufferOffset		= 0u;
    270 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
    271 
    272 	const VkRenderPassBeginInfo		renderPassBeginInfo		=
    273 	{
    274 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
    275 		DE_NULL,									// const void*			pNext;
    276 		renderPass,									// VkRenderPass			renderPass;
    277 		frameBuffer,								// VkFramebuffer		framebuffer;
    278 		renderArea,									// VkRect2D				renderArea;
    279 		1u,											// uint32_t				clearValueCount;
    280 		&renderPassClearValue,						// const VkClearValue*	pClearValues;
    281 	};
    282 
    283 	beginCommandBuffer(*m_device, *m_cmdBuffer);
    284 
    285 	beforeDraw();
    286 
    287 	m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
    288 
    289 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset);
    290 
    291 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
    292 	{
    293 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
    294 
    295 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
    296 			m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
    297 
    298 		if (subpassNdx < subpassCount - 1u)
    299 			m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
    300 	}
    301 
    302 	m_device->cmdEndRenderPass(*m_cmdBuffer);
    303 
    304 	afterDraw();
    305 
    306 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
    307 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
    308 }
    309 
    310 void MultiViewRenderTestInstance::createVertexData (void)
    311 {
    312 	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
    313 	m_data.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color));
    314 	m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color));
    315 	m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color));
    316 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
    317 
    318 	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
    319 	m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color));
    320 	m_data.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color));
    321 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
    322 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color));
    323 
    324 	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
    325 	m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color));
    326 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
    327 	m_data.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color));
    328 	m_data.push_back(VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color));
    329 
    330 	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
    331 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
    332 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color));
    333 	m_data.push_back(VertexData(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color));
    334 	m_data.push_back(VertexData(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color));
    335 }
    336 
    337 TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters)
    338 {
    339 	if (!parameters.viewMasks.empty())
    340 		return parameters;
    341 	else
    342 	{
    343 		if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_multiview"))
    344 			throw tcu::NotSupportedError("VK_KHR_multiview is not supported");
    345 
    346 		const InstanceInterface&			instance			= m_context.getInstanceInterface();
    347 		const VkPhysicalDevice				physicalDevice		= m_context.getPhysicalDevice();
    348 
    349 		VkPhysicalDeviceMultiviewProperties multiviewProperties =
    350 		{
    351 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,	// VkStructureType	sType;
    352 			DE_NULL,													// void*			pNext;
    353 			0u,															// deUint32			maxMultiviewViewCount;
    354 			0u															// deUint32			maxMultiviewInstanceIndex;
    355 		};
    356 
    357 		VkPhysicalDeviceProperties2 deviceProperties2;
    358 		deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
    359 		deviceProperties2.pNext = &multiviewProperties;
    360 
    361 		instance.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
    362 
    363 		TestParameters newParameters = parameters;
    364 		newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount;
    365 
    366 		vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount);
    367 		for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++)
    368 			viewMasks[i] = 1 << i;
    369 		newParameters.viewMasks = viewMasks;
    370 
    371 		return newParameters;
    372 	}
    373 }
    374 
    375 void MultiViewRenderTestInstance::createVertexBuffer (void)
    376 {
    377 	const VkDeviceSize						vertexDataSize			= static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>( m_data.size() * sizeof(VertexData)),
    378 																	static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
    379 	const VkBufferCreateInfo				bufferInfo				= makeBufferCreateInfo(vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
    380 
    381 	m_vertexBuffer		= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
    382 	m_allocationBuffer	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexBuffer),  MemoryRequirement::HostVisible);
    383 
    384 	// Init host buffer data
    385 	VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexBuffer, m_allocationBuffer->getMemory(), m_allocationBuffer->getOffset()));
    386 	deMemcpy(m_allocationBuffer->getHostPtr(), m_data.data(), static_cast<size_t>(vertexDataSize));
    387 	flushMappedMemoryRange(*m_device, *m_logicalDevice, m_allocationBuffer->getMemory(), m_allocationBuffer->getOffset(), static_cast<size_t>(vertexDataSize));
    388 }
    389 
    390 void MultiViewRenderTestInstance::createMultiViewDevices (void)
    391 {
    392 	const InstanceInterface&				instance				= m_context.getInstanceInterface();
    393 	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
    394 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
    395 
    396 	for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex)
    397 	{
    398 		if (queueFamilyProperties[m_queueFamilyIndex].queueFlags | VK_QUEUE_GRAPHICS_BIT )
    399 			break;
    400 	}
    401 
    402 	const float								queuePriorities			= 1.0f;
    403 	const VkDeviceQueueCreateInfo			queueInfo				=
    404 	{
    405 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,					//VkStructureType			sType;
    406 		DE_NULL,													//const void*				pNext;
    407 		(VkDeviceQueueCreateFlags)0u,								//VkDeviceQueueCreateFlags	flags;
    408 		m_queueFamilyIndex,											//deUint32					queueFamilyIndex;
    409 		1u,															//deUint32					queueCount;
    410 		&queuePriorities											//const float*				pQueuePriorities;
    411 	};
    412 
    413 	VkPhysicalDeviceMultiviewFeatures		multiviewFeatures		=
    414 	{
    415 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR,	// VkStructureType			sType;
    416 		DE_NULL,													// void*					pNext;
    417 		DE_FALSE,													// VkBool32					multiview;
    418 		DE_FALSE,													// VkBool32					multiviewGeometryShader;
    419 		DE_FALSE,													// VkBool32					multiviewTessellationShader;
    420 	};
    421 
    422 	VkPhysicalDeviceFeatures2				enabledFeatures;
    423 	enabledFeatures.sType					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    424 	enabledFeatures.pNext					= &multiviewFeatures;
    425 
    426 	instance.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
    427 
    428 	if (!multiviewFeatures.multiview)
    429 		TCU_THROW(NotSupportedError, "MultiView not supported");
    430 
    431 	bool requiresGeomShader = (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex) ||
    432 								(TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex) ||
    433 								(TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex) ||
    434 								(TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex);
    435 
    436 	if (requiresGeomShader && !multiviewFeatures.multiviewGeometryShader)
    437 		TCU_THROW(NotSupportedError, "Geometry shader is not supported");
    438 
    439 	if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader)
    440 		TCU_THROW(NotSupportedError, "Tessellation shader is not supported");
    441 
    442 	VkPhysicalDeviceMultiviewProperties	multiviewProperties			=
    443 	{
    444 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,	//VkStructureType	sType;
    445 		DE_NULL,													//void*				pNext;
    446 		0u,															//deUint32			maxMultiviewViewCount;
    447 		0u															//deUint32			maxMultiviewInstanceIndex;
    448 	};
    449 
    450 	VkPhysicalDeviceProperties2			propertiesDeviceProperties2;
    451 	propertiesDeviceProperties2.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
    452 	propertiesDeviceProperties2.pNext	= &multiviewProperties;
    453 
    454 	instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2);
    455 
    456 	if (multiviewProperties.maxMultiviewViewCount < 6u)
    457 		TCU_FAIL("maxMultiviewViewCount below min value");
    458 
    459 	if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1
    460 		TCU_FAIL("maxMultiviewInstanceIndex below min value");
    461 
    462 	if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth)
    463 		TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test");
    464 
    465 	m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect;
    466 
    467 	{
    468 		vector<const char*>							deviceExtensions;
    469 
    470 		if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview"))
    471 			deviceExtensions.push_back("VK_KHR_multiview");
    472 
    473 		const VkDeviceCreateInfo		deviceInfo			=
    474 		{
    475 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//VkStructureType					sType;
    476 			&enabledFeatures,												//const void*						pNext;
    477 			0u,																//VkDeviceCreateFlags				flags;
    478 			1u,																//deUint32							queueCreateInfoCount;
    479 			&queueInfo,														//const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
    480 			0u,																//deUint32							enabledLayerCount;
    481 			DE_NULL,														//const char* const*				ppEnabledLayerNames;
    482 			static_cast<deUint32>(deviceExtensions.size()),					//deUint32							enabledExtensionCount;
    483 			deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],		//const char* const*				pEnabledExtensionNames;
    484 			DE_NULL															//const VkPhysicalDeviceFeatures*	pEnabledFeatures;
    485 		};
    486 
    487 		m_logicalDevice					= createDevice(instance, physicalDevice, &deviceInfo);
    488 		m_device						= MovePtr<DeviceDriver>(new DeviceDriver(instance, *m_logicalDevice));
    489 		m_allocator						= MovePtr<Allocator>(new SimpleAllocator(*m_device, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice)));
    490 		m_device->getDeviceQueue		(*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue);
    491 	}
    492 }
    493 
    494 void MultiViewRenderTestInstance::createCommandBuffer (void)
    495 {
    496 	// cmdPool
    497 	{
    498 		const VkCommandPoolCreateInfo cmdPoolParams =
    499 		{
    500 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType		sType;
    501 			DE_NULL,											// const void*			pNext;
    502 			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCmdPoolCreateFlags	flags;
    503 			m_queueFamilyIndex,									// deUint32				queueFamilyIndex;
    504 		};
    505 		m_cmdPool = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams);
    506 	}
    507 
    508 	// cmdBuffer
    509 	{
    510 		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
    511 		{
    512 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
    513 			DE_NULL,											// const void*			pNext;
    514 			*m_cmdPool,											// VkCommandPool		commandPool;
    515 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
    516 			1u,													// deUint32				bufferCount;
    517 		};
    518 		m_cmdBuffer	= allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo);
    519 	}
    520 }
    521 
    522 void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams)
    523 {
    524 	// create shaders modules
    525 	switch (m_parameters.viewIndex)
    526 	{
    527 		case TEST_TYPE_VIEW_MASK:
    528 		case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
    529 		case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
    530 		case TEST_TYPE_INSTANCED_RENDERING:
    531 		case TEST_TYPE_INPUT_RATE_INSTANCE:
    532 		case TEST_TYPE_DRAW_INDIRECT:
    533 			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
    534 			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
    535 			break;
    536 		case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
    537 		case TEST_TYPE_INPUT_ATTACHMENTS:
    538 		case TEST_TYPE_CLEAR_ATTACHMENTS:
    539 		case TEST_TYPE_SECONDARY_CMD_BUFFER:
    540 			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
    541 			shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0))));
    542 			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
    543 			break;
    544 		case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
    545 			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
    546 			shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT]		= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0))));
    547 			shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT]	= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0))));
    548 			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
    549 			break;
    550 		default:
    551 			DE_ASSERT(0);
    552 		break;
    553 	};
    554 
    555 	VkPipelineShaderStageCreateInfo	pipelineShaderStage	=
    556 	{
    557 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
    558 			DE_NULL,												// const void*							pNext;
    559 			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
    560 			(VkShaderStageFlagBits)0,								// VkShaderStageFlagBits				stage;
    561 			(VkShaderModule)0,										// VkShaderModule						module;
    562 			"main",													// const char*							pName;
    563 			(const VkSpecializationInfo*)DE_NULL,					// const VkSpecializationInfo*			pSpecializationInfo;
    564 	};
    565 
    566 	for (map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it)
    567 	{
    568 		pipelineShaderStage.stage	= it->first;
    569 		pipelineShaderStage.module	= **it->second;
    570 		shaderStageParams.push_back(pipelineShaderStage);
    571 	}
    572 }
    573 
    574 Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass							renderPass,
    575 																	const VkPipelineLayout						pipelineLayout,
    576 																	const deUint32								pipelineShaderStageCount,
    577 																	const VkPipelineShaderStageCreateInfo*		pipelineShaderStageCreate,
    578 																	const deUint32								subpass,
    579 																	const VkVertexInputRate						vertexInputRate)
    580 {
    581 	const VkVertexInputBindingDescription			vertexInputBindingDescription		=
    582 	{
    583 		0u,											// binding;
    584 		static_cast<deUint32>(sizeof(VertexData)),	// stride;
    585 		vertexInputRate								// inputRate
    586 	};
    587 
    588 	const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[]	=
    589 	{
    590 		{
    591 			0u,
    592 			0u,
    593 			VK_FORMAT_R32G32B32A32_SFLOAT,
    594 			0u
    595 		},	// VertexElementData::position
    596 		{
    597 			1u,
    598 			0u,
    599 			VK_FORMAT_R32G32B32A32_SFLOAT,
    600 			static_cast<deUint32>(sizeof(tcu::Vec4))
    601 		},	// VertexElementData::color
    602 	};
    603 
    604 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
    605 	{																	// sType;
    606 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// pNext;
    607 		NULL,															// flags;
    608 		0u,																// vertexBindingDescriptionCount;
    609 		1u,																// pVertexBindingDescriptions;
    610 		&vertexInputBindingDescription,									// vertexAttributeDescriptionCount;
    611 		2u,																// pVertexAttributeDescriptions;
    612 		vertexInputAttributeDescriptions
    613 	};
    614 
    615 
    616 	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateParams			=
    617 	{
    618 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,																				// VkStructureType							sType;
    619 		DE_NULL,																																	// const void*								pNext;
    620 		0u,																																			// VkPipelineInputAssemblyStateCreateFlags	flags;
    621 		(TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// VkPrimitiveTopology						topology;
    622 		VK_FALSE,																																	// VkBool32									primitiveRestartEnable;
    623 	};
    624 
    625 	const VkViewport								viewport							=
    626 	{
    627 		0.0f,								// float	originX;
    628 		0.0f,								// float	originY;
    629 		(float)m_parameters.extent.width,	// float	width;
    630 		(float)m_parameters.extent.height,	// float	height;
    631 		0.0f,								// float	minDepth;
    632 		1.0f								// float	maxDepth;
    633 	};
    634 
    635 	const VkRect2D									scissor								=
    636 	{
    637 		{ 0, 0 },													// VkOffset2D	offset;
    638 		{ m_parameters.extent.width, m_parameters.extent.height }	// VkExtent2D	extent;
    639 	};
    640 
    641 	const VkPipelineViewportStateCreateInfo		viewportStateParams						=
    642 	{
    643 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType						sType;
    644 		DE_NULL,												// const void*							pNext;
    645 		0u,														// VkPipelineViewportStateCreateFlags	flags;
    646 		1u,														// deUint32								viewportCount;
    647 		&viewport,												// const VkViewport*					pViewports;
    648 		1u,														// deUint32								scissorCount;
    649 		&scissor												// const VkRect2D*						pScissors;
    650 	};
    651 
    652 	const VkPipelineRasterizationStateCreateInfo	rasterStateParams					=
    653 	{
    654 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
    655 		DE_NULL,													// const void*								pNext;
    656 		0u,															// VkPipelineRasterizationStateCreateFlags	flags;
    657 		VK_FALSE,													// VkBool32									depthClampEnable;
    658 		VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
    659 		VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
    660 		VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
    661 		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
    662 		VK_FALSE,													// VkBool32									depthBiasEnable;
    663 		0.0f,														// float									depthBiasConstantFactor;
    664 		0.0f,														// float									depthBiasClamp;
    665 		0.0f,														// float									depthBiasSlopeFactor;
    666 		1.0f,														// float									lineWidth;
    667 	};
    668 
    669 	const VkPipelineMultisampleStateCreateInfo		multisampleStateParams				=
    670 	{
    671 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
    672 		DE_NULL,													// const void*								pNext;
    673 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
    674 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
    675 		VK_FALSE,													// VkBool32									sampleShadingEnable;
    676 		0.0f,														// float									minSampleShading;
    677 		DE_NULL,													// const VkSampleMask*						pSampleMask;
    678 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
    679 		VK_FALSE,													// VkBool32									alphaToOneEnable;
    680 	};
    681 
    682 	VkPipelineDepthStencilStateCreateInfo			depthStencilStateParams				=
    683 	{
    684 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
    685 		DE_NULL,													// const void*								pNext;
    686 		0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
    687 		VK_TRUE,													// VkBool32									depthTestEnable;
    688 		VK_TRUE,													// VkBool32									depthWriteEnable;
    689 		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp;
    690 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
    691 		VK_FALSE,													// VkBool32									stencilTestEnable;
    692 		// VkStencilOpState front;
    693 		{
    694 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
    695 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
    696 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
    697 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
    698 			0u,						// deUint32		compareMask;
    699 			0u,						// deUint32		writeMask;
    700 			0u,						// deUint32		reference;
    701 		},
    702 		// VkStencilOpState back;
    703 		{
    704 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
    705 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
    706 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
    707 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
    708 			0u,						// deUint32		compareMask;
    709 			0u,						// deUint32		writeMask;
    710 			0u,						// deUint32		reference;
    711 		},
    712 		0.0f,	// float	minDepthBounds;
    713 		1.0f,	// float	maxDepthBounds;
    714 	};
    715 
    716 	const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState			=
    717 	{
    718 		VK_FALSE,								// VkBool32					blendEnable;
    719 		VK_BLEND_FACTOR_SRC_ALPHA,				// VkBlendFactor			srcColorBlendFactor;
    720 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstColorBlendFactor;
    721 		VK_BLEND_OP_ADD,						// VkBlendOp				colorBlendOp;
    722 		VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcAlphaBlendFactor;
    723 		VK_BLEND_FACTOR_ONE,					// VkBlendFactor			dstAlphaBlendFactor;
    724 		VK_BLEND_OP_ADD,						// VkBlendOp				alphaBlendOp;
    725 		VK_COLOR_COMPONENT_R_BIT |				// VkColorComponentFlags	colorWriteMask;
    726 		VK_COLOR_COMPONENT_G_BIT |
    727 		VK_COLOR_COMPONENT_B_BIT |
    728 		VK_COLOR_COMPONENT_A_BIT
    729 	};
    730 
    731 	const VkPipelineColorBlendStateCreateInfo		colorBlendStateParams				=
    732 	{
    733 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
    734 		DE_NULL,													// const void*									pNext;
    735 		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
    736 		VK_FALSE,													// VkBool32										logicOpEnable;
    737 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
    738 		1u,															// deUint32										attachmentCount;
    739 		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
    740 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
    741 	};
    742 
    743 	VkPipelineTessellationStateCreateInfo			TessellationState					=
    744 	{
    745 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	// VkStructureType							sType;
    746 		DE_NULL,													// const void*								pNext;
    747 		(VkPipelineTessellationStateCreateFlags)0,					// VkPipelineTessellationStateCreateFlags	flags;
    748 		4u															// deUint32									patchControlPoints;
    749 	};
    750 
    751 	const VkGraphicsPipelineCreateInfo				graphicsPipelineParams				=
    752 	{
    753 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,												// VkStructureType									sType;
    754 		DE_NULL,																						// const void*										pNext;
    755 		(VkPipelineCreateFlags)0u,																		// VkPipelineCreateFlags							flags;
    756 		pipelineShaderStageCount,																		// deUint32											stageCount;
    757 		pipelineShaderStageCreate,																		// const VkPipelineShaderStageCreateInfo*			pStages;
    758 		&vertexInputStateParams,																		// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
    759 		&inputAssemblyStateParams,																		// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
    760 		(TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL,	// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
    761 		&viewportStateParams,																			// const VkPipelineViewportStateCreateInfo*			pViewportState;
    762 		&rasterStateParams,																				// const VkPipelineRasterizationStateCreateInfo*	pRasterState;
    763 		&multisampleStateParams,																		// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
    764 		&depthStencilStateParams,																		// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
    765 		&colorBlendStateParams,																			// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
    766 		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,												// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
    767 		pipelineLayout,																					// VkPipelineLayout									layout;
    768 		renderPass,																						// VkRenderPass										renderPass;
    769 		subpass,																						// deUint32											subpass;
    770 		0u,																								// VkPipeline										basePipelineHandle;
    771 		0,																								// deInt32											basePipelineIndex;
    772 	};
    773 
    774 	return createGraphicsPipeline(*m_device, *m_logicalDevice, DE_NULL, &graphicsPipelineParams);
    775 }
    776 
    777 void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
    778 {
    779 	Move<VkBuffer>				buffer;
    780 	MovePtr<Allocation>			bufferAlloc;
    781 	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_colorFormat).getPixelSize();
    782 
    783 	// Create destination buffer
    784 	{
    785 		const VkBufferCreateInfo bufferParams =
    786 		{
    787 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
    788 			DE_NULL,								// const void*			pNext;
    789 			0u,										// VkBufferCreateFlags	flags;
    790 			pixelDataSize,							// VkDeviceSize			size;
    791 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
    792 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
    793 			1u,										// deUint32				queueFamilyIndexCount;
    794 			&m_queueFamilyIndex,					// const deUint32*		pQueueFamilyIndices;
    795 		};
    796 
    797 		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
    798 		bufferAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
    799 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
    800 
    801 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
    802 		flushMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
    803 	}
    804 
    805 	const VkBufferMemoryBarrier	bufferBarrier	=
    806 	{
    807 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
    808 		DE_NULL,									// const void*		pNext;
    809 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
    810 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
    811 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
    812 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
    813 		*buffer,									// VkBuffer			buffer;
    814 		0u,											// VkDeviceSize		offset;
    815 		pixelDataSize								// VkDeviceSize		size;
    816 	};
    817 
    818 	// Copy image to buffer
    819 	const VkImageAspectFlags	aspect			= getAspectFlags(dst.getFormat());
    820 	const VkBufferImageCopy		copyRegion		=
    821 	{
    822 		0u,										// VkDeviceSize				bufferOffset;
    823 		(deUint32)dst.getWidth(),				// deUint32					bufferRowLength;
    824 		(deUint32)dst.getHeight(),				// deUint32					bufferImageHeight;
    825 		{
    826 			aspect,								// VkImageAspectFlags		aspect;
    827 			0u,									// deUint32					mipLevel;
    828 			0u,									// deUint32					baseArrayLayer;
    829 			m_parameters.extent.depth,			// deUint32					layerCount;
    830 		},										// VkImageSubresourceLayers	imageSubresource;
    831 		{ 0, 0, 0 },							// VkOffset3D				imageOffset;
    832 		{ m_parameters.extent.width, m_parameters.extent.height, 1u }	// VkExtent3D				imageExtent;
    833 	};
    834 
    835 	beginCommandBuffer (*m_device, *m_cmdBuffer);
    836 	{
    837 		VkImageSubresourceRange	subresourceRange	=
    838 		{
    839 			aspect,						// VkImageAspectFlags	aspectMask;
    840 			0u,							// deUint32				baseMipLevel;
    841 			1u,							// deUint32				mipLevels;
    842 			0u,							// deUint32				baseArraySlice;
    843 			m_parameters.extent.depth,	// deUint32				arraySize;
    844 		};
    845 
    846 		imageBarrier (*m_device, *m_cmdBuffer, image, subresourceRange, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
    847 						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
    848 
    849 		m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
    850 		m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
    851 	}
    852 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
    853 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
    854 
    855 	// Read buffer data
    856 	invalidateMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
    857 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
    858 }
    859 
    860 bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame)
    861 {
    862 	const MovePtr<tcu::Texture2DArray>	referenceFrame	= imageData();
    863 
    864 	if (tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", referenceFrame->getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
    865 		return true;
    866 
    867 	for (deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++)
    868 	{
    869 		tcu::ConstPixelBufferAccess ref (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx));
    870 		tcu::ConstPixelBufferAccess dst (mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx));
    871 		tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING);
    872 	}
    873 
    874 	return false;
    875 }
    876 
    877 MovePtr<tcu::Texture2DArray> MultiViewRenderTestInstance::imageData (void)
    878 {
    879 	MovePtr<tcu::Texture2DArray>	referenceFrame	= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth));
    880 	const deUint32					subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());
    881 	referenceFrame->allocLevel(0);
    882 
    883 	deMemset (referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_colorFormat).getPixelSize());
    884 
    885 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
    886 	{
    887 		int			layerNdx	= 0;
    888 		deUint32	mask		= m_parameters.viewMasks[subpassNdx];
    889 
    890 		while (mask > 0u)
    891 		{
    892 			int colorNdx	= 0;
    893 			if (mask & 1u)
    894 			{
    895 				if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
    896 				{
    897 					struct ColorDataRGBA
    898 					{
    899 						deUint8	r;
    900 						deUint8	g;
    901 						deUint8	b;
    902 						deUint8	a;
    903 					};
    904 
    905 					ColorDataRGBA	clear		=
    906 					{
    907 						tcu::floatToU8 (1.0f),
    908 						tcu::floatToU8 (0.0f),
    909 						tcu::floatToU8 (0.0f),
    910 						tcu::floatToU8 (1.0f)
    911 					};
    912 
    913 					ColorDataRGBA*	dataSrc		= (ColorDataRGBA*)referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx);
    914 					ColorDataRGBA*	dataDes		= dataSrc + 1;
    915 					deUint32		copySize	= 1u;
    916 					deUint32		layerSize	= m_parameters.extent.width * m_parameters.extent.height - copySize;
    917 					deMemcpy(dataSrc, &clear, sizeof(ColorDataRGBA));
    918 
    919 					while (layerSize > 0)
    920 					{
    921 						deMemcpy(dataDes, dataSrc, copySize * sizeof(ColorDataRGBA));
    922 						dataDes = dataDes + copySize;
    923 						layerSize = layerSize - copySize;
    924 						copySize = 2u * copySize;
    925 						if (copySize >= layerSize)
    926 							copySize = layerSize;
    927 					}
    928 				}
    929 
    930 				const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount;
    931 				if (subpassQuarterNdx == 0u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
    932 				{
    933 					const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color :
    934 											(TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.10f, 0.0) :
    935 											(TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.10f, 0.0) :
    936 											m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
    937 					for (deUint32 y = 0u; y < m_parameters.extent.height/2u; ++y)
    938 					for (deUint32 x = 0u; x < m_parameters.extent.width/2u; ++x)
    939 							referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx);
    940 				}
    941 
    942 				colorNdx += 4;
    943 				if (subpassQuarterNdx == 1u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
    944 				{
    945 					const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color :
    946 											(TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.20f, 0.0) :
    947 											(TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.20f, 0.0) :
    948 											m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
    949 					for (deUint32 y = m_parameters.extent.height/2u; y < m_parameters.extent.height; ++y)
    950 					for (deUint32 x = 0u; x < m_parameters.extent.width/2u; ++x)
    951 						referenceFrame->getLevel(0).setPixel(color , x, y, layerNdx);
    952 				}
    953 
    954 				colorNdx += 4;
    955 				if (subpassQuarterNdx == 2u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
    956 				{
    957 					const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color :
    958 											(TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.30f, 0.0) :
    959 											(TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.30f, 0.0) :
    960 											m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
    961 					for (deUint32 y = 0u; y < m_parameters.extent.height/2u; ++y)
    962 					for (deUint32 x =  m_parameters.extent.width/2u; x < m_parameters.extent.width; ++x)
    963 							referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx);
    964 				}
    965 
    966 				colorNdx += 4;
    967 				if (subpassQuarterNdx == 3u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
    968 				{
    969 					const tcu::Vec4 color = (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex) ? m_data[colorNdx].color :
    970 											(TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex) ? m_data[0].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f,  0.40f, 0.0) :
    971 											(TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? m_data[colorNdx / 4].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.40f, 0.0) :
    972 											m_data[colorNdx].color + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
    973 					for (deUint32 y =  m_parameters.extent.height/2u; y < m_parameters.extent.height; ++y)
    974 					for (deUint32 x =  m_parameters.extent.width/2u; x < m_parameters.extent.width; ++x)
    975 							referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx);
    976 				}
    977 
    978 				if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
    979 				{
    980 					const tcu::Vec4	color	(0.0f, 0.0f, 1.0f, 1.0f);
    981 					const int		maxY	= static_cast<int>(static_cast<float>(m_parameters.extent.height) * 0.75f);
    982 					const int		maxX	= static_cast<int>(static_cast<float>(m_parameters.extent.width) * 0.75f);
    983 					for (int y = static_cast<int>(m_parameters.extent.height / 4u); y < maxY; ++y)
    984 					for (int x = static_cast<int>(m_parameters.extent.width / 4u); x < maxX; ++x)
    985 						referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx);
    986 				}
    987 			}
    988 
    989 			mask = mask >> 1;
    990 			++layerNdx;
    991 		}
    992 	}
    993 	return referenceFrame;
    994 }
    995 
    996 class MultiViewAttachmentsTestInstance : public MultiViewRenderTestInstance
    997 {
    998 public:
    999 						MultiViewAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
   1000 protected:
   1001 	tcu::TestStatus		iterate								(void);
   1002 	void				beforeDraw							(void);
   1003 	void				setImageData						(VkImage image);
   1004 	de::SharedPtr<ImageAttachment>	m_inputAttachment;
   1005 	Move<VkDescriptorPool>			m_descriptorPool;
   1006 	Move<VkDescriptorSet>			m_descriptorSet;
   1007 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
   1008 	Move<VkPipelineLayout>			m_pipelineLayout;
   1009 
   1010 };
   1011 
   1012 MultiViewAttachmentsTestInstance::MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters)
   1013 	: MultiViewRenderTestInstance	(context, parameters)
   1014 {
   1015 }
   1016 
   1017 tcu::TestStatus MultiViewAttachmentsTestInstance::iterate (void)
   1018 {
   1019 	const deUint32								subpassCount			= static_cast<deUint32>(m_parameters.viewMasks.size());
   1020 	// All color attachment
   1021 	m_colorAttachment	= de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_colorFormat));
   1022 	m_inputAttachment	= de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_colorFormat));
   1023 
   1024 	// FrameBuffer & renderPass
   1025 	Unique<VkRenderPass>						renderPass				(makeRenderPassWithAttachments(*m_device, *m_logicalDevice, m_colorFormat, m_parameters.viewMasks));
   1026 
   1027 	vector<VkImageView>							attachments;
   1028 	attachments.push_back(m_colorAttachment->getImageView());
   1029 	attachments.push_back(m_inputAttachment->getImageView());
   1030 	Unique<VkFramebuffer>						frameBuffer				(makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, attachments, m_parameters.extent.width, m_parameters.extent.height, 1u));
   1031 
   1032 	// pipelineLayout
   1033 	m_descriptorSetLayout	= makeDescriptorSetLayout(*m_device, *m_logicalDevice);
   1034 	m_pipelineLayout		= makePipelineLayout(*m_device, *m_logicalDevice, &m_descriptorSetLayout.get());
   1035 
   1036 	// pipelines
   1037 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
   1038 	vector<PipelineSp>							pipelines(subpassCount);
   1039 
   1040 	{
   1041 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
   1042 		madeShaderModule(shaderModule, shaderStageParams);
   1043 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
   1044 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *m_pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
   1045 	}
   1046 
   1047 	createVertexData();
   1048 	createVertexBuffer();
   1049 
   1050 	createCommandBuffer();
   1051 	setImageData(m_inputAttachment->getImage());
   1052 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
   1053 
   1054 	{
   1055 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_colorFormat).getPixelSize());
   1056 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
   1057 
   1058 		readImage (m_colorAttachment->getImage(), dst);
   1059 		if (!checkImage(dst))
   1060 			return tcu::TestStatus::fail("Fail");
   1061 	}
   1062 
   1063 	return tcu::TestStatus::pass("Pass");
   1064 }
   1065 
   1066 void MultiViewAttachmentsTestInstance::beforeDraw (void)
   1067 {
   1068 	const VkDescriptorPoolSize poolSize =
   1069 	{
   1070 		vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
   1071 		1u
   1072 	};
   1073 
   1074 	const VkDescriptorPoolCreateInfo createInfo =
   1075 	{
   1076 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   1077 		DE_NULL,
   1078 		VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   1079 		1u,
   1080 		1u,
   1081 		&poolSize
   1082 	};
   1083 
   1084 	m_descriptorPool = createDescriptorPool(*m_device, *m_logicalDevice, &createInfo);
   1085 
   1086 	const VkDescriptorSetAllocateInfo	allocateInfo =
   1087 	{
   1088 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   1089 		DE_NULL,
   1090 		*m_descriptorPool,
   1091 		1u,
   1092 		&m_descriptorSetLayout.get()
   1093 	};
   1094 
   1095 	m_descriptorSet	= vk::allocateDescriptorSet(*m_device, *m_logicalDevice, &allocateInfo);
   1096 
   1097 	const VkDescriptorImageInfo	imageInfo =
   1098 	{
   1099 		(VkSampler)0,
   1100 		m_inputAttachment->getImageView(),
   1101 		VK_IMAGE_LAYOUT_GENERAL
   1102 	};
   1103 
   1104 	const VkWriteDescriptorSet	write =
   1105 	{
   1106 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	//VkStructureType				sType;
   1107 		DE_NULL,								//const void*					pNext;
   1108 		*m_descriptorSet,						//VkDescriptorSet				dstSet;
   1109 		0u,										//deUint32						dstBinding;
   1110 		0u,										//deUint32						dstArrayElement;
   1111 		1u,										//deUint32						descriptorCount;
   1112 		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	//VkDescriptorType				descriptorType;
   1113 		&imageInfo,								//const VkDescriptorImageInfo*	pImageInfo;
   1114 		DE_NULL,								//const VkDescriptorBufferInfo*	pBufferInfo;
   1115 		DE_NULL,								//const VkBufferView*			pTexelBufferView;
   1116 	};
   1117 
   1118 	m_device->updateDescriptorSets(*m_logicalDevice, (deUint32)1u, &write, 0u, DE_NULL);
   1119 
   1120 	const VkImageSubresourceRange	subresourceRange	=
   1121 	{
   1122 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
   1123 		0u,							//deUint32				baseMipLevel;
   1124 		1u,							//deUint32				levelCount;
   1125 		0u,							//deUint32				baseArrayLayer;
   1126 		m_parameters.extent.depth,	//deUint32				layerCount;
   1127 	};
   1128 	m_device->cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, NULL);
   1129 
   1130 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
   1131 
   1132 	const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
   1133 	m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);
   1134 
   1135 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
   1136 
   1137 	imageBarrier(*m_device, *m_cmdBuffer,  m_inputAttachment->getImage(), subresourceRange, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, 0, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
   1138 }
   1139 
   1140 void MultiViewAttachmentsTestInstance::setImageData (VkImage image)
   1141 {
   1142 	const MovePtr<tcu::Texture2DArray>		data		= imageData();
   1143 	Move<VkBuffer>					buffer;
   1144 	const deUint32					bufferSize	= m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * tcu::getPixelSize(mapVkFormat(m_colorFormat));
   1145 	MovePtr<Allocation>				bufferAlloc;
   1146 
   1147 	// Create source buffer
   1148 	{
   1149 		const VkBufferCreateInfo		bufferParams			=
   1150 		{
   1151 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   1152 			DE_NULL,									// const void*			pNext;
   1153 			0u,											// VkBufferCreateFlags	flags;
   1154 			bufferSize,									// VkDeviceSize			size;
   1155 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
   1156 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   1157 			1u,											// deUint32				queueFamilyIndexCount;
   1158 			&m_queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
   1159 		};
   1160 
   1161 		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
   1162 		bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
   1163 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
   1164 	}
   1165 
   1166 	// Barriers for copying buffer to image
   1167 	const VkBufferMemoryBarrier				preBufferBarrier		=
   1168 	{
   1169 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
   1170 		DE_NULL,										// const void*		pNext;
   1171 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
   1172 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
   1173 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
   1174 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
   1175 		*buffer,										// VkBuffer			buffer;
   1176 		0u,												// VkDeviceSize		offset;
   1177 		bufferSize										// VkDeviceSize		size;
   1178 	};
   1179 
   1180 	const VkImageAspectFlags				formatAspect			= getAspectFlags(mapVkFormat(m_colorFormat));
   1181 	VkImageSubresourceRange					subresourceRange		=
   1182 	{												// VkImageSubresourceRange	subresourceRange;
   1183 		formatAspect,				// VkImageAspectFlags	aspect;
   1184 		0u,							// deUint32				baseMipLevel;
   1185 		1u,							// deUint32				mipLevels;
   1186 		0u,							// deUint32				baseArraySlice;
   1187 		m_parameters.extent.depth,	// deUint32				arraySize;
   1188 	};
   1189 
   1190 	const VkBufferImageCopy					copyRegion				=
   1191 	{
   1192 		0u,															// VkDeviceSize				bufferOffset;
   1193 		(deUint32)data->getLevel(0).getWidth(),						// deUint32					bufferRowLength;
   1194 		(deUint32)data->getLevel(0).getHeight(),					// deUint32					bufferImageHeight;
   1195 		{
   1196 			VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags		aspect;
   1197 			0u,														// deUint32					mipLevel;
   1198 			0u,														// deUint32					baseArrayLayer;
   1199 			m_parameters.extent.depth,								// deUint32					layerCount;
   1200 		},															// VkImageSubresourceLayers	imageSubresource;
   1201 		{ 0, 0, 0 },												// VkOffset3D				imageOffset;
   1202 		{m_parameters.extent.width, m_parameters.extent.height, 1u}	// VkExtent3D				imageExtent;
   1203 	};
   1204 
   1205 	// Write buffer data
   1206 	deMemcpy(bufferAlloc->getHostPtr(), data->getLevel(0).getDataPtr(), bufferSize);
   1207 	flushMappedMemoryRange(*m_device, *m_logicalDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
   1208 
   1209 	beginCommandBuffer(*m_device, *m_cmdBuffer);
   1210 
   1211 	m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
   1212 	imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
   1213 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
   1214 	m_device->cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
   1215 	imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
   1216 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
   1217 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
   1218 
   1219 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
   1220 }
   1221 
   1222 class MultiViewInstancedTestInstance : public MultiViewRenderTestInstance
   1223 {
   1224 public:
   1225 						MultiViewInstancedTestInstance	(Context& context, const TestParameters& parameters);
   1226 protected:
   1227 	void				createVertexData				(void);
   1228 	void				draw							(const deUint32			subpassCount,
   1229 														 VkRenderPass			renderPass,
   1230 														 VkFramebuffer			frameBuffer,
   1231 														 vector<PipelineSp>&	pipelines);
   1232 };
   1233 
   1234 MultiViewInstancedTestInstance::MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters)
   1235 	: MultiViewRenderTestInstance	(context, parameters)
   1236 {
   1237 }
   1238 void MultiViewInstancedTestInstance::createVertexData (void)
   1239 {
   1240 	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
   1241 	m_data.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color));
   1242 	m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color));
   1243 	m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color));
   1244 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
   1245 }
   1246 
   1247 void MultiViewInstancedTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
   1248 {
   1249 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
   1250 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
   1251 	const VkDeviceSize				vertexBufferOffset		= 0u;
   1252 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
   1253 
   1254 	const VkRenderPassBeginInfo		renderPassBeginInfo		=
   1255 	{
   1256 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
   1257 		DE_NULL,									// const void*			pNext;
   1258 		renderPass,									// VkRenderPass			renderPass;
   1259 		frameBuffer,								// VkFramebuffer		framebuffer;
   1260 		renderArea,									// VkRect2D				renderArea;
   1261 		1u,											// uint32_t				clearValueCount;
   1262 		&renderPassClearValue,						// const VkClearValue*	pClearValues;
   1263 	};
   1264 
   1265 	beginCommandBuffer(*m_device, *m_cmdBuffer);
   1266 
   1267 	beforeDraw();
   1268 
   1269 	m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   1270 
   1271 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset);
   1272 
   1273 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
   1274 	{
   1275 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
   1276 
   1277 		m_device->cmdDraw(*m_cmdBuffer, 4u, drawCountPerSubpass, 0u, subpassNdx % m_squareCount);
   1278 
   1279 		if (subpassNdx < subpassCount - 1u)
   1280 			m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
   1281 	}
   1282 
   1283 	m_device->cmdEndRenderPass(*m_cmdBuffer);
   1284 
   1285 	afterDraw();
   1286 
   1287 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
   1288 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
   1289 }
   1290 
   1291 class MultiViewInputRateInstanceTestInstance : public MultiViewRenderTestInstance
   1292 {
   1293 public:
   1294 				MultiViewInputRateInstanceTestInstance	(Context& context, const TestParameters& parameters);
   1295 protected:
   1296 	void		createVertexData						(void);
   1297 	void		draw									(const deUint32			subpassCount,
   1298 														 VkRenderPass			renderPass,
   1299 														 VkFramebuffer			frameBuffer,
   1300 														 vector<PipelineSp>&	pipelines);
   1301 };
   1302 
   1303 MultiViewInputRateInstanceTestInstance::MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters)
   1304 	: MultiViewRenderTestInstance	(context, parameters)
   1305 {
   1306 }
   1307 
   1308 void MultiViewInputRateInstanceTestInstance::createVertexData (void)
   1309 {
   1310 	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
   1311 	m_data.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color));
   1312 
   1313 	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
   1314 	m_data.push_back(VertexData(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color));
   1315 
   1316 	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
   1317 	m_data.push_back(VertexData(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color));
   1318 
   1319 	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
   1320 	m_data.push_back(VertexData(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color));
   1321 }
   1322 
   1323 void MultiViewInputRateInstanceTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
   1324 {
   1325 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
   1326 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
   1327 	const VkDeviceSize				vertexBufferOffset		= 0u;
   1328 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
   1329 
   1330 	const VkRenderPassBeginInfo		renderPassBeginInfo		=
   1331 	{
   1332 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
   1333 		DE_NULL,									// const void*			pNext;
   1334 		renderPass,									// VkRenderPass			renderPass;
   1335 		frameBuffer,								// VkFramebuffer		framebuffer;
   1336 		renderArea,									// VkRect2D				renderArea;
   1337 		1u,											// uint32_t				clearValueCount;
   1338 		&renderPassClearValue,						// const VkClearValue*	pClearValues;
   1339 	};
   1340 
   1341 	beginCommandBuffer(*m_device, *m_cmdBuffer);
   1342 
   1343 	beforeDraw();
   1344 
   1345 	m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   1346 
   1347 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset);
   1348 
   1349 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
   1350 	{
   1351 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
   1352 
   1353 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
   1354 			m_device->cmdDraw(*m_cmdBuffer, 4u, 4u, 0u, 0u);
   1355 
   1356 		if (subpassNdx < subpassCount - 1u)
   1357 			m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
   1358 	}
   1359 
   1360 	m_device->cmdEndRenderPass(*m_cmdBuffer);
   1361 
   1362 	afterDraw();
   1363 
   1364 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
   1365 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
   1366 }
   1367 
   1368 class MultiViewIDrawIndirectTestInstance : public MultiViewRenderTestInstance
   1369 {
   1370 public:
   1371 				MultiViewIDrawIndirectTestInstance	(Context& context, const TestParameters& parameters);
   1372 protected:
   1373 	void		draw									(const deUint32			subpassCount,
   1374 														 VkRenderPass			renderPass,
   1375 														 VkFramebuffer			frameBuffer,
   1376 														 vector<PipelineSp>&	pipelines);
   1377 };
   1378 
   1379 MultiViewIDrawIndirectTestInstance::MultiViewIDrawIndirectTestInstance (Context& context, const TestParameters& parameters)
   1380 	: MultiViewRenderTestInstance	(context, parameters)
   1381 {
   1382 }
   1383 
   1384 void MultiViewIDrawIndirectTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
   1385 {
   1386 	typedef de::SharedPtr<Unique<VkBuffer> >		BufferSP;
   1387 	typedef de::SharedPtr<UniquePtr<Allocation> >	AllocationSP;
   1388 
   1389 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
   1390 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
   1391 	const VkDeviceSize				vertexBufferOffset		= 0u;
   1392 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
   1393 	vector< BufferSP >				indirectBuffers(subpassCount);
   1394 	vector< AllocationSP >			indirectAllocations(subpassCount);
   1395 	deUint32						strideInBuffer = (deUint32)sizeof(vk::VkDrawIndirectCommand);
   1396 
   1397 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
   1398 	{
   1399 		vector<VkDrawIndirectCommand>	drawCommands;
   1400 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
   1401 		{
   1402 			const VkDrawIndirectCommand	drawCommand =
   1403 			{
   1404 				4u,												//deUint32	vertexCount;
   1405 				1u,												//deUint32	instanceCount;
   1406 				(drawNdx + subpassNdx % m_squareCount) * 4u,	//deUint32	firstVertex;
   1407 				0u												//deUint32	firstInstance;
   1408 			};
   1409 			drawCommands.push_back(drawCommand);
   1410 		}
   1411 
   1412 		const VkDeviceSize			bufferSize			=	static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>(drawCommands.size() * strideInBuffer),
   1413 															static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
   1414 		const VkBufferCreateInfo	bufferInfo			= makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
   1415 		Move<VkBuffer>				indirectBuffer		= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
   1416 		MovePtr<Allocation>			allocationBuffer	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexBuffer),  MemoryRequirement::HostVisible);
   1417 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *indirectBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset()));
   1418 
   1419 		deMemcpy(allocationBuffer->getHostPtr(), &drawCommands[0], static_cast<size_t>(bufferSize));
   1420 
   1421 		flushMappedMemoryRange(*m_device, *m_logicalDevice, allocationBuffer->getMemory(), allocationBuffer->getOffset(), static_cast<size_t>(bufferSize));
   1422 		indirectBuffers[subpassNdx] = (BufferSP(new Unique<VkBuffer>(indirectBuffer)));
   1423 		indirectAllocations[subpassNdx] = (AllocationSP(new UniquePtr<Allocation>(allocationBuffer)));
   1424 	}
   1425 
   1426 	const VkRenderPassBeginInfo		renderPassBeginInfo		=
   1427 	{
   1428 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
   1429 		DE_NULL,									// const void*			pNext;
   1430 		renderPass,									// VkRenderPass			renderPass;
   1431 		frameBuffer,								// VkFramebuffer		framebuffer;
   1432 		renderArea,									// VkRect2D				renderArea;
   1433 		1u,											// uint32_t				clearValueCount;
   1434 		&renderPassClearValue,						// const VkClearValue*	pClearValues;
   1435 	};
   1436 
   1437 	beginCommandBuffer(*m_device, *m_cmdBuffer);
   1438 
   1439 	beforeDraw();
   1440 
   1441 	m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   1442 
   1443 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset);
   1444 
   1445 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
   1446 	{
   1447 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
   1448 
   1449 		if (m_hasMultiDrawIndirect)
   1450 		{
   1451 			m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer);
   1452 		}
   1453 		else
   1454 		{
   1455 			for (deUint32 drawNdx = 0; drawNdx < drawCountPerSubpass; drawNdx++)
   1456 			{
   1457 				m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer);
   1458 			}
   1459 		}
   1460 
   1461 		if (subpassNdx < subpassCount - 1u)
   1462 			m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
   1463 	}
   1464 
   1465 	m_device->cmdEndRenderPass(*m_cmdBuffer);
   1466 
   1467 	afterDraw();
   1468 
   1469 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
   1470 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
   1471 }
   1472 
   1473 class MultiViewClearAttachmentsTestInstance : public MultiViewRenderTestInstance
   1474 {
   1475 public:
   1476 				MultiViewClearAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
   1477 protected:
   1478 	void		draw									(const deUint32			subpassCount,
   1479 														 VkRenderPass			renderPass,
   1480 														 VkFramebuffer			frameBuffer,
   1481 														 vector<PipelineSp>&	pipelines);
   1482 };
   1483 
   1484 MultiViewClearAttachmentsTestInstance::MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters)
   1485 	: MultiViewRenderTestInstance	(context, parameters)
   1486 {
   1487 }
   1488 
   1489 void MultiViewClearAttachmentsTestInstance::draw (const deUint32 subpassCount,VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
   1490 {
   1491 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
   1492 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
   1493 	const VkDeviceSize				vertexBufferOffset		= 0u;
   1494 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
   1495 
   1496 	const VkRenderPassBeginInfo		renderPassBeginInfo		=
   1497 	{
   1498 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
   1499 		DE_NULL,									// const void*			pNext;
   1500 		renderPass,									// VkRenderPass			renderPass;
   1501 		frameBuffer,								// VkFramebuffer		framebuffer;
   1502 		renderArea,									// VkRect2D				renderArea;
   1503 		1u,											// uint32_t				clearValueCount;
   1504 		&renderPassClearValue,						// const VkClearValue*	pClearValues;
   1505 	};
   1506 
   1507 	beginCommandBuffer(*m_device, *m_cmdBuffer);
   1508 
   1509 	beforeDraw();
   1510 
   1511 	m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   1512 
   1513 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset);
   1514 
   1515 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
   1516 	{
   1517 		VkClearAttachment	clearAttachment	=
   1518 		{
   1519 			VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspectMask
   1520 			0u,														// deUint32				colorAttachment
   1521 			makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f))	// VkClearValue			clearValue
   1522 		};
   1523 
   1524 		const VkOffset2D	offset[2]		=
   1525 		{
   1526 			{0, 0},
   1527 			{static_cast<deInt32>(static_cast<float>(m_parameters.extent.width) * 0.25f), static_cast<deInt32>(static_cast<float>(m_parameters.extent.height) * 0.25f)}
   1528 		};
   1529 
   1530 		const VkExtent2D	extent[2]		=
   1531 		{
   1532 			{m_parameters.extent.width, m_parameters.extent.height},
   1533 			{static_cast<deUint32>(static_cast<float>(m_parameters.extent.width) * 0.5f), static_cast<deUint32>(static_cast<float>(m_parameters.extent.height) * 0.5f)}
   1534 		};
   1535 
   1536 		const VkRect2D		rect2D[2]		=
   1537 		{
   1538 			{offset[0], extent[0]},
   1539 			{offset[1], extent[1]}
   1540 		};
   1541 
   1542 		VkClearRect			clearRect		=
   1543 		{
   1544 			rect2D[0],	// VkRect2D	rect
   1545 			0u,			// deUint32	baseArrayLayer
   1546 			1u,			// deUint32	layerCount
   1547 		};
   1548 
   1549 		m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);
   1550 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
   1551 
   1552 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
   1553 			m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
   1554 
   1555 		clearRect.rect = rect2D[1];
   1556 		clearAttachment.clearValue = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
   1557 		m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);
   1558 
   1559 		if (subpassNdx < subpassCount - 1u)
   1560 			m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
   1561 	}
   1562 
   1563 	m_device->cmdEndRenderPass(*m_cmdBuffer);
   1564 
   1565 	afterDraw();
   1566 
   1567 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
   1568 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
   1569 }
   1570 
   1571 
   1572 class MultiViewSecondaryCommandBufferTestInstance : public MultiViewRenderTestInstance
   1573 {
   1574 public:
   1575 				MultiViewSecondaryCommandBufferTestInstance	(Context& context, const TestParameters& parameters);
   1576 protected:
   1577 	void		draw										(const deUint32			subpassCount,
   1578 															 VkRenderPass			renderPass,
   1579 															 VkFramebuffer			frameBuffer,
   1580 															 vector<PipelineSp>&	pipelines);
   1581 };
   1582 
   1583 MultiViewSecondaryCommandBufferTestInstance::MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters)
   1584 	: MultiViewRenderTestInstance	(context, parameters)
   1585 {
   1586 }
   1587 
   1588 void MultiViewSecondaryCommandBufferTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
   1589 {
   1590 	typedef de::SharedPtr<Unique<VkCommandBuffer> >	VkCommandBufferSp;
   1591 
   1592 	const VkRect2D						renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
   1593 	const VkClearValue					renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
   1594 	const VkDeviceSize					vertexBufferOffset		= 0u;
   1595 	const deUint32						drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
   1596 
   1597 	const VkRenderPassBeginInfo			renderPassBeginInfo		=
   1598 	{
   1599 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
   1600 		DE_NULL,									// const void*			pNext;
   1601 		renderPass,									// VkRenderPass			renderPass;
   1602 		frameBuffer,								// VkFramebuffer		framebuffer;
   1603 		renderArea,									// VkRect2D				renderArea;
   1604 		1u,											// uint32_t				clearValueCount;
   1605 		&renderPassClearValue,						// const VkClearValue*	pClearValues;
   1606 	};
   1607 
   1608 	beginCommandBuffer(*m_device, *m_cmdBuffer);
   1609 
   1610 	beforeDraw();
   1611 
   1612 	m_device->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   1613 
   1614 	//Create secondary buffer
   1615 	const VkCommandBufferAllocateInfo	cmdBufferAllocateInfo	=
   1616 	{
   1617 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
   1618 		DE_NULL,										// const void*				pNext;
   1619 		*m_cmdPool,										// VkCommandPool			commandPool;
   1620 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,				// VkCommandBufferLevel		level;
   1621 		1u,												// deUint32					bufferCount;
   1622 	};
   1623 	vector<VkCommandBufferSp>	cmdBufferSecondary;
   1624 
   1625 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
   1626 	{
   1627 		cmdBufferSecondary.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo))));
   1628 
   1629 		beginSecondaryCommandBuffer(*m_device, cmdBufferSecondary.back().get()->get(), renderPass, subpassNdx, frameBuffer);
   1630 		m_device->cmdBindVertexBuffers(cmdBufferSecondary.back().get()->get(), 0u, 1u, &(*m_vertexBuffer), &vertexBufferOffset);
   1631 		m_device->cmdBindPipeline(cmdBufferSecondary.back().get()->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
   1632 
   1633 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
   1634 			m_device->cmdDraw(cmdBufferSecondary.back().get()->get(), 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
   1635 
   1636 		VK_CHECK(m_device->endCommandBuffer(cmdBufferSecondary.back().get()->get()));
   1637 
   1638 		m_device->cmdExecuteCommands(*m_cmdBuffer, 1u, &cmdBufferSecondary.back().get()->get());
   1639 		if (subpassNdx < subpassCount - 1u)
   1640 			m_device->cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   1641 	}
   1642 
   1643 	m_device->cmdEndRenderPass(*m_cmdBuffer);
   1644 
   1645 	afterDraw();
   1646 
   1647 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
   1648 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
   1649 }
   1650 
   1651 class MultiViewRenderTestsCase : public vkt::TestCase
   1652 {
   1653 public:
   1654 	MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
   1655 		: TestCase			(context, name, description)
   1656 		, m_parameters		(parameters)
   1657 	{
   1658 	}
   1659 private:
   1660 	const TestParameters	m_parameters;
   1661 
   1662 	vkt::TestInstance*	createInstance		(vkt::Context& context) const
   1663 	{
   1664 		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex)
   1665 			return new MultiViewAttachmentsTestInstance(context, m_parameters);
   1666 
   1667 		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
   1668 			return new MultiViewInstancedTestInstance(context, m_parameters);
   1669 
   1670 		if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
   1671 			return new MultiViewInputRateInstanceTestInstance(context, m_parameters);
   1672 
   1673 		if (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex)
   1674 			return new	MultiViewIDrawIndirectTestInstance(context, m_parameters);
   1675 
   1676 		if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
   1677 			return new	MultiViewClearAttachmentsTestInstance(context, m_parameters);
   1678 
   1679 		if (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex)
   1680 			return new	MultiViewSecondaryCommandBufferTestInstance(context, m_parameters);
   1681 
   1682 		return new MultiViewRenderTestInstance(context, m_parameters);
   1683 	}
   1684 
   1685 	void				initPrograms		(SourceCollections& programCollection) const
   1686 	{
   1687 		// Create vertex shader
   1688 		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
   1689 		{
   1690 			std::ostringstream source;
   1691 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
   1692 					<< "#extension GL_EXT_multiview : enable\n"
   1693 					<< "layout(location = 0) in highp vec4 in_position;\n"
   1694 					<< "layout(location = 1) in vec4 in_color;\n"
   1695 					<< "layout(location = 0) out vec4 out_color;\n"
   1696 					<< "void main (void)\n"
   1697 					<< "{\n"
   1698 					<< "	int modInstance = gl_InstanceIndex % 4;\n"
   1699 					<< "	int instance    = gl_InstanceIndex + 1;\n"
   1700 					<< "	gl_Position = in_position;\n"
   1701 					<< "	if (modInstance == 1)\n"
   1702 					<< "		gl_Position = in_position + vec4(0.0f, 1.0f, 0.0f, 0.0f);\n"
   1703 					<< "	if (modInstance == 2)\n"
   1704 					<< "		gl_Position = in_position + vec4(1.0f, 0.0f, 0.0f, 0.0f);\n"
   1705 					<< "	if (modInstance == 3)\n"
   1706 					<< "		gl_Position =  in_position + vec4(1.0f, 1.0f, 0.0f, 0.0f);\n"
   1707 					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
   1708 					<< "}\n";
   1709 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
   1710 		}
   1711 		else if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
   1712 		{
   1713 			std::ostringstream source;
   1714 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
   1715 					<< "#extension GL_EXT_multiview : enable\n"
   1716 					<< "layout(location = 0) in highp vec4 in_position;\n"
   1717 					<< "layout(location = 1) in vec4 in_color;\n"
   1718 					<< "layout(location = 0) out vec4 out_color;\n"
   1719 					<< "void main (void)\n"
   1720 					<< "{\n"
   1721 					<< "	int instance = gl_InstanceIndex + 1;\n"
   1722 					<< "	gl_Position = in_position;\n"
   1723 					<< "	if (gl_VertexIndex == 1)\n"
   1724 					<< "		gl_Position.y += 1.0f;\n"
   1725 					<< "	else if (gl_VertexIndex == 2)\n"
   1726 					<< "		gl_Position.x += 1.0f;\n"
   1727 					<< "	else if (gl_VertexIndex == 3)\n"
   1728 					<< "	{\n"
   1729 					<< "		gl_Position.x += 1.0f;\n"
   1730 					<< "		gl_Position.y += 1.0f;\n"
   1731 					<< "	}\n"
   1732 					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
   1733 					<< "}\n";
   1734 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
   1735 		}
   1736 		else
   1737 		{
   1738 			std::ostringstream source;
   1739 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
   1740 					<< "#extension GL_EXT_multiview : enable\n"
   1741 					<< "layout(location = 0) in highp vec4 in_position;\n"
   1742 					<< "layout(location = 1) in vec4 in_color;\n"
   1743 					<< "layout(location = 0) out vec4 out_color;\n"
   1744 					<< "void main (void)\n"
   1745 					<< "{\n"
   1746 					<< "	gl_Position = in_position;\n";
   1747 				if (TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex || TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex)
   1748 					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
   1749 				else
   1750 					source << "	out_color = in_color;\n";
   1751 			source	<< "}\n";
   1752 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
   1753 		}
   1754 
   1755 		if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)
   1756 		{// Tessellation control & evaluation
   1757 			std::ostringstream source_tc;
   1758 			source_tc	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
   1759 						<< "#extension GL_EXT_multiview : enable\n"
   1760 						<< "#extension GL_EXT_tessellation_shader : require\n"
   1761 						<< "layout(vertices = 4) out;\n"
   1762 						<< "layout(location = 0) in vec4 in_color[];\n"
   1763 						<< "layout(location = 0) out vec4 out_color[];\n"
   1764 						<< "\n"
   1765 						<< "void main (void)\n"
   1766 						<< "{\n"
   1767 						<< "	if ( gl_InvocationID == 0 )\n"
   1768 						<< "	{\n"
   1769 						<< "		gl_TessLevelInner[0] = 4.0f;\n"
   1770 						<< "		gl_TessLevelInner[1] = 4.0f;\n"
   1771 						<< "		gl_TessLevelOuter[0] = 4.0f;\n"
   1772 						<< "		gl_TessLevelOuter[1] = 4.0f;\n"
   1773 						<< "		gl_TessLevelOuter[2] = 4.0f;\n"
   1774 						<< "		gl_TessLevelOuter[3] = 4.0f;\n"
   1775 						<< "	}\n"
   1776 						<< "	out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
   1777 						<< "	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
   1778 						<< "}\n";
   1779 			programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str());
   1780 
   1781 			std::ostringstream source_te;
   1782 			source_te	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
   1783 						<< "#extension GL_EXT_multiview : enable\n"
   1784 						<< "#extension GL_EXT_tessellation_shader : require\n"
   1785 						<< "layout( quads, equal_spacing, ccw ) in;\n"
   1786 						<< "layout(location = 0) in vec4 in_color[];\n"
   1787 						<< "layout(location = 0) out vec4 out_color;\n"
   1788 						<< "void main (void)\n"
   1789 						<< "{\n"
   1790 						<< "	const float u = gl_TessCoord.x;\n"
   1791 						<< "	const float v = gl_TessCoord.y;\n"
   1792 						<< "	const float w = gl_TessCoord.z;\n"
   1793 						<< "	gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n"
   1794 						<< "	out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
   1795 						<< "}\n";
   1796 			programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str());
   1797 		}
   1798 
   1799 		if (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY	== m_parameters.viewIndex ||
   1800 			TEST_TYPE_INPUT_ATTACHMENTS			== m_parameters.viewIndex ||
   1801 			TEST_TYPE_CLEAR_ATTACHMENTS			== m_parameters.viewIndex ||
   1802 			TEST_TYPE_SECONDARY_CMD_BUFFER		== m_parameters.viewIndex)
   1803 		{// Geometry Shader
   1804 			std::ostringstream	source;
   1805 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
   1806 					<< "#extension GL_EXT_multiview : enable\n"
   1807 					<< "layout(triangles) in;\n"
   1808 					<< "layout(triangle_strip, max_vertices = 16) out;\n"
   1809 					<< "layout(location = 0) in vec4 in_color[];\n"
   1810 					<< "layout(location = 0) out vec4 out_color;\n"
   1811 					<< "void main (void)\n"
   1812 					<< "{\n"
   1813 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
   1814 					<< "	gl_Position = gl_in[0].gl_Position;\n"
   1815 					<< "	EmitVertex();\n"
   1816 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
   1817 					<< "	gl_Position = gl_in[1].gl_Position;\n"
   1818 					<< "	EmitVertex();\n"
   1819 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
   1820 					<< "	gl_Position = gl_in[2].gl_Position;\n"
   1821 					<< "	EmitVertex();\n"
   1822 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
   1823 					<< "	gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
   1824 					<< "	EmitVertex();\n"
   1825 					<< "	EndPrimitive();\n"
   1826 					<< "}\n";
   1827 			programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str());
   1828 		}
   1829 
   1830 		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex)
   1831 		{// Create fragment shader read/write attachment
   1832 			std::ostringstream source;
   1833 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
   1834 					<< "#extension GL_EXT_multiview : enable\n"
   1835 					<< "layout(location = 0) in vec4 in_color;\n"
   1836 					<< "layout(location = 0) out vec4 out_color;\n"
   1837 					<< "layout(input_attachment_index = 0, set=0, binding=0) uniform highp subpassInput in_color_attachment;\n"
   1838 					<< "void main()\n"
   1839 					<<"{\n"
   1840 					<< "	out_color = vec4(subpassLoad(in_color_attachment));\n"
   1841 					<< "}\n";
   1842 			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
   1843 		}
   1844 		else
   1845 		{// Create fragment shader
   1846 			std::ostringstream source;
   1847 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
   1848 					<< "#extension GL_EXT_multiview : enable\n"
   1849 					<< "layout(location = 0) in vec4 in_color;\n"
   1850 					<< "layout(location = 0) out vec4 out_color;\n"
   1851 					<< "void main()\n"
   1852 					<<"{\n";
   1853 				if (TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex)
   1854 					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
   1855 				else
   1856 					source << "	out_color = in_color;\n";
   1857 			source	<< "}\n";
   1858 			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
   1859 		}
   1860 	}
   1861 };
   1862 } //anonymous
   1863 
   1864 void multiViewRenderCreateTests (tcu::TestCaseGroup* group)
   1865 {
   1866 	tcu::TestContext&			testCtx						= group->getTestContext();
   1867 	const deUint32				testCaseCount				= 6u;
   1868 	MovePtr<tcu::TestCaseGroup>	groupViewIndex				(new tcu::TestCaseGroup(testCtx, "index", "ViewIndex rendering tests."));
   1869 	const string				shaderName[TEST_TYPE_LAST]	=
   1870 	{
   1871 		"masks",
   1872 		"vertex_shader",
   1873 		"fragment_shader",
   1874 		"geometry_shader",
   1875 		"tesellation_shader",
   1876 		"input_attachments",
   1877 		"instanced",
   1878 		"input_instance",
   1879 		"draw_indirect",
   1880 		"clear_attachments",
   1881 		"secondary_cmd_buffer"
   1882 	};
   1883 	const VkExtent3D			extent3D[testCaseCount]		=
   1884 	{
   1885 		{16u,	16u,	4u},
   1886 		{64u,	64u,	8u},
   1887 		{128u,	128u,	4u},
   1888 		{32u,	32u,	5u},
   1889 		{64u,	64u,	6u},
   1890 		{16u,	16u,	10u},
   1891 	};
   1892 	vector<deUint32>			viewMasks[testCaseCount];
   1893 
   1894 	viewMasks[0].push_back(15u);	//1111
   1895 
   1896 	viewMasks[1].push_back(8u);		//1000
   1897 
   1898 	viewMasks[2].push_back(1u);		//0001
   1899 	viewMasks[2].push_back(2u);		//0010
   1900 	viewMasks[2].push_back(4u);		//0100
   1901 	viewMasks[2].push_back(8u);		//1000
   1902 
   1903 	viewMasks[3].push_back(15u);	//1111
   1904 	viewMasks[3].push_back(15u);	//1111
   1905 	viewMasks[3].push_back(15u);	//1111
   1906 	viewMasks[3].push_back(15u);	//1111
   1907 
   1908 	viewMasks[4].push_back(8u);		//1000
   1909 	viewMasks[4].push_back(1u);		//0001
   1910 	viewMasks[4].push_back(1u);		//0001
   1911 	viewMasks[4].push_back(8u);		//1000
   1912 
   1913 	const deUint32 minSupportedMultiviewViewCount	= 6u;
   1914 	const deUint32 maxViewMask						= (1u << minSupportedMultiviewViewCount) - 1u;
   1915 
   1916 	for (deUint32 mask = 1u; mask <= maxViewMask; mask = mask << 1u)
   1917 		viewMasks[5].push_back(mask);
   1918 
   1919 	for (int testTypeNdx = TEST_TYPE_VIEW_MASK; testTypeNdx < TEST_TYPE_LAST; ++testTypeNdx)
   1920 	{
   1921 		MovePtr<tcu::TestCaseGroup>	groupShader	(new tcu::TestCaseGroup(testCtx, shaderName[testTypeNdx].c_str(), ""));
   1922 		for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx)
   1923 		{
   1924 			const TestParameters	parameters		=	{extent3D[testCaseNdx], viewMasks[testCaseNdx], (TestType)testTypeNdx};
   1925 			std::ostringstream		masks;
   1926 			const deUint32			viewMaksSize	=	static_cast<deUint32>(viewMasks[testCaseNdx].size());
   1927 
   1928 			for (deUint32 ndx = 0u; ndx < viewMaksSize; ++ndx)
   1929 			{
   1930 				masks<<viewMasks[testCaseNdx][ndx];
   1931 				if (viewMaksSize - 1 != ndx)
   1932 					masks<<"_";
   1933 			}
   1934 			groupShader->addChild(new MultiViewRenderTestsCase(testCtx, masks.str().c_str(), "", parameters));
   1935 		}
   1936 
   1937 		// maxMultiviewViewCount case
   1938 		{
   1939 			const VkExtent3D		incompleteExtent3D	= { 16u, 16u, 0u };
   1940 			const vector<deUint32>	dummyMasks;
   1941 			const TestParameters	parameters			= { incompleteExtent3D, dummyMasks, (TestType)testTypeNdx };
   1942 
   1943 			groupShader->addChild(new MultiViewRenderTestsCase(testCtx, "max_multi_view_view_count", "", parameters));
   1944 		}
   1945 
   1946 		switch (testTypeNdx)
   1947 		{
   1948 			case TEST_TYPE_VIEW_MASK:
   1949 			case TEST_TYPE_INPUT_ATTACHMENTS:
   1950 			case TEST_TYPE_INSTANCED_RENDERING:
   1951 			case TEST_TYPE_INPUT_RATE_INSTANCE:
   1952 			case TEST_TYPE_DRAW_INDIRECT:
   1953 			case TEST_TYPE_CLEAR_ATTACHMENTS:
   1954 			case TEST_TYPE_SECONDARY_CMD_BUFFER:
   1955 				group->addChild(groupShader.release());
   1956 				break;
   1957 			case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
   1958 			case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
   1959 			case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
   1960 			case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
   1961 				groupViewIndex->addChild(groupShader.release());
   1962 				break;
   1963 			default:
   1964 				DE_ASSERT(0);
   1965 				break;
   1966 		};
   1967 	}
   1968 
   1969 	group->addChild(groupViewIndex.release());
   1970 }
   1971 
   1972 } //MultiView
   1973 } //vkt
   1974 
   1975