Home | History | Annotate | Download | only in vulkan
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 Google 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 RenderPass tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktRenderPassTests.hpp"
     25 
     26 #include "vktTestCaseUtil.hpp"
     27 #include "vktTestGroupUtil.hpp"
     28 
     29 #include "vkDefs.hpp"
     30 #include "vkDeviceUtil.hpp"
     31 #include "vkImageUtil.hpp"
     32 #include "vkMemUtil.hpp"
     33 #include "vkPlatform.hpp"
     34 #include "vkPrograms.hpp"
     35 #include "vkQueryUtil.hpp"
     36 #include "vkRef.hpp"
     37 #include "vkRefUtil.hpp"
     38 #include "vkStrUtil.hpp"
     39 #include "vkTypeUtil.hpp"
     40 
     41 #include "tcuFloat.hpp"
     42 #include "tcuFormatUtil.hpp"
     43 #include "tcuMaybe.hpp"
     44 #include "tcuResultCollector.hpp"
     45 #include "tcuTestLog.hpp"
     46 #include "tcuTextureUtil.hpp"
     47 #include "tcuVectorUtil.hpp"
     48 
     49 #include "deRandom.hpp"
     50 #include "deSTLUtil.hpp"
     51 #include "deSharedPtr.hpp"
     52 #include "deStringUtil.hpp"
     53 #include "deUniquePtr.hpp"
     54 
     55 #include <limits>
     56 #include <set>
     57 #include <string>
     58 #include <vector>
     59 
     60 using namespace vk;
     61 
     62 using tcu::BVec4;
     63 using tcu::IVec2;
     64 using tcu::IVec4;
     65 using tcu::UVec2;
     66 using tcu::UVec4;
     67 using tcu::Vec2;
     68 using tcu::Vec4;
     69 
     70 using tcu::Maybe;
     71 using tcu::just;
     72 using tcu::nothing;
     73 
     74 using tcu::ConstPixelBufferAccess;
     75 using tcu::PixelBufferAccess;
     76 
     77 using tcu::TestLog;
     78 
     79 using de::UniquePtr;
     80 
     81 using std::pair;
     82 using std::set;
     83 using std::string;
     84 using std::vector;
     85 
     86 namespace vkt
     87 {
     88 namespace
     89 {
     90 enum BoolOp
     91 {
     92 	BOOLOP_AND,
     93 	BOOLOP_OR,
     94 	BOOLOP_EQ,
     95 	BOOLOP_NEQ
     96 };
     97 
     98 const char* boolOpToString (BoolOp op)
     99 {
    100 	switch (op)
    101 	{
    102 		case BOOLOP_OR:
    103 			return "||";
    104 
    105 		case BOOLOP_AND:
    106 			return "&&";
    107 
    108 		case BOOLOP_EQ:
    109 			return "==";
    110 
    111 		case BOOLOP_NEQ:
    112 			return "!=";
    113 
    114 		default:
    115 			DE_FATAL("Unknown boolean operation.");
    116 			return DE_NULL;
    117 	}
    118 }
    119 
    120 bool performBoolOp (BoolOp op, bool a, bool b)
    121 {
    122 	switch (op)
    123 	{
    124 		case BOOLOP_OR:
    125 			return a || b;
    126 
    127 		case BOOLOP_AND:
    128 			return a && b;
    129 
    130 		case BOOLOP_EQ:
    131 			return a == b;
    132 
    133 		case BOOLOP_NEQ:
    134 			return a != b;
    135 
    136 		default:
    137 			DE_FATAL("Unknown boolean operation.");
    138 			return false;
    139 	}
    140 }
    141 
    142 BoolOp boolOpFromIndex (size_t index)
    143 {
    144 	const BoolOp ops[] =
    145 	{
    146 		BOOLOP_OR,
    147 		BOOLOP_AND,
    148 		BOOLOP_EQ,
    149 		BOOLOP_NEQ
    150 	};
    151 
    152 	return ops[index % DE_LENGTH_OF_ARRAY(ops)];
    153 }
    154 
    155 // Utility functions using flattened structs
    156 Move<VkFence> createFence (const DeviceInterface& vk, VkDevice device, VkFenceCreateFlags flags)
    157 {
    158 	const VkFenceCreateInfo pCreateInfo =
    159 	{
    160 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
    161 		DE_NULL,
    162 
    163 		flags
    164 	};
    165 	return createFence(vk, device, &pCreateInfo);
    166 }
    167 
    168 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&	vk,
    169 									   VkDevice					device,
    170 									   VkFramebufferCreateFlags	pCreateInfo_flags,
    171 									   VkRenderPass				pCreateInfo_renderPass,
    172 									   deUint32					pCreateInfo_attachmentCount,
    173 									   const VkImageView*		pCreateInfo_pAttachments,
    174 									   deUint32					pCreateInfo_width,
    175 									   deUint32					pCreateInfo_height,
    176 									   deUint32					pCreateInfo_layers)
    177 {
    178 	const VkFramebufferCreateInfo pCreateInfo =
    179 	{
    180 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
    181 		DE_NULL,
    182 		pCreateInfo_flags,
    183 		pCreateInfo_renderPass,
    184 		pCreateInfo_attachmentCount,
    185 		pCreateInfo_pAttachments,
    186 		pCreateInfo_width,
    187 		pCreateInfo_height,
    188 		pCreateInfo_layers,
    189 	};
    190 	return createFramebuffer(vk, device, &pCreateInfo);
    191 }
    192 
    193 Move<VkImage> createImage (const DeviceInterface&	vk,
    194 						   VkDevice					device,
    195 						   VkImageCreateFlags		pCreateInfo_flags,
    196 						   VkImageType				pCreateInfo_imageType,
    197 						   VkFormat					pCreateInfo_format,
    198 						   VkExtent3D				pCreateInfo_extent,
    199 						   deUint32					pCreateInfo_mipLevels,
    200 						   deUint32					pCreateInfo_arrayLayers,
    201 						   VkSampleCountFlagBits	pCreateInfo_samples,
    202 						   VkImageTiling			pCreateInfo_tiling,
    203 						   VkImageUsageFlags		pCreateInfo_usage,
    204 						   VkSharingMode			pCreateInfo_sharingMode,
    205 						   deUint32					pCreateInfo_queueFamilyCount,
    206 						   const deUint32*			pCreateInfo_pQueueFamilyIndices,
    207 						   VkImageLayout			pCreateInfo_initialLayout)
    208 {
    209 	const VkImageCreateInfo pCreateInfo =
    210 	{
    211 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
    212 		DE_NULL,
    213 		pCreateInfo_flags,
    214 		pCreateInfo_imageType,
    215 		pCreateInfo_format,
    216 		pCreateInfo_extent,
    217 		pCreateInfo_mipLevels,
    218 		pCreateInfo_arrayLayers,
    219 		pCreateInfo_samples,
    220 		pCreateInfo_tiling,
    221 		pCreateInfo_usage,
    222 		pCreateInfo_sharingMode,
    223 		pCreateInfo_queueFamilyCount,
    224 		pCreateInfo_pQueueFamilyIndices,
    225 		pCreateInfo_initialLayout
    226 	};
    227 	return createImage(vk, device, &pCreateInfo);
    228 }
    229 
    230 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
    231 {
    232 	VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
    233 }
    234 
    235 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
    236 {
    237 	VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
    238 }
    239 
    240 Move<VkImageView> createImageView (const DeviceInterface&	vk,
    241 									VkDevice				device,
    242 									VkImageViewCreateFlags	pCreateInfo_flags,
    243 									VkImage					pCreateInfo_image,
    244 									VkImageViewType			pCreateInfo_viewType,
    245 									VkFormat				pCreateInfo_format,
    246 									VkComponentMapping		pCreateInfo_components,
    247 									VkImageSubresourceRange	pCreateInfo_subresourceRange)
    248 {
    249 	const VkImageViewCreateInfo pCreateInfo =
    250 	{
    251 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
    252 		DE_NULL,
    253 		pCreateInfo_flags,
    254 		pCreateInfo_image,
    255 		pCreateInfo_viewType,
    256 		pCreateInfo_format,
    257 		pCreateInfo_components,
    258 		pCreateInfo_subresourceRange,
    259 	};
    260 	return createImageView(vk, device, &pCreateInfo);
    261 }
    262 
    263 Move<VkBuffer> createBuffer (const DeviceInterface&	vk,
    264 							 VkDevice				device,
    265 							 VkBufferCreateFlags	pCreateInfo_flags,
    266 							 VkDeviceSize			pCreateInfo_size,
    267 							 VkBufferUsageFlags		pCreateInfo_usage,
    268 							 VkSharingMode			pCreateInfo_sharingMode,
    269 							 deUint32				pCreateInfo_queueFamilyCount,
    270 							 const deUint32*		pCreateInfo_pQueueFamilyIndices)
    271 {
    272 	const VkBufferCreateInfo pCreateInfo =
    273 	{
    274 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
    275 		DE_NULL,
    276 		pCreateInfo_flags,
    277 		pCreateInfo_size,
    278 		pCreateInfo_usage,
    279 		pCreateInfo_sharingMode,
    280 		pCreateInfo_queueFamilyCount,
    281 		pCreateInfo_pQueueFamilyIndices,
    282 	};
    283 	return createBuffer(vk, device, &pCreateInfo);
    284 }
    285 
    286 Move<VkCommandPool> createCommandPool (const DeviceInterface&	vk,
    287 									   VkDevice					device,
    288 									   VkCommandPoolCreateFlags	pCreateInfo_flags,
    289 									   deUint32					pCreateInfo_queueFamilyIndex)
    290 {
    291 	const VkCommandPoolCreateInfo pCreateInfo =
    292 	{
    293 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
    294 		DE_NULL,
    295 		pCreateInfo_flags,
    296 		pCreateInfo_queueFamilyIndex,
    297 	};
    298 	return createCommandPool(vk, device, &pCreateInfo);
    299 }
    300 
    301 void cmdBeginRenderPass (const DeviceInterface&	vk,
    302 						 VkCommandBuffer		cmdBuffer,
    303 						 VkRenderPass			pRenderPassBegin_renderPass,
    304 						 VkFramebuffer			pRenderPassBegin_framebuffer,
    305 						 VkRect2D				pRenderPassBegin_renderArea,
    306 						 deUint32				pRenderPassBegin_clearValueCount,
    307 						 const VkClearValue*	pRenderPassBegin_pAttachmentClearValues,
    308 						 VkSubpassContents		contents)
    309 {
    310 	const VkRenderPassBeginInfo pRenderPassBegin =
    311 	{
    312 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
    313 		DE_NULL,
    314 		pRenderPassBegin_renderPass,
    315 		pRenderPassBegin_framebuffer,
    316 		pRenderPassBegin_renderArea,
    317 		pRenderPassBegin_clearValueCount,
    318 		pRenderPassBegin_pAttachmentClearValues,
    319 	};
    320 	vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
    321 }
    322 
    323 Move<VkCommandBuffer> allocateCommandBuffer (const DeviceInterface&	vk,
    324 											 VkDevice				device,
    325 											 VkCommandPool			pCreateInfo_commandPool,
    326 											 VkCommandBufferLevel	pCreateInfo_level)
    327 {
    328 	const VkCommandBufferAllocateInfo pAllocateInfo =
    329 	{
    330 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
    331 		DE_NULL,
    332 		pCreateInfo_commandPool,
    333 		pCreateInfo_level,
    334 		1u,												// bufferCount
    335 	};
    336 	return allocateCommandBuffer(vk, device, &pAllocateInfo);
    337 }
    338 
    339 void beginCommandBuffer (const DeviceInterface&			vk,
    340 						 VkCommandBuffer				cmdBuffer,
    341 						 VkCommandBufferUsageFlags		pBeginInfo_flags,
    342 						 VkRenderPass					pInheritanceInfo_renderPass,
    343 						 deUint32						pInheritanceInfo_subpass,
    344 						 VkFramebuffer					pInheritanceInfo_framebuffer,
    345 						 VkBool32						pInheritanceInfo_occlusionQueryEnable,
    346 						 VkQueryControlFlags			pInheritanceInfo_queryFlags,
    347 						 VkQueryPipelineStatisticFlags	pInheritanceInfo_pipelineStatistics)
    348 {
    349 	const VkCommandBufferInheritanceInfo pInheritanceInfo =
    350 	{
    351 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
    352 		DE_NULL,
    353 		pInheritanceInfo_renderPass,
    354 		pInheritanceInfo_subpass,
    355 		pInheritanceInfo_framebuffer,
    356 		pInheritanceInfo_occlusionQueryEnable,
    357 		pInheritanceInfo_queryFlags,
    358 		pInheritanceInfo_pipelineStatistics,
    359 	};
    360 	const VkCommandBufferBeginInfo pBeginInfo =
    361 	{
    362 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
    363 		DE_NULL,
    364 		pBeginInfo_flags,
    365 		&pInheritanceInfo,
    366 	};
    367 	VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
    368 }
    369 
    370 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
    371 {
    372 	VK_CHECK(vk.endCommandBuffer(cmdBuffer));
    373 }
    374 
    375 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
    376 {
    377 	const VkSubmitInfo submitInfo =
    378 	{
    379 		VK_STRUCTURE_TYPE_SUBMIT_INFO,
    380 		DE_NULL,
    381 		0u,								// waitSemaphoreCount
    382 		(const VkSemaphore*)DE_NULL,	// pWaitSemaphores
    383 		(const VkPipelineStageFlags*)DE_NULL,
    384 		cmdBufferCount,					// commandBufferCount
    385 		pCmdBuffers,
    386 		0u,								// signalSemaphoreCount
    387 		(const VkSemaphore*)DE_NULL,	// pSignalSemaphores
    388 	};
    389 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
    390 }
    391 
    392 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
    393 {
    394 	VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
    395 }
    396 
    397 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
    398 {
    399 	const tcu::TextureFormat format = mapVkFormat(vkFormat);
    400 
    401 	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
    402 
    403 	switch (format.order)
    404 	{
    405 		case tcu::TextureFormat::DS:
    406 			return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
    407 
    408 		case tcu::TextureFormat::D:
    409 			return VK_IMAGE_ASPECT_DEPTH_BIT;
    410 
    411 		case tcu::TextureFormat::S:
    412 			return VK_IMAGE_ASPECT_STENCIL_BIT;
    413 
    414 		default:
    415 			return VK_IMAGE_ASPECT_COLOR_BIT;
    416 	}
    417 }
    418 
    419 VkAccessFlags getAllMemoryReadFlags (void)
    420 {
    421 	return VK_ACCESS_TRANSFER_READ_BIT
    422 		   | VK_ACCESS_UNIFORM_READ_BIT
    423 		   | VK_ACCESS_HOST_READ_BIT
    424 		   | VK_ACCESS_INDEX_READ_BIT
    425 		   | VK_ACCESS_SHADER_READ_BIT
    426 		   | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
    427 		   | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
    428 		   | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
    429 		   | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
    430 		   | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
    431 }
    432 
    433 VkAccessFlags getAllMemoryWriteFlags (void)
    434 {
    435 	return VK_ACCESS_TRANSFER_WRITE_BIT
    436 		   | VK_ACCESS_HOST_WRITE_BIT
    437 		   | VK_ACCESS_SHADER_WRITE_BIT
    438 		   | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
    439 		   | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    440 }
    441 
    442 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
    443 {
    444 	switch (layout)
    445 	{
    446 		case VK_IMAGE_LAYOUT_GENERAL:							return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
    447 		case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:			return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    448 		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:	return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
    449 		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:	return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
    450 		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:			return VK_ACCESS_SHADER_READ_BIT;
    451 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:				return VK_ACCESS_TRANSFER_READ_BIT;
    452 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:				return VK_ACCESS_TRANSFER_WRITE_BIT;
    453 
    454 		default:
    455 			return (VkAccessFlags)0;
    456 	}
    457 }
    458 
    459 VkPipelineStageFlags getAllPipelineStageFlags (void)
    460 {
    461 	return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
    462 		   | VK_PIPELINE_STAGE_TRANSFER_BIT
    463 		   | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
    464 		   | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
    465 		   | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
    466 		   | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
    467 		   | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
    468 		   | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
    469 		   | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
    470 		   | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
    471 		   | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
    472 		   | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
    473 		   | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
    474 }
    475 
    476 class AttachmentReference
    477 {
    478 public:
    479 					AttachmentReference		(deUint32		attachment,
    480 											 VkImageLayout	layout)
    481 		: m_attachment	(attachment)
    482 		, m_layout		(layout)
    483 	{
    484 	}
    485 
    486 	deUint32		getAttachment			(void) const { return m_attachment;	}
    487 	VkImageLayout	getImageLayout			(void) const { return m_layout;		}
    488 
    489 private:
    490 	deUint32		m_attachment;
    491 	VkImageLayout	m_layout;
    492 };
    493 
    494 class Subpass
    495 {
    496 public:
    497 										Subpass						(VkPipelineBindPoint				pipelineBindPoint,
    498 																	 VkSubpassDescriptionFlags			flags,
    499 																	 const vector<AttachmentReference>&	inputAttachments,
    500 																	 const vector<AttachmentReference>&	colorAttachments,
    501 																	 const vector<AttachmentReference>&	resolveAttachments,
    502 																	 AttachmentReference				depthStencilAttachment,
    503 																	 const vector<deUint32>&			preserveAttachments)
    504 		: m_pipelineBindPoint		(pipelineBindPoint)
    505 		, m_flags					(flags)
    506 		, m_inputAttachments		(inputAttachments)
    507 		, m_colorAttachments		(colorAttachments)
    508 		, m_resolveAttachments		(resolveAttachments)
    509 		, m_depthStencilAttachment	(depthStencilAttachment)
    510 		, m_preserveAttachments		(preserveAttachments)
    511 	{
    512 	}
    513 
    514 	VkPipelineBindPoint					getPipelineBindPoint		(void) const { return m_pipelineBindPoint;		}
    515 	VkSubpassDescriptionFlags			getFlags					(void) const { return m_flags;					}
    516 	const vector<AttachmentReference>&	getInputAttachments			(void) const { return m_inputAttachments;		}
    517 	const vector<AttachmentReference>&	getColorAttachments			(void) const { return m_colorAttachments;		}
    518 	const vector<AttachmentReference>&	getResolveAttachments		(void) const { return m_resolveAttachments;		}
    519 	const AttachmentReference&			getDepthStencilAttachment	(void) const { return m_depthStencilAttachment;	}
    520 	const vector<deUint32>&				getPreserveAttachments		(void) const { return m_preserveAttachments;	}
    521 
    522 private:
    523 	VkPipelineBindPoint					m_pipelineBindPoint;
    524 	VkSubpassDescriptionFlags			m_flags;
    525 
    526 	vector<AttachmentReference>			m_inputAttachments;
    527 	vector<AttachmentReference>			m_colorAttachments;
    528 	vector<AttachmentReference>			m_resolveAttachments;
    529 	AttachmentReference					m_depthStencilAttachment;
    530 
    531 	vector<deUint32>					m_preserveAttachments;
    532 };
    533 
    534 class SubpassDependency
    535 {
    536 public:
    537 							SubpassDependency	(deUint32				srcPass,
    538 												 deUint32				dstPass,
    539 
    540 												 VkPipelineStageFlags	srcStageMask,
    541 												 VkPipelineStageFlags	dstStageMask,
    542 
    543 												 VkAccessFlags			outputMask,
    544 												 VkAccessFlags			inputMask,
    545 
    546 												 VkDependencyFlags		flags)
    547 		: m_srcPass			(srcPass)
    548 		, m_dstPass			(dstPass)
    549 
    550 		, m_srcStageMask	(srcStageMask)
    551 		, m_dstStageMask	(dstStageMask)
    552 
    553 		, m_outputMask		(outputMask)
    554 		, m_inputMask		(inputMask)
    555 		, m_flags			(flags)
    556 	{
    557 	}
    558 
    559 	deUint32				getSrcPass			(void) const { return m_srcPass;		}
    560 	deUint32				getDstPass			(void) const { return m_dstPass;		}
    561 
    562 	VkPipelineStageFlags	getSrcStageMask		(void) const { return m_srcStageMask;	}
    563 	VkPipelineStageFlags	getDstStageMask		(void) const { return m_dstStageMask;	}
    564 
    565 	VkAccessFlags			getOutputMask		(void) const { return m_outputMask;		}
    566 	VkAccessFlags			getInputMask		(void) const { return m_inputMask;		}
    567 
    568 	VkDependencyFlags		getFlags			(void) const { return m_flags;		}
    569 
    570 private:
    571 	deUint32				m_srcPass;
    572 	deUint32				m_dstPass;
    573 
    574 	VkPipelineStageFlags	m_srcStageMask;
    575 	VkPipelineStageFlags	m_dstStageMask;
    576 
    577 	VkAccessFlags			m_outputMask;
    578 	VkAccessFlags			m_inputMask;
    579 	VkDependencyFlags		m_flags;
    580 };
    581 
    582 class Attachment
    583 {
    584 public:
    585 							Attachment			(VkFormat				format,
    586 												 VkSampleCountFlagBits	samples,
    587 
    588 												 VkAttachmentLoadOp		loadOp,
    589 												 VkAttachmentStoreOp	storeOp,
    590 
    591 												 VkAttachmentLoadOp		stencilLoadOp,
    592 												 VkAttachmentStoreOp	stencilStoreOp,
    593 
    594 												 VkImageLayout			initialLayout,
    595 												 VkImageLayout			finalLayout)
    596 		: m_format			(format)
    597 		, m_samples			(samples)
    598 
    599 		, m_loadOp			(loadOp)
    600 		, m_storeOp			(storeOp)
    601 
    602 		, m_stencilLoadOp	(stencilLoadOp)
    603 		, m_stencilStoreOp	(stencilStoreOp)
    604 
    605 		, m_initialLayout	(initialLayout)
    606 		, m_finalLayout		(finalLayout)
    607 	{
    608 	}
    609 
    610 	VkFormat				getFormat			(void) const { return m_format;			}
    611 	VkSampleCountFlagBits	getSamples			(void) const { return m_samples;		}
    612 
    613 	VkAttachmentLoadOp		getLoadOp			(void) const { return m_loadOp;			}
    614 	VkAttachmentStoreOp		getStoreOp			(void) const { return m_storeOp;		}
    615 
    616 
    617 	VkAttachmentLoadOp		getStencilLoadOp	(void) const { return m_stencilLoadOp;	}
    618 	VkAttachmentStoreOp		getStencilStoreOp	(void) const { return m_stencilStoreOp;	}
    619 
    620 	VkImageLayout			getInitialLayout	(void) const { return m_initialLayout;	}
    621 	VkImageLayout			getFinalLayout		(void) const { return m_finalLayout;	}
    622 
    623 private:
    624 	VkFormat				m_format;
    625 	VkSampleCountFlagBits	m_samples;
    626 
    627 	VkAttachmentLoadOp		m_loadOp;
    628 	VkAttachmentStoreOp		m_storeOp;
    629 
    630 	VkAttachmentLoadOp		m_stencilLoadOp;
    631 	VkAttachmentStoreOp		m_stencilStoreOp;
    632 
    633 	VkImageLayout			m_initialLayout;
    634 	VkImageLayout			m_finalLayout;
    635 };
    636 
    637 class RenderPass
    638 {
    639 public:
    640 										RenderPass		(const vector<Attachment>&			attachments,
    641 														 const vector<Subpass>&				subpasses,
    642 														 const vector<SubpassDependency>&	dependencies)
    643 		: m_attachments		(attachments)
    644 		, m_subpasses		(subpasses)
    645 		, m_dependencies	(dependencies)
    646 	{
    647 	}
    648 
    649 	const vector<Attachment>&			getAttachments	(void) const { return m_attachments;	}
    650 	const vector<Subpass>&				getSubpasses	(void) const { return m_subpasses;		}
    651 	const vector<SubpassDependency>&	getDependencies	(void) const { return m_dependencies;	}
    652 
    653 private:
    654 	const vector<Attachment>			m_attachments;
    655 	const vector<Subpass>				m_subpasses;
    656 	const vector<SubpassDependency>		m_dependencies;
    657 };
    658 
    659 struct TestConfig
    660 {
    661 	enum RenderTypes
    662 	{
    663 		RENDERTYPES_NONE	= 0,
    664 		RENDERTYPES_CLEAR	= (1<<1),
    665 		RENDERTYPES_DRAW	= (1<<2)
    666 	};
    667 
    668 	enum CommandBufferTypes
    669 	{
    670 		COMMANDBUFFERTYPES_INLINE		= (1<<0),
    671 		COMMANDBUFFERTYPES_SECONDARY	= (1<<1)
    672 	};
    673 
    674 	enum ImageMemory
    675 	{
    676 		IMAGEMEMORY_STRICT		= (1<<0),
    677 		IMAGEMEMORY_LAZY		= (1<<1)
    678 	};
    679 
    680 						TestConfig (const RenderPass&	renderPass_,
    681 									RenderTypes			renderTypes_,
    682 									CommandBufferTypes	commandBufferTypes_,
    683 									ImageMemory			imageMemory_,
    684 									const UVec2&		targetSize_,
    685 									const UVec2&		renderPos_,
    686 									const UVec2&		renderSize_,
    687 									deUint32			seed_)
    688 		: renderPass			(renderPass_)
    689 		, renderTypes			(renderTypes_)
    690 		, commandBufferTypes	(commandBufferTypes_)
    691 		, imageMemory			(imageMemory_)
    692 		, targetSize			(targetSize_)
    693 		, renderPos				(renderPos_)
    694 		, renderSize			(renderSize_)
    695 		, seed					(seed_)
    696 	{
    697 	}
    698 
    699 	RenderPass			renderPass;
    700 	RenderTypes			renderTypes;
    701 	CommandBufferTypes	commandBufferTypes;
    702 	ImageMemory			imageMemory;
    703 	UVec2				targetSize;
    704 	UVec2				renderPos;
    705 	UVec2				renderSize;
    706 	deUint32			seed;
    707 };
    708 
    709 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
    710 {
    711 	return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
    712 }
    713 
    714 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
    715 {
    716 	return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
    717 }
    718 
    719 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
    720 {
    721 	return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
    722 }
    723 
    724 void logRenderPassInfo (TestLog&			log,
    725 						const RenderPass&	renderPass)
    726 {
    727 	const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
    728 
    729 	{
    730 		const tcu::ScopedLogSection	attachmentsSection	(log, "Attachments", "Attachments");
    731 		const vector<Attachment>&	attachments			= renderPass.getAttachments();
    732 
    733 		for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
    734 		{
    735 			const tcu::ScopedLogSection	attachmentSection	(log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
    736 			const Attachment&			attachment			= attachments[attachmentNdx];
    737 
    738 			log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
    739 			log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
    740 
    741 			log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
    742 			log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
    743 
    744 			log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
    745 			log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
    746 
    747 			log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
    748 			log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
    749 		}
    750 	}
    751 
    752 	{
    753 		const tcu::ScopedLogSection	subpassesSection	(log, "Subpasses", "Subpasses");
    754 		const vector<Subpass>&		subpasses			= renderPass.getSubpasses();
    755 
    756 		for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
    757 		{
    758 			const tcu::ScopedLogSection			subpassSection		(log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
    759 			const Subpass&						subpass				= subpasses[subpassNdx];
    760 
    761 			const vector<AttachmentReference>&	inputAttachments	= subpass.getInputAttachments();
    762 			const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();
    763 			const vector<AttachmentReference>&	resolveAttachments	= subpass.getResolveAttachments();
    764 			const vector<deUint32>&				preserveAttachments	= subpass.getPreserveAttachments();
    765 
    766 			if (!inputAttachments.empty())
    767 			{
    768 				const tcu::ScopedLogSection	inputAttachmentsSection	(log, "Inputs", "Inputs");
    769 
    770 				for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
    771 				{
    772 					const tcu::ScopedLogSection	inputAttachmentSection	(log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
    773 					const AttachmentReference&	inputAttachment			= inputAttachments[inputNdx];
    774 
    775 					log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
    776 					log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
    777 				}
    778 			}
    779 
    780 			if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
    781 			{
    782 				const tcu::ScopedLogSection	depthStencilAttachmentSection	(log, "DepthStencil", "DepthStencil");
    783 				const AttachmentReference&	depthStencilAttachment			= subpass.getDepthStencilAttachment();
    784 
    785 				log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
    786 				log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
    787 			}
    788 
    789 			if (!colorAttachments.empty())
    790 			{
    791 				const tcu::ScopedLogSection	colorAttachmentsSection	(log, "Colors", "Colors");
    792 
    793 				for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
    794 				{
    795 					const tcu::ScopedLogSection	colorAttachmentSection	(log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
    796 					const AttachmentReference&	colorAttachment			= colorAttachments[colorNdx];
    797 
    798 					log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
    799 					log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
    800 				}
    801 			}
    802 
    803 			if (!resolveAttachments.empty())
    804 			{
    805 				const tcu::ScopedLogSection	resolveAttachmentsSection	(log, "Resolves", "Resolves");
    806 
    807 				for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
    808 				{
    809 					const tcu::ScopedLogSection	resolveAttachmentSection	(log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
    810 					const AttachmentReference&	resolveAttachment			= resolveAttachments[resolveNdx];
    811 
    812 					log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
    813 					log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
    814 				}
    815 			}
    816 
    817 			if (!preserveAttachments.empty())
    818 			{
    819 				const tcu::ScopedLogSection	preserveAttachmentsSection	(log, "Preserves", "Preserves");
    820 
    821 				for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
    822 				{
    823 					const tcu::ScopedLogSection	preserveAttachmentSection	(log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
    824 					const deUint32				preserveAttachment			= preserveAttachments[preserveNdx];
    825 
    826 					log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
    827 				}
    828 			}
    829 		}
    830 
    831 	}
    832 
    833 	if (!renderPass.getDependencies().empty())
    834 	{
    835 		const tcu::ScopedLogSection	dependenciesSection	(log, "Dependencies", "Dependencies");
    836 
    837 		for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
    838 		{
    839 			const tcu::ScopedLogSection	dependencySection	(log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
    840 			const SubpassDependency&	dep					= renderPass.getDependencies()[depNdx];
    841 
    842 			log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
    843 			log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
    844 
    845 			log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
    846 			log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
    847 
    848 			log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
    849 			log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
    850 			log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
    851 		}
    852 	}
    853 }
    854 
    855 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
    856 {
    857 	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
    858 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
    859 	const tcu::BVec4				channelMask		= tcu::getTextureFormatChannelMask(format);
    860 
    861 	std::ostringstream				stream;
    862 
    863 	stream << "(";
    864 
    865 	switch (channelClass)
    866 	{
    867 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    868 			for (int i = 0; i < 4; i++)
    869 			{
    870 				if (i > 0)
    871 					stream << ", ";
    872 
    873 				if (channelMask[i])
    874 					stream << value.int32[i];
    875 				else
    876 					stream << "Undef";
    877 			}
    878 			break;
    879 
    880 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    881 			for (int i = 0; i < 4; i++)
    882 			{
    883 				if (i > 0)
    884 					stream << ", ";
    885 
    886 				if (channelMask[i])
    887 					stream << value.uint32[i];
    888 				else
    889 					stream << "Undef";
    890 			}
    891 			break;
    892 
    893 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    894 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    895 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    896 			for (int i = 0; i < 4; i++)
    897 			{
    898 				if (i > 0)
    899 					stream << ", ";
    900 
    901 				if (channelMask[i])
    902 					stream << value.float32[i];
    903 				else
    904 					stream << "Undef";
    905 			}
    906 			break;
    907 
    908 		default:
    909 			DE_FATAL("Unknown channel class");
    910 	}
    911 
    912 	stream << ")";
    913 
    914 	return stream.str();
    915 }
    916 
    917 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
    918 {
    919 	const tcu::TextureFormat	format	= mapVkFormat(vkFormat);
    920 
    921 	if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
    922 	{
    923 		std::ostringstream stream;
    924 
    925 		stream << "(";
    926 
    927 		if (tcu::hasStencilComponent(format.order))
    928 			stream << "stencil: " << value.depthStencil.stencil;
    929 
    930 		if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
    931 			stream << ", ";
    932 
    933 		if (tcu::hasDepthComponent(format.order))
    934 			stream << "depth: " << value.depthStencil.depth;
    935 
    936 		stream << ")";
    937 
    938 		return stream.str();
    939 	}
    940 	else
    941 		return clearColorToString(vkFormat, value.color);
    942 }
    943 
    944 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
    945 {
    946 	const float						clearNan		= tcu::Float32::nan().asFloat();
    947 	const tcu::TextureFormat		format			= mapVkFormat(attachment.getFormat());
    948 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
    949 	const tcu::BVec4				channelMask		= tcu::getTextureFormatChannelMask(format);
    950 	VkClearColorValue				clearColor;
    951 
    952 	switch (channelClass)
    953 	{
    954 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    955 		{
    956 			for (int ndx = 0; ndx < 4; ndx++)
    957 			{
    958 				if (!channelMask[ndx])
    959 					clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
    960 				else
    961 					clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
    962 			}
    963 			break;
    964 		}
    965 
    966 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    967 		{
    968 			for (int ndx = 0; ndx < 4; ndx++)
    969 			{
    970 				if (!channelMask[ndx])
    971 					clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
    972 				else
    973 					clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
    974 			}
    975 			break;
    976 		}
    977 
    978 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    979 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    980 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    981 		{
    982 			for (int ndx = 0; ndx < 4; ndx++)
    983 			{
    984 				if (!channelMask[ndx])
    985 					clearColor.float32[ndx] = clearNan;
    986 				else
    987 					clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
    988 			}
    989 			break;
    990 		}
    991 
    992 		default:
    993 			DE_FATAL("Unknown channel class");
    994 	}
    995 
    996 	return clearColor;
    997 }
    998 
    999 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
   1000 {
   1001 	const VkAttachmentDescription attachmentDescription =
   1002 	{
   1003 		0,								// flags
   1004 
   1005 		attachment.getFormat(),			// format
   1006 		attachment.getSamples(),		// samples
   1007 
   1008 		attachment.getLoadOp(),			// loadOp
   1009 		attachment.getStoreOp(),		// storeOp
   1010 
   1011 		attachment.getStencilLoadOp(),	// stencilLoadOp
   1012 		attachment.getStencilStoreOp(),	// stencilStoreOp
   1013 
   1014 		attachment.getInitialLayout(),	// initialLayout
   1015 		attachment.getFinalLayout(),	// finalLayout
   1016 	};
   1017 
   1018 	return attachmentDescription;
   1019 }
   1020 
   1021 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
   1022 {
   1023 	const VkAttachmentReference reference =
   1024 	{
   1025 		referenceInfo.getAttachment(),	// attachment;
   1026 		referenceInfo.getImageLayout()	// layout;
   1027 	};
   1028 
   1029 	return reference;
   1030 }
   1031 
   1032 VkSubpassDescription createSubpassDescription (const Subpass&					subpass,
   1033 											   vector<VkAttachmentReference>*	attachmentReferenceLists,
   1034 											   vector<deUint32>*				preserveAttachmentReferences)
   1035 {
   1036 	vector<VkAttachmentReference>&	inputAttachmentReferences			= attachmentReferenceLists[0];
   1037 	vector<VkAttachmentReference>&	colorAttachmentReferences			= attachmentReferenceLists[1];
   1038 	vector<VkAttachmentReference>&	resolveAttachmentReferences			= attachmentReferenceLists[2];
   1039 	vector<VkAttachmentReference>&	depthStencilAttachmentReferences	= attachmentReferenceLists[3];
   1040 
   1041 	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
   1042 		colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
   1043 
   1044 	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
   1045 		inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
   1046 
   1047 	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
   1048 		resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
   1049 
   1050 	depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
   1051 
   1052 	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
   1053 		preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
   1054 
   1055 	DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
   1056 
   1057 	{
   1058 		const VkSubpassDescription subpassDescription =
   1059 		{
   1060 			subpass.getFlags(),																		// flags;
   1061 			subpass.getPipelineBindPoint(),															// pipelineBindPoint;
   1062 
   1063 			(deUint32)inputAttachmentReferences.size(),												// inputCount;
   1064 			inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0],			// inputAttachments;
   1065 
   1066 			(deUint32)colorAttachmentReferences.size(),												// colorCount;
   1067 			colorAttachmentReferences.empty() ? DE_NULL :  &colorAttachmentReferences[0],			// colorAttachments;
   1068 			resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0],		// resolveAttachments;
   1069 
   1070 			&depthStencilAttachmentReferences[0],													// pDepthStencilAttachment;
   1071 			(deUint32)preserveAttachmentReferences->size(),											// preserveCount;
   1072 			preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0]	// preserveAttachments;
   1073 		};
   1074 
   1075 		return subpassDescription;
   1076 	}
   1077 }
   1078 
   1079 VkSubpassDependency createSubpassDependency	(const SubpassDependency& dependencyInfo)
   1080 {
   1081 	const VkSubpassDependency dependency =
   1082 	{
   1083 		dependencyInfo.getSrcPass(),		// srcSubpass;
   1084 		dependencyInfo.getDstPass(),		// destSubpass;
   1085 
   1086 		dependencyInfo.getSrcStageMask(),	// srcStageMask;
   1087 		dependencyInfo.getDstStageMask(),	// destStageMask;
   1088 
   1089 		dependencyInfo.getOutputMask(),		// outputMask;
   1090 		dependencyInfo.getInputMask(),		// inputMask;
   1091 
   1092 		dependencyInfo.getFlags()			// dependencyFlags;
   1093 	};
   1094 
   1095 	return dependency;
   1096 }
   1097 
   1098 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vk,
   1099 									 VkDevice				device,
   1100 									 const RenderPass&		renderPassInfo)
   1101 {
   1102 	const size_t							perSubpassAttachmentReferenceLists = 4;
   1103 	vector<VkAttachmentDescription>			attachments;
   1104 	vector<VkSubpassDescription>			subpasses;
   1105 	vector<VkSubpassDependency>				dependencies;
   1106 	vector<vector<VkAttachmentReference> >	attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
   1107 	vector<vector<deUint32> >				preserveAttachments(renderPassInfo.getSubpasses().size());
   1108 
   1109 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   1110 		attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
   1111 
   1112 	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
   1113 		subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
   1114 
   1115 	for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
   1116 		dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
   1117 
   1118 	{
   1119 		const VkRenderPassCreateInfo	createInfo	=
   1120 		{
   1121 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
   1122 			DE_NULL,
   1123 			(VkRenderPassCreateFlags)0u,
   1124 			(deUint32)attachments.size(),
   1125 			(attachments.empty() ? DE_NULL : &attachments[0]),
   1126 			(deUint32)subpasses.size(),
   1127 			(subpasses.empty() ? DE_NULL : &subpasses[0]),
   1128 			(deUint32)dependencies.size(),
   1129 			(dependencies.empty() ? DE_NULL : &dependencies[0])
   1130 		};
   1131 
   1132 		return createRenderPass(vk, device, &createInfo);
   1133 	}
   1134 }
   1135 
   1136 Move<VkFramebuffer> createFramebuffer (const DeviceInterface&		vk,
   1137 									   VkDevice						device,
   1138 									   VkRenderPass					renderPass,
   1139 									   const UVec2&					size,
   1140 									   const vector<VkImageView>&	attachments)
   1141 {
   1142 	return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
   1143 }
   1144 
   1145 Move<VkImage> createAttachmentImage (const DeviceInterface&	vk,
   1146 									 VkDevice				device,
   1147 									 deUint32				queueIndex,
   1148 									 const UVec2&			size,
   1149 									 VkFormat				format,
   1150 									 VkSampleCountFlagBits	samples,
   1151 									 VkImageUsageFlags		usageFlags,
   1152 									 VkImageLayout			layout)
   1153 {
   1154 	VkImageUsageFlags			targetUsageFlags	= 0;
   1155 	const tcu::TextureFormat	textureFormat		= mapVkFormat(format);
   1156 
   1157 	DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
   1158 					|| ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
   1159 
   1160 	DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
   1161 					|| ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
   1162 
   1163 	if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
   1164 		targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
   1165 	else
   1166 		targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   1167 
   1168 	return createImage(vk, device,
   1169 					   (VkImageCreateFlags)0,
   1170 					   VK_IMAGE_TYPE_2D,
   1171 					   format,
   1172 					   vk::makeExtent3D(size.x(), size.y(), 1u),
   1173 					   1u /* mipLevels */,
   1174 					   1u /* arraySize */,
   1175 					   samples,
   1176 					   VK_IMAGE_TILING_OPTIMAL,
   1177 					   usageFlags | targetUsageFlags,
   1178 					   VK_SHARING_MODE_EXCLUSIVE,
   1179 					   1,
   1180 					   &queueIndex,
   1181 					   layout);
   1182 }
   1183 
   1184 de::MovePtr<Allocation> createImageMemory (const DeviceInterface&	vk,
   1185 										   VkDevice					device,
   1186 										   Allocator&				allocator,
   1187 										   VkImage					image,
   1188 										   bool						lazy)
   1189 {
   1190 	de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any));
   1191 	bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
   1192 	return allocation;
   1193 }
   1194 
   1195 Move<VkImageView> createImageAttachmentView (const DeviceInterface&	vk,
   1196 											 VkDevice				device,
   1197 											 VkImage				image,
   1198 											 VkFormat				format,
   1199 											 VkImageAspectFlags		aspect)
   1200 {
   1201 	const VkImageSubresourceRange range =
   1202 	{
   1203 		aspect,
   1204 		0,
   1205 		1,
   1206 		0,
   1207 		1
   1208 	};
   1209 
   1210 	return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
   1211 }
   1212 
   1213 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
   1214 {
   1215 	const float					clearNan	= tcu::Float32::nan().asFloat();
   1216 	const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
   1217 
   1218 	if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
   1219 	{
   1220 		VkClearValue clearValue;
   1221 
   1222 		clearValue.depthStencil.depth	= clearNan;
   1223 		clearValue.depthStencil.stencil	= 0xCDu;
   1224 
   1225 		if (tcu::hasStencilComponent(format.order))
   1226 			clearValue.depthStencil.stencil	= rng.getBool()
   1227 											? 0xFFu
   1228 											: 0x0u;
   1229 
   1230 		if (tcu::hasDepthComponent(format.order))
   1231 			clearValue.depthStencil.depth	= rng.getBool()
   1232 											? 1.0f
   1233 											: 0.0f;
   1234 
   1235 		return clearValue;
   1236 	}
   1237 	else
   1238 	{
   1239 		VkClearValue clearValue;
   1240 
   1241 		clearValue.color = randomColorClearValue(attachment, rng);
   1242 
   1243 		return clearValue;
   1244 	}
   1245 }
   1246 
   1247 class AttachmentResources
   1248 {
   1249 public:
   1250 	AttachmentResources (const DeviceInterface&	vk,
   1251 						 VkDevice				device,
   1252 						 Allocator&				allocator,
   1253 						 deUint32				queueIndex,
   1254 						 const UVec2&			size,
   1255 						 const Attachment&		attachmentInfo,
   1256 						 VkImageUsageFlags		usageFlags)
   1257 		: m_image			(createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
   1258 		, m_imageMemory		(createImageMemory(vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)))
   1259 		, m_attachmentView	(createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
   1260 	{
   1261 		const tcu::TextureFormat	format			= mapVkFormat(attachmentInfo.getFormat());
   1262 		const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
   1263 		const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
   1264 
   1265 		if (isDepthFormat && isStencilFormat)
   1266 		{
   1267 			m_depthInputAttachmentView		= createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
   1268 			m_stencilInputAttachmentView	= createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);
   1269 
   1270 			m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
   1271 		}
   1272 		else
   1273 			m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
   1274 
   1275 		if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
   1276 		{
   1277 			if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
   1278 			{
   1279 				const tcu::TextureFormat	depthFormat		= getDepthCopyFormat(attachmentInfo.getFormat());
   1280 				const tcu::TextureFormat	stencilFormat	= getStencilCopyFormat(attachmentInfo.getFormat());
   1281 
   1282 				m_bufferSize			= size.x() * size.y() * depthFormat.getPixelSize();
   1283 				m_secondaryBufferSize	= size.x() * size.y() * stencilFormat.getPixelSize();
   1284 
   1285 				m_buffer				= createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
   1286 				m_bufferMemory			= allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
   1287 
   1288 				bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
   1289 
   1290 				m_secondaryBuffer		= createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
   1291 				m_secondaryBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vk, device, *m_secondaryBuffer), MemoryRequirement::HostVisible);
   1292 
   1293 				bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
   1294 			}
   1295 			else
   1296 			{
   1297 				m_bufferSize	= size.x() * size.y() * format.getPixelSize();
   1298 
   1299 				m_buffer		= createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
   1300 				m_bufferMemory	= allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
   1301 
   1302 				bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
   1303 			}
   1304 		}
   1305 	}
   1306 
   1307 	const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
   1308 	{
   1309 		return m_inputAttachmentViews;
   1310 	}
   1311 
   1312 	~AttachmentResources (void)
   1313 	{
   1314 	}
   1315 
   1316 	VkImageView getAttachmentView (void) const
   1317 	{
   1318 		return *m_attachmentView;
   1319 	}
   1320 
   1321 	VkImage getImage (void) const
   1322 	{
   1323 		return *m_image;
   1324 	}
   1325 
   1326 	VkBuffer getBuffer (void) const
   1327 	{
   1328 		DE_ASSERT(*m_buffer != DE_NULL);
   1329 		return *m_buffer;
   1330 	}
   1331 
   1332 	VkDeviceSize getBufferSize (void) const
   1333 	{
   1334 		DE_ASSERT(*m_buffer != DE_NULL);
   1335 		return m_bufferSize;
   1336 	}
   1337 
   1338 	const Allocation& getResultMemory (void) const
   1339 	{
   1340 		DE_ASSERT(m_bufferMemory);
   1341 		return *m_bufferMemory;
   1342 	}
   1343 
   1344 	VkBuffer getSecondaryBuffer (void) const
   1345 	{
   1346 		DE_ASSERT(*m_secondaryBuffer != DE_NULL);
   1347 		return *m_secondaryBuffer;
   1348 	}
   1349 
   1350 	VkDeviceSize getSecondaryBufferSize (void) const
   1351 	{
   1352 		DE_ASSERT(*m_secondaryBuffer != DE_NULL);
   1353 		return m_secondaryBufferSize;
   1354 	}
   1355 
   1356 	const Allocation& getSecondaryResultMemory (void) const
   1357 	{
   1358 		DE_ASSERT(m_secondaryBufferMemory);
   1359 		return *m_secondaryBufferMemory;
   1360 	}
   1361 
   1362 private:
   1363 	const Unique<VkImage>			m_image;
   1364 	const UniquePtr<Allocation>		m_imageMemory;
   1365 	const Unique<VkImageView>		m_attachmentView;
   1366 
   1367 	Move<VkImageView>				m_depthInputAttachmentView;
   1368 	Move<VkImageView>				m_stencilInputAttachmentView;
   1369 	pair<VkImageView, VkImageView>	m_inputAttachmentViews;
   1370 
   1371 	Move<VkBuffer>					m_buffer;
   1372 	VkDeviceSize					m_bufferSize;
   1373 	de::MovePtr<Allocation>			m_bufferMemory;
   1374 
   1375 	Move<VkBuffer>					m_secondaryBuffer;
   1376 	VkDeviceSize					m_secondaryBufferSize;
   1377 	de::MovePtr<Allocation>			m_secondaryBufferMemory;
   1378 };
   1379 
   1380 void uploadBufferData (const DeviceInterface&	vk,
   1381 					   VkDevice					device,
   1382 					   const Allocation&		memory,
   1383 					   size_t					size,
   1384 					   const void*				data)
   1385 {
   1386 	const VkMappedMemoryRange range =
   1387 	{
   1388 		VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// sType;
   1389 		DE_NULL,								// pNext;
   1390 		memory.getMemory(),						// mem;
   1391 		memory.getOffset(),						// offset;
   1392 		(VkDeviceSize)size						// size;
   1393 	};
   1394 	void* const ptr = memory.getHostPtr();
   1395 
   1396 	deMemcpy(ptr, data, size);
   1397 	VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
   1398 }
   1399 
   1400 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
   1401 {
   1402 	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
   1403 
   1404 	switch (order)
   1405 	{
   1406 		case tcu::TextureFormat::D:
   1407 		case tcu::TextureFormat::DS:
   1408 			return VK_IMAGE_ASPECT_DEPTH_BIT;
   1409 
   1410 		case tcu::TextureFormat::S:
   1411 			return VK_IMAGE_ASPECT_STENCIL_BIT;
   1412 
   1413 		default:
   1414 			return VK_IMAGE_ASPECT_COLOR_BIT;
   1415 	}
   1416 }
   1417 
   1418 class RenderQuad
   1419 {
   1420 public:
   1421 					RenderQuad			(const Vec2& posA, const Vec2& posB)
   1422 		: m_vertices(6)
   1423 	{
   1424 		m_vertices[0] = posA;
   1425 		m_vertices[1] = Vec2(posA[0], posB[1]);
   1426 		m_vertices[2] = posB;
   1427 
   1428 		m_vertices[3] = posB;
   1429 		m_vertices[4] = Vec2(posB[0], posA[1]);
   1430 		m_vertices[5] = posA;
   1431 	}
   1432 
   1433 	const Vec2&		getCornerA			(void) const
   1434 	{
   1435 		return m_vertices[0];
   1436 	}
   1437 
   1438 	const Vec2&		getCornerB			(void) const
   1439 	{
   1440 		return m_vertices[2];
   1441 	}
   1442 
   1443 	const void*		getVertexPointer	(void) const
   1444 	{
   1445 		return &m_vertices[0];
   1446 	}
   1447 
   1448 	size_t			getVertexDataSize	(void) const
   1449 	{
   1450 		return sizeof(Vec2) * m_vertices.size();
   1451 	}
   1452 
   1453 private:
   1454 	vector<Vec2>	m_vertices;
   1455 };
   1456 
   1457 class ColorClear
   1458 {
   1459 public:
   1460 								ColorClear	(const UVec2&				offset,
   1461 											 const UVec2&				size,
   1462 											 const VkClearColorValue&	color)
   1463 		: m_offset	(offset)
   1464 		, m_size	(size)
   1465 		, m_color	(color)
   1466 	{
   1467 	}
   1468 
   1469 	const UVec2&				getOffset	(void) const { return m_offset;	}
   1470 	const UVec2&				getSize		(void) const { return m_size;	}
   1471 	const VkClearColorValue&	getColor	(void) const { return m_color;	}
   1472 
   1473 private:
   1474 	UVec2						m_offset;
   1475 	UVec2						m_size;
   1476 	VkClearColorValue			m_color;
   1477 };
   1478 
   1479 class DepthStencilClear
   1480 {
   1481 public:
   1482 					DepthStencilClear	(const UVec2&	offset,
   1483 										 const UVec2&	size,
   1484 										 float			depth,
   1485 										 deUint32		stencil)
   1486 		: m_offset	(offset)
   1487 		, m_size	(size)
   1488 		, m_depth	(depth)
   1489 		, m_stencil	(stencil)
   1490 	{
   1491 	}
   1492 
   1493 	const UVec2&	getOffset			(void) const { return m_offset;		}
   1494 	const UVec2&	getSize				(void) const { return m_size;		}
   1495 	float			getDepth			(void) const { return m_depth;		}
   1496 	deUint32		getStencil			(void) const { return m_stencil;	}
   1497 
   1498 private:
   1499 	const UVec2		m_offset;
   1500 	const UVec2		m_size;
   1501 
   1502 	const float		m_depth;
   1503 	const deUint32	m_stencil;
   1504 };
   1505 
   1506 class SubpassRenderInfo
   1507 {
   1508 public:
   1509 									SubpassRenderInfo				(const RenderPass&					renderPass,
   1510 																	 deUint32							subpassIndex,
   1511 
   1512 																	 bool								isSecondary_,
   1513 
   1514 																	 const UVec2&						viewportOffset,
   1515 																	 const UVec2&						viewportSize,
   1516 
   1517 																	 const Maybe<RenderQuad>&			renderQuad,
   1518 																	 const vector<ColorClear>&			colorClears,
   1519 																	 const Maybe<DepthStencilClear>&	depthStencilClear)
   1520 		: m_viewportOffset		(viewportOffset)
   1521 		, m_viewportSize		(viewportSize)
   1522 		, m_subpassIndex		(subpassIndex)
   1523 		, m_isSecondary			(isSecondary_)
   1524 		, m_flags				(renderPass.getSubpasses()[subpassIndex].getFlags())
   1525 		, m_renderQuad			(renderQuad)
   1526 		, m_colorClears			(colorClears)
   1527 		, m_depthStencilClear	(depthStencilClear)
   1528 		, m_colorAttachments	(renderPass.getSubpasses()[subpassIndex].getColorAttachments())
   1529 		, m_inputAttachments	(renderPass.getSubpasses()[subpassIndex].getInputAttachments())
   1530 	{
   1531 		for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
   1532 			m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
   1533 
   1534 		if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   1535 		{
   1536 			m_depthStencilAttachment		= tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
   1537 			m_depthStencilAttachmentInfo	= tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
   1538 		}
   1539 	}
   1540 
   1541 	const UVec2&					getViewportOffset				(void) const { return m_viewportOffset;		}
   1542 	const UVec2&					getViewportSize					(void) const { return m_viewportSize;		}
   1543 
   1544 	deUint32						getSubpassIndex					(void) const { return m_subpassIndex;		}
   1545 	bool							isSecondary						(void) const { return m_isSecondary;		}
   1546 
   1547 	const Maybe<RenderQuad>&		getRenderQuad					(void) const { return m_renderQuad;			}
   1548 	const vector<ColorClear>&		getColorClears					(void) const { return m_colorClears;		}
   1549 	const Maybe<DepthStencilClear>&	getDepthStencilClear			(void) const { return m_depthStencilClear;	}
   1550 
   1551 	deUint32						getInputAttachmentCount			(void) const { return (deUint32)m_inputAttachments.size(); }
   1552 	deUint32						getInputAttachmentIndex			(deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
   1553 	VkImageLayout					getInputAttachmentLayout		(deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }
   1554 
   1555 	deUint32						getColorAttachmentCount			(void) const { return (deUint32)m_colorAttachments.size(); }
   1556 	VkImageLayout					getColorAttachmentLayout		(deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
   1557 	deUint32						getColorAttachmentIndex			(deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
   1558 	const Attachment&				getColorAttachment				(deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
   1559 	Maybe<VkImageLayout>			getDepthStencilAttachmentLayout	(void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
   1560 	Maybe<deUint32>					getDepthStencilAttachmentIndex	(void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
   1561 	const Maybe<Attachment>&		getDepthStencilAttachment		(void) const { return m_depthStencilAttachmentInfo; }
   1562 	VkSubpassDescriptionFlags		getSubpassFlags					(void) const { return m_flags; }
   1563 
   1564 private:
   1565 	UVec2							m_viewportOffset;
   1566 	UVec2							m_viewportSize;
   1567 
   1568 	deUint32						m_subpassIndex;
   1569 	bool							m_isSecondary;
   1570 	VkSubpassDescriptionFlags		m_flags;
   1571 
   1572 	Maybe<RenderQuad>				m_renderQuad;
   1573 	vector<ColorClear>				m_colorClears;
   1574 	Maybe<DepthStencilClear>		m_depthStencilClear;
   1575 
   1576 	vector<AttachmentReference>		m_colorAttachments;
   1577 	vector<Attachment>				m_colorAttachmentInfo;
   1578 
   1579 	Maybe<AttachmentReference>		m_depthStencilAttachment;
   1580 	Maybe<Attachment>				m_depthStencilAttachmentInfo;
   1581 
   1582 	vector<AttachmentReference>		m_inputAttachments;
   1583 };
   1584 
   1585 Move<VkPipeline> createSubpassPipeline (const DeviceInterface&		vk,
   1586 										VkDevice					device,
   1587 										VkRenderPass				renderPass,
   1588 										VkShaderModule				vertexShaderModule,
   1589 										VkShaderModule				fragmentShaderModule,
   1590 										VkPipelineLayout			pipelineLayout,
   1591 										const SubpassRenderInfo&	renderInfo)
   1592 {
   1593 	const VkSpecializationInfo emptyShaderSpecializations =
   1594 	{
   1595 		0u,			// mapEntryCount
   1596 		DE_NULL,	// pMap
   1597 		0u,			// dataSize
   1598 		DE_NULL,	// pData
   1599 	};
   1600 
   1601 	Maybe<VkSampleCountFlagBits>				rasterSamples;
   1602 	vector<VkPipelineColorBlendAttachmentState>	attachmentBlendStates;
   1603 
   1604 	for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
   1605 	{
   1606 		const Attachment&	attachment	= renderInfo.getColorAttachment(attachmentNdx);
   1607 
   1608 		DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
   1609 
   1610 		rasterSamples = attachment.getSamples();
   1611 
   1612 		{
   1613 			const VkPipelineColorBlendAttachmentState	attachmentBlendState =
   1614 			{
   1615 				VK_FALSE,																								// blendEnable
   1616 				VK_BLEND_FACTOR_SRC_ALPHA,																				// srcBlendColor
   1617 				VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,																	// destBlendColor
   1618 				VK_BLEND_OP_ADD,																						// blendOpColor
   1619 				VK_BLEND_FACTOR_ONE,																					// srcBlendAlpha
   1620 				VK_BLEND_FACTOR_ONE,																					// destBlendAlpha
   1621 				VK_BLEND_OP_ADD,																						// blendOpAlpha
   1622 				VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT,	// channelWriteMask
   1623 			};
   1624 
   1625 			attachmentBlendStates.push_back(attachmentBlendState);
   1626 		}
   1627 	}
   1628 
   1629 	if (renderInfo.getDepthStencilAttachment())
   1630 	{
   1631 		const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
   1632 
   1633 		DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
   1634 		rasterSamples = attachment.getSamples();
   1635 	}
   1636 
   1637 	// If there are no attachment use single sample
   1638 	if (!rasterSamples)
   1639 		rasterSamples = VK_SAMPLE_COUNT_1_BIT;
   1640 
   1641 	const VkPipelineShaderStageCreateInfo shaderStages[2] =
   1642 	{
   1643 		{
   1644 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// sType
   1645 			DE_NULL,												// pNext
   1646 			(VkPipelineShaderStageCreateFlags)0u,
   1647 			VK_SHADER_STAGE_VERTEX_BIT,								// stage
   1648 			vertexShaderModule,										// shader
   1649 			"main",
   1650 			&emptyShaderSpecializations
   1651 		},
   1652 		{
   1653 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// sType
   1654 			DE_NULL,												// pNext
   1655 			(VkPipelineShaderStageCreateFlags)0u,
   1656 			VK_SHADER_STAGE_FRAGMENT_BIT,							// stage
   1657 			fragmentShaderModule,									// shader
   1658 			"main",
   1659 			&emptyShaderSpecializations
   1660 		}
   1661 	};
   1662 	const VkVertexInputBindingDescription vertexBinding =
   1663 	{
   1664 		0u,															// binding
   1665 		(deUint32)sizeof(tcu::Vec2),								// strideInBytes
   1666 		VK_VERTEX_INPUT_RATE_VERTEX,								// stepRate
   1667 	};
   1668 	const VkVertexInputAttributeDescription vertexAttrib =
   1669 	{
   1670 		0u,															// location
   1671 		0u,															// binding
   1672 		VK_FORMAT_R32G32_SFLOAT,									// format
   1673 		0u,															// offsetInBytes
   1674 	};
   1675 	const VkPipelineVertexInputStateCreateInfo vertexInputState =
   1676 	{
   1677 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	sType
   1678 		DE_NULL,													//	pNext
   1679 		(VkPipelineVertexInputStateCreateFlags)0u,
   1680 		1u,															//	bindingCount
   1681 		&vertexBinding,												//	pVertexBindingDescriptions
   1682 		1u,															//	attributeCount
   1683 		&vertexAttrib,												//	pVertexAttributeDescriptions
   1684 	};
   1685 	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
   1686 	{
   1687 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// sType
   1688 		DE_NULL,														// pNext
   1689 		(VkPipelineInputAssemblyStateCreateFlags)0u,
   1690 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// topology
   1691 		VK_FALSE,														// primitiveRestartEnable
   1692 	};
   1693 	const VkViewport viewport =
   1694 	{
   1695 		(float)renderInfo.getViewportOffset().x(),	(float)renderInfo.getViewportOffset().y(),
   1696 		(float)renderInfo.getViewportSize().x(),	(float)renderInfo.getViewportSize().y(),
   1697 		0.0f, 1.0f
   1698 	};
   1699 	const VkRect2D scissor =
   1700 	{
   1701 		{ (deInt32)renderInfo.getViewportOffset().x(),	(deInt32)renderInfo.getViewportOffset().y() },
   1702 		{ renderInfo.getViewportSize().x(),				renderInfo.getViewportSize().y() }
   1703 	};
   1704 	const VkPipelineViewportStateCreateInfo viewportState =
   1705 	{
   1706 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
   1707 		DE_NULL,
   1708 		(VkPipelineViewportStateCreateFlags)0u,
   1709 		1u,
   1710 		&viewport,
   1711 		1u,
   1712 		&scissor
   1713 	};
   1714 	const VkPipelineRasterizationStateCreateInfo rasterState =
   1715 	{
   1716 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// sType
   1717 		DE_NULL,														// pNext
   1718 		(VkPipelineRasterizationStateCreateFlags)0u,
   1719 		VK_TRUE,														// depthClipEnable
   1720 		VK_FALSE,														// rasterizerDiscardEnable
   1721 		VK_POLYGON_MODE_FILL,											// fillMode
   1722 		VK_CULL_MODE_NONE,												// cullMode
   1723 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// frontFace
   1724 		VK_FALSE,														// depthBiasEnable
   1725 		0.0f,															// depthBias
   1726 		0.0f,															// depthBiasClamp
   1727 		0.0f,															// slopeScaledDepthBias
   1728 		1.0f															// lineWidth
   1729 	};
   1730 	const VkPipelineMultisampleStateCreateInfo multisampleState =
   1731 	{
   1732 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// sType
   1733 		DE_NULL,														// pNext
   1734 		(VkPipelineMultisampleStateCreateFlags)0u,
   1735 		*rasterSamples,													// rasterSamples
   1736 		VK_FALSE,														// sampleShadingEnable
   1737 		0.0f,															// minSampleShading
   1738 		DE_NULL,														// pSampleMask
   1739 		VK_FALSE,														// alphaToCoverageEnable
   1740 		VK_FALSE,														// alphaToOneEnable
   1741 	};
   1742 	const size_t stencilIndex = renderInfo.getSubpassIndex();
   1743 	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
   1744 	{
   1745 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// sType
   1746 		DE_NULL,													// pNext
   1747 		(VkPipelineDepthStencilStateCreateFlags)0u,
   1748 		VK_TRUE,													// depthTestEnable
   1749 		VK_TRUE,													// depthWriteEnable
   1750 		VK_COMPARE_OP_ALWAYS,										// depthCompareOp
   1751 		VK_FALSE,													// depthBoundsEnable
   1752 		VK_TRUE,													// stencilTestEnable
   1753 		{
   1754 			VK_STENCIL_OP_REPLACE,									// stencilFailOp
   1755 			VK_STENCIL_OP_REPLACE,									// stencilPassOp
   1756 			VK_STENCIL_OP_REPLACE,									// stencilDepthFailOp
   1757 			VK_COMPARE_OP_ALWAYS,									// stencilCompareOp
   1758 			~0u,													// stencilCompareMask
   1759 			~0u,													// stencilWriteMask
   1760 			((stencilIndex % 2) == 0) ? ~0x0u : 0x0u				// stencilReference
   1761 		},															// front
   1762 		{
   1763 			VK_STENCIL_OP_REPLACE,									// stencilFailOp
   1764 			VK_STENCIL_OP_REPLACE,									// stencilPassOp
   1765 			VK_STENCIL_OP_REPLACE,									// stencilDepthFailOp
   1766 			VK_COMPARE_OP_ALWAYS,									// stencilCompareOp
   1767 			~0u,													// stencilCompareMask
   1768 			~0u,													// stencilWriteMask
   1769 			((stencilIndex % 2) == 0) ? ~0x0u : 0x0u				// stencilReference
   1770 		},															// back
   1771 
   1772 		0.0f,														// minDepthBounds;
   1773 		1.0f														// maxDepthBounds;
   1774 	};
   1775 	const VkPipelineColorBlendStateCreateInfo blendState =
   1776 	{
   1777 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,			// sType
   1778 		DE_NULL,															// pNext
   1779 		(VkPipelineColorBlendStateCreateFlags)0u,
   1780 		VK_FALSE,															// logicOpEnable
   1781 		VK_LOGIC_OP_COPY,													// logicOp
   1782 		(deUint32)attachmentBlendStates.size(),								// attachmentCount
   1783 		attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
   1784 		{ 0.0f, 0.0f, 0.0f, 0.0f }											// blendConst
   1785 	};
   1786 	const VkGraphicsPipelineCreateInfo createInfo =
   1787 	{
   1788 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// sType
   1789 		DE_NULL,											// pNext
   1790 		(VkPipelineCreateFlags)0u,
   1791 
   1792 		2,													// stageCount
   1793 		shaderStages,										// pStages
   1794 
   1795 		&vertexInputState,									// pVertexInputState
   1796 		&inputAssemblyState,								// pInputAssemblyState
   1797 		DE_NULL,											// pTessellationState
   1798 		&viewportState,										// pViewportState
   1799 		&rasterState,										// pRasterState
   1800 		&multisampleState,									// pMultisampleState
   1801 		&depthStencilState,									// pDepthStencilState
   1802 		&blendState,										// pColorBlendState
   1803 		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// pDynamicState
   1804 		pipelineLayout,										// layout
   1805 
   1806 		renderPass,											// renderPass
   1807 		renderInfo.getSubpassIndex(),						// subpass
   1808 		DE_NULL,											// basePipelineHandle
   1809 		0u													// basePipelineIndex
   1810 	};
   1811 
   1812 	return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
   1813 }
   1814 
   1815 class SubpassRenderer
   1816 {
   1817 public:
   1818 	SubpassRenderer (Context&										context,
   1819 					 const DeviceInterface&							vk,
   1820 					 VkDevice										device,
   1821 					 Allocator&										allocator,
   1822 					 VkRenderPass									renderPass,
   1823 					 VkFramebuffer									framebuffer,
   1824 					 VkCommandPool									commandBufferPool,
   1825 					 deUint32										queueFamilyIndex,
   1826 					 const vector<VkImage>&							attachmentImages,
   1827 					 const vector<pair<VkImageView, VkImageView> >&	attachmentViews,
   1828 					 const SubpassRenderInfo&						renderInfo,
   1829 					 const vector<Attachment>&						attachmentInfos)
   1830 		: m_renderInfo	(renderInfo)
   1831 	{
   1832 		const deUint32							subpassIndex	= renderInfo.getSubpassIndex();
   1833 		vector<VkDescriptorSetLayoutBinding>	bindings;
   1834 
   1835 		for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount();  colorAttachmentNdx++)
   1836 			m_colorAttachmentImages.push_back(attachmentImages[renderInfo.getColorAttachmentIndex(colorAttachmentNdx)]);
   1837 
   1838 		if (renderInfo.getDepthStencilAttachmentIndex())
   1839 			m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
   1840 
   1841 		if (renderInfo.getRenderQuad())
   1842 		{
   1843 			const RenderQuad&	renderQuad	= *renderInfo.getRenderQuad();
   1844 
   1845 			if (renderInfo.getInputAttachmentCount() > 0)
   1846 			{
   1847 				deUint32								bindingIndex	= 0;
   1848 
   1849 				for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
   1850 				{
   1851 					const Attachment			attachmentInfo	= attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
   1852 					const tcu::TextureFormat	format			= mapVkFormat(attachmentInfo.getFormat());
   1853 					const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
   1854 					const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
   1855 					const deUint32				bindingCount	= isDepthFormat && isStencilFormat ? 2u : 1u;
   1856 
   1857 					for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
   1858 					{
   1859 						const VkDescriptorSetLayoutBinding binding =
   1860 						{
   1861 							bindingIndex,
   1862 							vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
   1863 							1u,
   1864 							vk::VK_SHADER_STAGE_FRAGMENT_BIT,
   1865 							DE_NULL
   1866 						};
   1867 
   1868 						bindings.push_back(binding);
   1869 						bindingIndex++;
   1870 					}
   1871 				}
   1872 
   1873 				const VkDescriptorSetLayoutCreateInfo createInfo =
   1874 				{
   1875 					vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
   1876 					DE_NULL,
   1877 
   1878 					0u,
   1879 					(deUint32)bindings.size(),
   1880 					&bindings[0]
   1881 				};
   1882 
   1883 				m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
   1884 			}
   1885 
   1886 			const VkDescriptorSetLayout			descriptorSetLayout		= *m_descriptorSetLayout;
   1887 			const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
   1888 			{
   1889 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType;
   1890 				DE_NULL,												// pNext;
   1891 				(vk::VkPipelineLayoutCreateFlags)0,
   1892 				m_descriptorSetLayout ? 1u :0u ,						// setLayoutCount;
   1893 				m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL,	// pSetLayouts;
   1894 				0u,														// pushConstantRangeCount;
   1895 				DE_NULL,												// pPushConstantRanges;
   1896 			};
   1897 
   1898 			m_vertexShaderModule	= createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
   1899 			m_fragmentShaderModule	= createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
   1900 			m_pipelineLayout		= createPipelineLayout(vk, device, &pipelineLayoutParams);
   1901 			m_pipeline				= createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
   1902 
   1903 			m_vertexBuffer			= createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
   1904 			m_vertexBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
   1905 
   1906 			bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
   1907 			uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
   1908 
   1909 			if (renderInfo.getInputAttachmentCount() > 0)
   1910 			{
   1911 				{
   1912 					const VkDescriptorPoolSize poolSize =
   1913 					{
   1914 						vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
   1915 						// \note Reserve 2 per input attachment since depthStencil attachments require 2.
   1916 						renderInfo.getInputAttachmentCount() * 2u
   1917 					};
   1918 					const VkDescriptorPoolCreateInfo createInfo =
   1919 					{
   1920 						vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   1921 						DE_NULL,
   1922 						VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
   1923 
   1924 						// \note Reserve 2 per input attachment since depthStencil attachments require 2.
   1925 						renderInfo.getInputAttachmentCount() * 2u,
   1926 						1u,
   1927 						&poolSize
   1928 					};
   1929 
   1930 					m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
   1931 				}
   1932 				{
   1933 					const VkDescriptorSetAllocateInfo	allocateInfo =
   1934 					{
   1935 						vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
   1936 						DE_NULL,
   1937 
   1938 						*m_descriptorPool,
   1939 						1u,
   1940 						&descriptorSetLayout
   1941 					};
   1942 
   1943 					m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
   1944 				}
   1945 				{
   1946 					vector<VkWriteDescriptorSet>	writes			(bindings.size());
   1947 					vector<VkDescriptorImageInfo>	imageInfos		(bindings.size());
   1948 					deUint32						bindingIndex	= 0;
   1949 
   1950 					for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
   1951 					{
   1952 						const Attachment			attachmentInfo			= attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
   1953 						const tcu::TextureFormat	format					= mapVkFormat(attachmentInfo.getFormat());
   1954 						const bool					isDepthFormat			= tcu::hasDepthComponent(format.order);
   1955 						const bool					isStencilFormat			= tcu::hasStencilComponent(format.order);
   1956 						const VkImageLayout			inputAttachmentLayout	= renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
   1957 
   1958 						if (isDepthFormat && isStencilFormat)
   1959 						{
   1960 							{
   1961 								const VkDescriptorImageInfo	imageInfo =
   1962 								{
   1963 									(VkSampler)0,
   1964 									attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
   1965 									inputAttachmentLayout
   1966 								};
   1967 								imageInfos[bindingIndex] = imageInfo;
   1968 
   1969 								{
   1970 									const VkWriteDescriptorSet	write =
   1971 									{
   1972 										VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   1973 										DE_NULL,
   1974 
   1975 										*m_descriptorSet,
   1976 										bindingIndex,
   1977 										0u,
   1978 										1u,
   1979 										VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
   1980 										&imageInfos[bindingIndex],
   1981 										DE_NULL,
   1982 										DE_NULL
   1983 									};
   1984 									writes[bindingIndex] = write;
   1985 
   1986 									bindingIndex++;
   1987 								}
   1988 							}
   1989 							{
   1990 								const VkDescriptorImageInfo	imageInfo =
   1991 								{
   1992 									(VkSampler)0,
   1993 									attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
   1994 									inputAttachmentLayout
   1995 								};
   1996 								imageInfos[bindingIndex] = imageInfo;
   1997 
   1998 								{
   1999 									const VkWriteDescriptorSet	write =
   2000 									{
   2001 										VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   2002 										DE_NULL,
   2003 
   2004 										*m_descriptorSet,
   2005 										bindingIndex,
   2006 										0u,
   2007 										1u,
   2008 										VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
   2009 										&imageInfos[bindingIndex],
   2010 										DE_NULL,
   2011 										DE_NULL
   2012 									};
   2013 									writes[bindingIndex] = write;
   2014 
   2015 									bindingIndex++;
   2016 								}
   2017 							}
   2018 						}
   2019 						else
   2020 						{
   2021 							const VkDescriptorImageInfo	imageInfo =
   2022 							{
   2023 								(VkSampler)0,
   2024 								attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
   2025 								inputAttachmentLayout
   2026 							};
   2027 							imageInfos[bindingIndex] = imageInfo;
   2028 
   2029 							{
   2030 								const VkWriteDescriptorSet	write =
   2031 								{
   2032 									VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
   2033 									DE_NULL,
   2034 
   2035 									*m_descriptorSet,
   2036 									bindingIndex,
   2037 									0u,
   2038 									1u,
   2039 									VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
   2040 									&imageInfos[bindingIndex],
   2041 									DE_NULL,
   2042 									DE_NULL
   2043 								};
   2044 								writes[bindingIndex] = write;
   2045 
   2046 								bindingIndex++;
   2047 							}
   2048 						}
   2049 					}
   2050 
   2051 					vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
   2052 				}
   2053 			}
   2054 		}
   2055 
   2056 		if (renderInfo.isSecondary())
   2057 		{
   2058 			m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   2059 
   2060 			beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
   2061 			pushRenderCommands(vk, *m_commandBuffer);
   2062 			endCommandBuffer(vk, *m_commandBuffer);
   2063 		}
   2064 	}
   2065 
   2066 	bool isSecondary (void) const
   2067 	{
   2068 		return m_commandBuffer;
   2069 	}
   2070 
   2071 	VkCommandBuffer getCommandBuffer (void) const
   2072 	{
   2073 		DE_ASSERT(isSecondary());
   2074 		return *m_commandBuffer;
   2075 	}
   2076 
   2077 	void pushRenderCommands (const DeviceInterface&		vk,
   2078 							 VkCommandBuffer			commandBuffer)
   2079 	{
   2080 		if (!m_renderInfo.getColorClears().empty())
   2081 		{
   2082 			const vector<ColorClear>&	colorClears	(m_renderInfo.getColorClears());
   2083 
   2084 			for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
   2085 			{
   2086 				const ColorClear&		colorClear	= colorClears[attachmentNdx];
   2087 				const VkClearAttachment	attachment	=
   2088 				{
   2089 					VK_IMAGE_ASPECT_COLOR_BIT,
   2090 					attachmentNdx,
   2091 					makeClearValue(colorClear.getColor()),
   2092 				};
   2093 				const VkClearRect		rect		=
   2094 				{
   2095 					{
   2096 						{ (deInt32)colorClear.getOffset().x(),	(deInt32)colorClear.getOffset().y()	},
   2097 						{ colorClear.getSize().x(),				colorClear.getSize().y()			}
   2098 					},					// rect
   2099 					0u,					// baseArrayLayer
   2100 					1u,					// layerCount
   2101 				};
   2102 
   2103 				vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
   2104 			}
   2105 		}
   2106 
   2107 		if (m_renderInfo.getDepthStencilClear())
   2108 		{
   2109 			const DepthStencilClear&	depthStencilClear	= *m_renderInfo.getDepthStencilClear();
   2110 			const deUint32				attachmentNdx		= m_renderInfo.getColorAttachmentCount();
   2111 			tcu::TextureFormat			format				= mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
   2112 			const VkClearAttachment		attachment			=
   2113 			{
   2114 				(VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
   2115 					| (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
   2116 				attachmentNdx,
   2117 				makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
   2118 			};
   2119 			const VkClearRect				rect				=
   2120 			{
   2121 				{
   2122 					{ (deInt32)depthStencilClear.getOffset().x(),	(deInt32)depthStencilClear.getOffset().y()	},
   2123 					{ depthStencilClear.getSize().x(),				depthStencilClear.getSize().y()				}
   2124 				},							// rect
   2125 				0u,							// baseArrayLayer
   2126 				1u,							// layerCount
   2127 			};
   2128 
   2129 			vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
   2130 		}
   2131 
   2132 		vector<VkImageMemoryBarrier>	selfDeps;
   2133 		VkPipelineStageFlags			srcStages = 0;
   2134 		VkPipelineStageFlags			dstStages = 0;
   2135 
   2136 		for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
   2137 		{
   2138 			for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
   2139 			{
   2140 				if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
   2141 				{
   2142 					const VkImageMemoryBarrier	barrier   =
   2143 					{
   2144 						VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
   2145 						DE_NULL,										// pNext
   2146 
   2147 						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// srcAccessMask
   2148 						VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// dstAccessMask
   2149 
   2150 						VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
   2151 						VK_IMAGE_LAYOUT_GENERAL,						// newLayout
   2152 
   2153 						VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex
   2154 						VK_QUEUE_FAMILY_IGNORED,						// destQueueFamilyIndex
   2155 
   2156 						m_colorAttachmentImages[colorAttachmentNdx],	// image
   2157 						{												// subresourceRange
   2158 							VK_IMAGE_ASPECT_COLOR_BIT,						// aspect
   2159 							0,												// baseMipLevel
   2160 							1,												// mipLevels
   2161 							0,												// baseArraySlice
   2162 							1												// arraySize
   2163 						}
   2164 					};
   2165 
   2166 					srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
   2167 					dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
   2168 
   2169 					selfDeps.push_back(barrier);
   2170 				}
   2171 			}
   2172 
   2173 			if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
   2174 			{
   2175 				const tcu::TextureFormat	format		= mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
   2176 				const bool					hasDepth	= hasDepthComponent(format.order);
   2177 				const bool					hasStencil	= hasStencilComponent(format.order);
   2178 				const VkImageMemoryBarrier	barrier		=
   2179 				{
   2180 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType;
   2181 					DE_NULL,										// pNext;
   2182 
   2183 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	// srcAccessMask
   2184 					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// dstAccessMask
   2185 
   2186 					VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
   2187 					VK_IMAGE_LAYOUT_GENERAL,						// newLayout;
   2188 
   2189 					VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
   2190 					VK_QUEUE_FAMILY_IGNORED,						// destQueueFamilyIndex;
   2191 
   2192 					m_depthStencilAttachmentImage,					// image;
   2193 					{												// subresourceRange;
   2194 						(hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
   2195 							| (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u),	// aspect;
   2196 						0,															// baseMipLevel;
   2197 						1,															// mipLevels;
   2198 						0,															// baseArraySlice;
   2199 						1															// arraySize;
   2200 					}
   2201 				};
   2202 
   2203 				srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
   2204 				dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
   2205 
   2206 				selfDeps.push_back(barrier);
   2207 			}
   2208 		}
   2209 
   2210 		if (!selfDeps.empty())
   2211 			vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
   2212 
   2213 		if (m_renderInfo.getRenderQuad())
   2214 		{
   2215 			const VkDeviceSize	offset			= 0;
   2216 			const VkBuffer		vertexBuffer	= *m_vertexBuffer;
   2217 
   2218 			vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
   2219 
   2220 			if (m_descriptorSet)
   2221 			{
   2222 				const VkDescriptorSet descriptorSet = *m_descriptorSet;
   2223 				vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
   2224 			}
   2225 
   2226 			vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
   2227 			vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
   2228 		}
   2229 	}
   2230 
   2231 private:
   2232 	const SubpassRenderInfo		m_renderInfo;
   2233 	Move<VkCommandBuffer>		m_commandBuffer;
   2234 	Move<VkPipeline>			m_pipeline;
   2235 	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
   2236 	Move<VkPipelineLayout>		m_pipelineLayout;
   2237 
   2238 	Move<VkShaderModule>		m_vertexShaderModule;
   2239 	Move<VkShaderModule>		m_fragmentShaderModule;
   2240 
   2241 	Move<VkDescriptorPool>		m_descriptorPool;
   2242 	Move<VkDescriptorSet>		m_descriptorSet;
   2243 	Move<VkBuffer>				m_vertexBuffer;
   2244 	de::MovePtr<Allocation>		m_vertexBufferMemory;
   2245 	vector<VkImage>				m_colorAttachmentImages;
   2246 	VkImage						m_depthStencilAttachmentImage;
   2247 };
   2248 
   2249 void pushImageInitializationCommands (const DeviceInterface&								vk,
   2250 									  VkCommandBuffer										commandBuffer,
   2251 									  const vector<Attachment>&								attachmentInfo,
   2252 									  const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
   2253 									  deUint32												queueIndex,
   2254 									  const vector<Maybe<VkClearValue> >&					clearValues)
   2255 {
   2256 	{
   2257 		vector<VkImageMemoryBarrier>	initializeLayouts;
   2258 
   2259 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
   2260 		{
   2261 			if (!clearValues[attachmentNdx])
   2262 				continue;
   2263 
   2264 			const VkImageMemoryBarrier barrier =
   2265 			{
   2266 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,							// sType;
   2267 				DE_NULL,														// pNext;
   2268 
   2269 				(VkAccessFlags)0,												// srcAccessMask
   2270 				getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT,			// dstAccessMask
   2271 
   2272 				VK_IMAGE_LAYOUT_UNDEFINED,										// oldLayout
   2273 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,							// newLayout;
   2274 
   2275 				queueIndex,														// srcQueueFamilyIndex;
   2276 				queueIndex,														// destQueueFamilyIndex;
   2277 
   2278 				attachmentResources[attachmentNdx]->getImage(),					// image;
   2279 				{																// subresourceRange;
   2280 					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
   2281 					0,																	// baseMipLevel;
   2282 					1,																	// mipLevels;
   2283 					0,																	// baseArraySlice;
   2284 					1																	// arraySize;
   2285 				}
   2286 			};
   2287 
   2288 			initializeLayouts.push_back(barrier);
   2289 		}
   2290 
   2291 		if (!initializeLayouts.empty())
   2292 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
   2293 								  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
   2294 								  0, (const VkMemoryBarrier*)DE_NULL,
   2295 								  0, (const VkBufferMemoryBarrier*)DE_NULL,
   2296 								  (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
   2297 	}
   2298 
   2299 	for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
   2300 	{
   2301 		if (!clearValues[attachmentNdx])
   2302 			continue;
   2303 
   2304 		const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
   2305 
   2306 		if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
   2307 		{
   2308 			const float						clearNan		= tcu::Float32::nan().asFloat();
   2309 			const float						clearDepth		= hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
   2310 			const deUint32					clearStencil	= hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
   2311 			const VkClearDepthStencilValue	depthStencil	=
   2312 			{
   2313 				clearDepth,
   2314 				clearStencil
   2315 			};
   2316 			const VkImageSubresourceRange range =
   2317 			{
   2318 				(VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
   2319 									 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
   2320 				0,
   2321 				1,
   2322 				0,
   2323 				1
   2324 			};
   2325 
   2326 			vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
   2327 		}
   2328 		else
   2329 		{
   2330 			const VkImageSubresourceRange	range		=
   2331 			{
   2332 				VK_IMAGE_ASPECT_COLOR_BIT,	// aspectMask;
   2333 				0,							// baseMipLevel;
   2334 				1,							// mipLevels;
   2335 				0,							// baseArrayLayer;
   2336 				1							// layerCount;
   2337 			};
   2338 			const VkClearColorValue			clearColor	= clearValues[attachmentNdx]->color;
   2339 
   2340 			vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
   2341 		}
   2342 	}
   2343 
   2344 	{
   2345 		vector<VkImageMemoryBarrier>	renderPassLayouts;
   2346 
   2347 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
   2348 		{
   2349 			const VkImageLayout			oldLayout	= clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
   2350 			const VkImageMemoryBarrier	barrier		=
   2351 			{
   2352 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// sType;
   2353 				DE_NULL,												// pNext;
   2354 
   2355 				(oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0),					// srcAccessMask
   2356 				getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()),	// dstAccessMask
   2357 
   2358 				oldLayout,												// oldLayout
   2359 				attachmentInfo[attachmentNdx].getInitialLayout(),		// newLayout;
   2360 
   2361 				queueIndex,												// srcQueueFamilyIndex;
   2362 				queueIndex,												// destQueueFamilyIndex;
   2363 
   2364 				attachmentResources[attachmentNdx]->getImage(),			// image;
   2365 				{														// subresourceRange;
   2366 					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
   2367 					0,																	// baseMipLevel;
   2368 					1,																	// mipLevels;
   2369 					0,																	// baseArraySlice;
   2370 					1																	// arraySize;
   2371 				}
   2372 			};
   2373 
   2374 			renderPassLayouts.push_back(barrier);
   2375 		}
   2376 
   2377 		if (!renderPassLayouts.empty())
   2378 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
   2379 								  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
   2380 								  0, (const VkMemoryBarrier*)DE_NULL,
   2381 								  0, (const VkBufferMemoryBarrier*)DE_NULL,
   2382 								  (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
   2383 	}
   2384 }
   2385 
   2386 void pushRenderPassCommands (const DeviceInterface&							vk,
   2387 							 VkCommandBuffer								commandBuffer,
   2388 							 VkRenderPass									renderPass,
   2389 							 VkFramebuffer									framebuffer,
   2390 							 const vector<de::SharedPtr<SubpassRenderer> >&	subpassRenderers,
   2391 							 const UVec2&									renderPos,
   2392 							 const UVec2&									renderSize,
   2393 							 const vector<Maybe<VkClearValue> >&			renderPassClearValues,
   2394 							 TestConfig::RenderTypes						render)
   2395 {
   2396 	const float				clearNan				= tcu::Float32::nan().asFloat();
   2397 	vector<VkClearValue>	attachmentClearValues;
   2398 
   2399 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
   2400 	{
   2401 		if (renderPassClearValues[attachmentNdx])
   2402 			attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
   2403 		else
   2404 			attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
   2405 	}
   2406 
   2407 	{
   2408 		const VkRect2D renderArea =
   2409 		{
   2410 			{ (deInt32)renderPos.x(),	(deInt32)renderPos.y()	},
   2411 			{ renderSize.x(),			renderSize.y()			}
   2412 		};
   2413 
   2414 		for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
   2415 		{
   2416 			const VkSubpassContents	contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
   2417 
   2418 			if (subpassNdx == 0)
   2419 				cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
   2420 			else
   2421 				vk.cmdNextSubpass(commandBuffer, contents);
   2422 
   2423 			if (render)
   2424 			{
   2425 				if (contents == VK_SUBPASS_CONTENTS_INLINE)
   2426 				{
   2427 					subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
   2428 				}
   2429 				else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
   2430 				{
   2431 					const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
   2432 					vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
   2433 				}
   2434 				else
   2435 					DE_FATAL("Invalid contents");
   2436 			}
   2437 		}
   2438 
   2439 		vk.cmdEndRenderPass(commandBuffer);
   2440 	}
   2441 }
   2442 
   2443 void pushReadImagesToBuffers (const DeviceInterface&								vk,
   2444 							  VkCommandBuffer										commandBuffer,
   2445 							  deUint32												queueIndex,
   2446 
   2447 							  const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
   2448 							  const vector<Attachment>&								attachmentInfo,
   2449 							  const vector<bool>&									isLazy,
   2450 
   2451 							  const UVec2&											targetSize)
   2452 {
   2453 	{
   2454 		vector<VkImageMemoryBarrier>	imageBarriers;
   2455 
   2456 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
   2457 		{
   2458 			if (isLazy[attachmentNdx])
   2459 				continue;
   2460 
   2461 			const VkImageLayout			oldLayout	= attachmentInfo[attachmentNdx].getFinalLayout();
   2462 			const VkImageMemoryBarrier	barrier		=
   2463 			{
   2464 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,							// sType
   2465 				DE_NULL,														// pNext
   2466 
   2467 				getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout),	// srcAccessMask
   2468 				getAllMemoryReadFlags(),										// dstAccessMask
   2469 
   2470 				oldLayout,														// oldLayout
   2471 				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,							// newLayout
   2472 
   2473 				queueIndex,														// srcQueueFamilyIndex
   2474 				queueIndex,														// destQueueFamilyIndex
   2475 
   2476 				attachmentResources[attachmentNdx]->getImage(),					// image
   2477 				{																// subresourceRange
   2478 					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
   2479 					0,																	// baseMipLevel
   2480 					1,																	// mipLevels
   2481 					0,																	// baseArraySlice
   2482 					1																	// arraySize
   2483 				}
   2484 			};
   2485 
   2486 			imageBarriers.push_back(barrier);
   2487 		}
   2488 
   2489 		if (!imageBarriers.empty())
   2490 			vk.cmdPipelineBarrier(commandBuffer,
   2491 								  getAllPipelineStageFlags(),
   2492 								  getAllPipelineStageFlags(),
   2493 								  (VkDependencyFlags)0,
   2494 								  0, (const VkMemoryBarrier*)DE_NULL,
   2495 								  0, (const VkBufferMemoryBarrier*)DE_NULL,
   2496 								  (deUint32)imageBarriers.size(), &imageBarriers[0]);
   2497 	}
   2498 
   2499 	for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
   2500 	{
   2501 		if (isLazy[attachmentNdx])
   2502 			continue;
   2503 
   2504 		const tcu::TextureFormat::ChannelOrder	order	= mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
   2505 		const VkBufferImageCopy					rect	=
   2506 		{
   2507 			0, // bufferOffset
   2508 			0, // bufferRowLength
   2509 			0, // bufferImageHeight
   2510 			{							// imageSubresource
   2511 				(vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order),	// aspect
   2512 				0,						// mipLevel
   2513 				0,						// arraySlice
   2514 				1						// arraySize
   2515 			},
   2516 			{ 0, 0, 0 },				// imageOffset
   2517 			{ targetSize.x(), targetSize.y(), 1u }		// imageExtent
   2518 		};
   2519 
   2520 		vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
   2521 
   2522 		if (tcu::TextureFormat::DS == order)
   2523 		{
   2524 			const VkBufferImageCopy stencilRect =
   2525 			{
   2526 				0,										// bufferOffset
   2527 				0,										// bufferRowLength
   2528 				0,										// bufferImageHeight
   2529 				{									// imageSubresource
   2530 					VK_IMAGE_ASPECT_STENCIL_BIT,	// aspect
   2531 					0,								// mipLevel
   2532 					0,								// arraySlice
   2533 					1								// arraySize
   2534 				},
   2535 				{ 0, 0, 0 },							// imageOffset
   2536 				{ targetSize.x(), targetSize.y(), 1u }	// imageExtent
   2537 			};
   2538 
   2539 			vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
   2540 		}
   2541 	}
   2542 
   2543 	{
   2544 		vector<VkBufferMemoryBarrier>	bufferBarriers;
   2545 
   2546 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
   2547 		{
   2548 			if (isLazy[attachmentNdx])
   2549 				continue;
   2550 
   2551 			const tcu::TextureFormat::ChannelOrder	order			= mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
   2552 			const VkBufferMemoryBarrier				bufferBarrier	=
   2553 			{
   2554 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   2555 				DE_NULL,
   2556 
   2557 				getAllMemoryWriteFlags(),
   2558 				getAllMemoryReadFlags(),
   2559 
   2560 				queueIndex,
   2561 				queueIndex,
   2562 
   2563 				attachmentResources[attachmentNdx]->getBuffer(),
   2564 				0,
   2565 				attachmentResources[attachmentNdx]->getBufferSize()
   2566 			};
   2567 
   2568 			bufferBarriers.push_back(bufferBarrier);
   2569 
   2570 			if (tcu::TextureFormat::DS == order)
   2571 			{
   2572 				const VkBufferMemoryBarrier secondaryBufferBarrier =
   2573 				{
   2574 					VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
   2575 					DE_NULL,
   2576 
   2577 					getAllMemoryWriteFlags(),
   2578 					getAllMemoryReadFlags(),
   2579 
   2580 					queueIndex,
   2581 					queueIndex,
   2582 
   2583 					attachmentResources[attachmentNdx]->getSecondaryBuffer(),
   2584 					0,
   2585 					attachmentResources[attachmentNdx]->getSecondaryBufferSize()
   2586 				};
   2587 
   2588 				bufferBarriers.push_back(secondaryBufferBarrier);
   2589 			}
   2590 		}
   2591 
   2592 		if (!bufferBarriers.empty())
   2593 			vk.cmdPipelineBarrier(commandBuffer,
   2594 								  getAllPipelineStageFlags(),
   2595 								  getAllPipelineStageFlags(),
   2596 								  (VkDependencyFlags)0,
   2597 								  0, (const VkMemoryBarrier*)DE_NULL,
   2598 								  (deUint32)bufferBarriers.size(), &bufferBarriers[0],
   2599 								  0, (const VkImageMemoryBarrier*)DE_NULL);
   2600 	}
   2601 }
   2602 
   2603 class PixelValue
   2604 {
   2605 public:
   2606 				PixelValue		(const Maybe<bool>&	x = nothing<bool>(),
   2607 								 const Maybe<bool>&	y = nothing<bool>(),
   2608 								 const Maybe<bool>&	z = nothing<bool>(),
   2609 								 const Maybe<bool>&	w = nothing<bool>());
   2610 
   2611 	void		setUndefined	(size_t ndx);
   2612 	void		setValue		(size_t ndx, bool value);
   2613 	Maybe<bool>	getValue		(size_t ndx) const;
   2614 
   2615 private:
   2616 	deUint16	m_status;
   2617 };
   2618 
   2619 PixelValue::PixelValue (const Maybe<bool>&	x,
   2620 						const Maybe<bool>&	y,
   2621 						const Maybe<bool>&	z,
   2622 						const Maybe<bool>&	w)
   2623 	: m_status (0)
   2624 {
   2625 	const Maybe<bool> values[] =
   2626 	{
   2627 		x, y, z, w
   2628 	};
   2629 
   2630 	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
   2631 	{
   2632 		if (values[ndx])
   2633 			setValue(ndx, *values[ndx]);
   2634 		else
   2635 			setUndefined(ndx);
   2636 	}
   2637 
   2638 	DE_ASSERT(m_status <= 0xFFu);
   2639 }
   2640 
   2641 void PixelValue::setUndefined (size_t ndx)
   2642 {
   2643 	DE_ASSERT(ndx < 4);
   2644 	DE_ASSERT(m_status <= 0xFFu);
   2645 
   2646 	m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
   2647 	DE_ASSERT(m_status <= 0xFFu);
   2648 }
   2649 
   2650 void PixelValue::setValue (size_t ndx, bool value)
   2651 {
   2652 	DE_ASSERT(ndx < 4);
   2653 	DE_ASSERT(m_status <= 0xFFu);
   2654 
   2655 	m_status |= (deUint16)(0x1u << (ndx * 2));
   2656 
   2657 	if (value)
   2658 		m_status |= (deUint16)(0x1u << (ndx * 2 + 1));
   2659 	else
   2660 		m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
   2661 
   2662 	DE_ASSERT(m_status <= 0xFFu);
   2663 }
   2664 
   2665 Maybe<bool> PixelValue::getValue (size_t ndx) const
   2666 {
   2667 	DE_ASSERT(ndx < 4);
   2668 	DE_ASSERT(m_status <= 0xFFu);
   2669 
   2670 	if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
   2671 	{
   2672 		return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
   2673 	}
   2674 	else
   2675 		return nothing<bool>();
   2676 }
   2677 
   2678 void clearReferenceValues (vector<PixelValue>&	values,
   2679 						   const UVec2&			targetSize,
   2680 						   const UVec2&			offset,
   2681 						   const UVec2&			size,
   2682 						   const BVec4&			mask,
   2683 						   const PixelValue&	value)
   2684 {
   2685 	DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
   2686 	DE_ASSERT(offset.x() + size.x() <= targetSize.x());
   2687 	DE_ASSERT(offset.y() + size.y() <= targetSize.y());
   2688 
   2689 	for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
   2690 	for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
   2691 	{
   2692 		for (int compNdx = 0; compNdx < 4; compNdx++)
   2693 		{
   2694 			if (mask[compNdx])
   2695 			{
   2696 				if (value.getValue(compNdx))
   2697 					values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
   2698 				else
   2699 					values[x + y * targetSize.x()].setUndefined(compNdx);
   2700 			}
   2701 		}
   2702 	}
   2703 }
   2704 
   2705 void markUndefined (vector<PixelValue>&	values,
   2706 					const BVec4&		mask,
   2707 					const UVec2&		targetSize,
   2708 					const UVec2&		offset,
   2709 					const UVec2&		size)
   2710 {
   2711 	DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
   2712 
   2713 	for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
   2714 	for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
   2715 	{
   2716 		for (int compNdx = 0; compNdx < 4; compNdx++)
   2717 		{
   2718 			if (mask[compNdx])
   2719 				values[x + y * targetSize.x()].setUndefined(compNdx);
   2720 		}
   2721 	}
   2722 }
   2723 
   2724 PixelValue clearValueToPixelValue (const VkClearValue&			value,
   2725 								   const tcu::TextureFormat&	format)
   2726 {
   2727 	const bool	isDepthAttachment			= hasDepthComponent(format.order);
   2728 	const bool	isStencilAttachment			= hasStencilComponent(format.order);
   2729 	const bool	isDepthOrStencilAttachment	= isDepthAttachment || isStencilAttachment;
   2730 	PixelValue	pixelValue;
   2731 
   2732 	if (isDepthOrStencilAttachment)
   2733 	{
   2734 		if (isDepthAttachment)
   2735 		{
   2736 			if (value.depthStencil.depth == 1.0f)
   2737 				pixelValue.setValue(0, true);
   2738 			else if (value.depthStencil.depth == 0.0f)
   2739 				pixelValue.setValue(0, false);
   2740 			else
   2741 				DE_FATAL("Unknown depth value");
   2742 		}
   2743 
   2744 		if (isStencilAttachment)
   2745 		{
   2746 			if (value.depthStencil.stencil == 0xFFu)
   2747 				pixelValue.setValue(1, true);
   2748 			else if (value.depthStencil.stencil == 0x0u)
   2749 				pixelValue.setValue(1, false);
   2750 			else
   2751 				DE_FATAL("Unknown stencil value");
   2752 		}
   2753 	}
   2754 	else
   2755 	{
   2756 		const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
   2757 		const tcu::BVec4				channelMask		= tcu::getTextureFormatChannelMask(format);
   2758 
   2759 		switch (channelClass)
   2760 		{
   2761 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
   2762 				for (int i = 0; i < 4; i++)
   2763 				{
   2764 					if (channelMask[i])
   2765 					{
   2766 						if (value.color.int32[i] == 1)
   2767 							pixelValue.setValue(i, true);
   2768 						else if (value.color.int32[i] == 0)
   2769 							pixelValue.setValue(i, false);
   2770 						else
   2771 							DE_FATAL("Unknown clear color value");
   2772 					}
   2773 				}
   2774 				break;
   2775 
   2776 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
   2777 				for (int i = 0; i < 4; i++)
   2778 				{
   2779 					if (channelMask[i])
   2780 					{
   2781 						if (value.color.uint32[i] == 1u)
   2782 							pixelValue.setValue(i, true);
   2783 						else if (value.color.uint32[i] == 0u)
   2784 							pixelValue.setValue(i, false);
   2785 						else
   2786 							DE_FATAL("Unknown clear color value");
   2787 					}
   2788 				}
   2789 				break;
   2790 
   2791 			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
   2792 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
   2793 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
   2794 				for (int i = 0; i < 4; i++)
   2795 				{
   2796 					if (channelMask[i])
   2797 					{
   2798 						if (value.color.float32[i] == 1.0f)
   2799 							pixelValue.setValue(i, true);
   2800 						else if (value.color.float32[i] == 0.0f)
   2801 							pixelValue.setValue(i, false);
   2802 						else
   2803 							DE_FATAL("Unknown clear color value");
   2804 					}
   2805 				}
   2806 				break;
   2807 
   2808 			default:
   2809 				DE_FATAL("Unknown channel class");
   2810 		}
   2811 	}
   2812 
   2813 	return pixelValue;
   2814 }
   2815 
   2816 void renderReferenceValues (vector<vector<PixelValue> >&		referenceAttachments,
   2817 							const RenderPass&					renderPassInfo,
   2818 							const UVec2&						targetSize,
   2819 							const vector<Maybe<VkClearValue> >&	imageClearValues,
   2820 							const vector<Maybe<VkClearValue> >&	renderPassClearValues,
   2821 							const vector<SubpassRenderInfo>&	subpassRenderInfo,
   2822 							const UVec2&						renderPos,
   2823 							const UVec2&						renderSize)
   2824 {
   2825 	const vector<Subpass>&	subpasses		= renderPassInfo.getSubpasses();
   2826 	vector<bool>			attachmentUsed	(renderPassInfo.getAttachments().size(), false);
   2827 
   2828 	referenceAttachments.resize(renderPassInfo.getAttachments().size());
   2829 
   2830 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   2831 	{
   2832 		const Attachment			attachment	= renderPassInfo.getAttachments()[attachmentNdx];
   2833 		const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
   2834 		vector<PixelValue>&			reference	= referenceAttachments[attachmentNdx];
   2835 
   2836 		reference.resize(targetSize.x() * targetSize.y());
   2837 
   2838 		if (imageClearValues[attachmentNdx])
   2839 			clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format));
   2840 	}
   2841 
   2842 	for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
   2843 	{
   2844 		const Subpass&						subpass				= subpasses[subpassNdx];
   2845 		const SubpassRenderInfo&			renderInfo			= subpassRenderInfo[subpassNdx];
   2846 		const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();
   2847 
   2848 		// Apply load op if attachment was used for the first time
   2849 		for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
   2850 		{
   2851 			const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
   2852 
   2853 			if (!attachmentUsed[attachmentIndex])
   2854 			{
   2855 				const Attachment&			attachment	= renderPassInfo.getAttachments()[attachmentIndex];
   2856 				vector<PixelValue>&			reference	= referenceAttachments[attachmentIndex];
   2857 				const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
   2858 
   2859 				DE_ASSERT(!tcu::hasDepthComponent(format.order));
   2860 				DE_ASSERT(!tcu::hasStencilComponent(format.order));
   2861 
   2862 				if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
   2863 					clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
   2864 				else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
   2865 					markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
   2866 
   2867 				attachmentUsed[attachmentIndex] = true;
   2868 			}
   2869 		}
   2870 
   2871 		// Apply load op to depth/stencil attachment if it was used for the first time
   2872 		if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   2873 		{
   2874 			const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
   2875 
   2876 			// Apply load op if attachment was used for the first time
   2877 			if (!attachmentUsed[attachmentIndex])
   2878 			{
   2879 				const Attachment&			attachment	= renderPassInfo.getAttachments()[attachmentIndex];
   2880 				vector<PixelValue>&			reference	= referenceAttachments[attachmentIndex];
   2881 				const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
   2882 
   2883 				if (tcu::hasDepthComponent(format.order))
   2884 				{
   2885 					if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
   2886 						clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
   2887 					else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
   2888 						markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
   2889 				}
   2890 
   2891 				if (tcu::hasStencilComponent(format.order))
   2892 				{
   2893 					if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
   2894 						clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
   2895 					else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
   2896 						markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
   2897 				}
   2898 
   2899 				attachmentUsed[attachmentIndex] = true;
   2900 			}
   2901 		}
   2902 
   2903 		for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
   2904 		{
   2905 			const ColorClear&			colorClear		= renderInfo.getColorClears()[colorClearNdx];
   2906 			const UVec2					offset			= colorClear.getOffset();
   2907 			const UVec2					size			= colorClear.getSize();
   2908 			const deUint32				attachmentIndex	= subpass.getColorAttachments()[colorClearNdx].getAttachment();
   2909 			const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   2910 			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   2911 			vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
   2912 			VkClearValue				value;
   2913 
   2914 			value.color = colorClear.getColor();
   2915 
   2916 			clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format));
   2917 		}
   2918 
   2919 		if (renderInfo.getDepthStencilClear())
   2920 		{
   2921 			const DepthStencilClear&	dsClear			= *renderInfo.getDepthStencilClear();
   2922 			const UVec2					offset			= dsClear.getOffset();
   2923 			const UVec2					size			= dsClear.getSize();
   2924 			const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
   2925 			const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   2926 			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   2927 			const bool					hasStencil		= tcu::hasStencilComponent(format.order);
   2928 			const bool					hasDepth		= tcu::hasDepthComponent(format.order);
   2929 			vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
   2930 			VkClearValue				value;
   2931 
   2932 			value.depthStencil.depth = dsClear.getDepth();
   2933 			value.depthStencil.stencil = dsClear.getStencil();
   2934 
   2935 			clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format));
   2936 		}
   2937 
   2938 		if (renderInfo.getRenderQuad())
   2939 		{
   2940 			const RenderQuad&	renderQuad	= *renderInfo.getRenderQuad();
   2941 			const Vec2			posA		= renderQuad.getCornerA();
   2942 			const Vec2			posB		= renderQuad.getCornerB();
   2943 			const Vec2			origin		= Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
   2944 			const Vec2			p			= Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
   2945 			const IVec2			posAI		(deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
   2946 											 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
   2947 			const IVec2			posBI		(deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
   2948 											 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
   2949 
   2950 			DE_ASSERT(posAI.x() < posBI.x());
   2951 			DE_ASSERT(posAI.y() < posBI.y());
   2952 
   2953 			if (subpass.getInputAttachments().empty())
   2954 			{
   2955 				for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
   2956 				{
   2957 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
   2958 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   2959 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   2960 					const tcu::BVec4			channelMask		= tcu::getTextureFormatChannelMask(format);
   2961 					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
   2962 
   2963 					for (int y = posAI.y(); y < (int)posBI.y(); y++)
   2964 					for (int x = posAI.x(); x < (int)posBI.x(); x++)
   2965 					{
   2966 						for (int compNdx = 0; compNdx < 4; compNdx++)
   2967 						{
   2968 							const size_t	index	= subpassNdx + attachmentIndex + compNdx;
   2969 							const BoolOp	op		= boolOpFromIndex(index);
   2970 							const bool		boolX	= x % 2 == (int)(index % 2);
   2971 							const bool		boolY	= y % 2 == (int)((index / 2) % 2);
   2972 
   2973 							if (channelMask[compNdx])
   2974 								reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
   2975 						}
   2976 					}
   2977 				}
   2978 
   2979 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   2980 				{
   2981 					const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
   2982 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   2983 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   2984 					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
   2985 
   2986 					for (int y = posAI.y(); y < (int)posBI.y(); y++)
   2987 					for (int x = posAI.x(); x < (int)posBI.x(); x++)
   2988 					{
   2989 						if (tcu::hasDepthComponent(format.order))
   2990 						{
   2991 							const size_t	index	= subpassNdx + 1;
   2992 							const BoolOp	op		= boolOpFromIndex(index);
   2993 							const bool		boolX	= x % 2 == (int)(index % 2);
   2994 							const bool		boolY	= y % 2 == (int)((index / 2) % 2);
   2995 
   2996 							reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
   2997 						}
   2998 
   2999 						if (tcu::hasStencilComponent(format.order))
   3000 						{
   3001 							const size_t	index	= subpassNdx;
   3002 							reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
   3003 						}
   3004 					}
   3005 				}
   3006 			}
   3007 			else
   3008 			{
   3009 				size_t					outputComponentCount	= 0;
   3010 				vector<Maybe<bool> >	inputs;
   3011 
   3012 				DE_ASSERT(posAI.x() < posBI.x());
   3013 				DE_ASSERT(posAI.y() < posBI.y());
   3014 
   3015 				for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
   3016 				{
   3017 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
   3018 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   3019 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3020 					const int					componentCount	= tcu::getNumUsedChannels(format.order);
   3021 
   3022 					outputComponentCount += (size_t)componentCount;
   3023 				}
   3024 
   3025 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   3026 					outputComponentCount++;
   3027 
   3028 				for (int y = posAI.y(); y < (int)posBI.y(); y++)
   3029 				for (int x = posAI.x(); x < (int)posBI.x(); x++)
   3030 				{
   3031 					for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
   3032 					{
   3033 						const deUint32				attachmentIndex	= subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
   3034 						const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   3035 						const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3036 						const int					componentCount	= tcu::getNumUsedChannels(format.order);
   3037 
   3038 						for (int compNdx = 0; compNdx < componentCount; compNdx++)
   3039 							inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
   3040 					}
   3041 
   3042 					const size_t inputsPerOutput = inputs.size() >= outputComponentCount
   3043 													? ((inputs.size() / outputComponentCount)
   3044 														+ ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
   3045 													: 1;
   3046 
   3047 					size_t outputValueNdx = 0;
   3048 
   3049 					for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
   3050 					{
   3051 						const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
   3052 						const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   3053 						const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3054 						vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
   3055 						const int					componentCount	= tcu::getNumUsedChannels(format.order);
   3056 
   3057 						for (int compNdx = 0; compNdx < componentCount; compNdx++)
   3058 						{
   3059 							const size_t	index	= subpassNdx + attachmentIndex + outputValueNdx;
   3060 							const BoolOp	op		= boolOpFromIndex(index);
   3061 							const bool		boolX	= x % 2 == (int)(index % 2);
   3062 							const bool		boolY	= y % 2 == (int)((index / 2) % 2);
   3063 							Maybe<bool>		output	= tcu::just(performBoolOp(op, boolX, boolY));
   3064 
   3065 							for (size_t i = 0; i < inputsPerOutput; i++)
   3066 							{
   3067 								if (!output)
   3068 									break;
   3069 								else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
   3070 									output = tcu::nothing<bool>();
   3071 								else
   3072 									output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
   3073 							}
   3074 
   3075 							if (output)
   3076 								reference[x + y * targetSize.x()].setValue(compNdx, *output);
   3077 							else
   3078 								reference[x + y * targetSize.x()].setUndefined(compNdx);
   3079 						}
   3080 
   3081 						outputValueNdx += componentCount;
   3082 					}
   3083 
   3084 					if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   3085 					{
   3086 						const deUint32		attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
   3087 						vector<PixelValue>&	reference		= referenceAttachments[attachmentIndex];
   3088 						const size_t		index			= subpassNdx + attachmentIndex;
   3089 						const BoolOp		op				= boolOpFromIndex(index);
   3090 						const bool			boolX			= x % 2 == (int)(index % 2);
   3091 						const bool			boolY			= y % 2 == (int)((index / 2) % 2);
   3092 						Maybe<bool>			output			= tcu::just(performBoolOp(op, boolX, boolY));
   3093 
   3094 						for (size_t i = 0; i < inputsPerOutput; i++)
   3095 						{
   3096 							if (!output)
   3097 								break;
   3098 							else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
   3099 								output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
   3100 							else
   3101 								output = tcu::nothing<bool>();
   3102 						}
   3103 
   3104 						if (output)
   3105 							reference[x + y * targetSize.x()].setValue(0, *output);
   3106 						else
   3107 							reference[x + y * targetSize.x()].setUndefined(0);
   3108 					}
   3109 
   3110 					inputs.clear();
   3111 				}
   3112 
   3113 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   3114 				{
   3115 					const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
   3116 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
   3117 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3118 					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
   3119 
   3120 					if (tcu::hasStencilComponent(format.order))
   3121 					{
   3122 						for (int y = posAI.y(); y < (int)posBI.y(); y++)
   3123 						for (int x = posAI.x(); x < (int)posBI.x(); x++)
   3124 						{
   3125 							const size_t	index	= subpassNdx;
   3126 							reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
   3127 						}
   3128 					}
   3129 				}
   3130 			}
   3131 		}
   3132 	}
   3133 
   3134 	// Mark all attachments that were used but not stored as undefined
   3135 	for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
   3136 	{
   3137 		const Attachment			attachment					= renderPassInfo.getAttachments()[attachmentIndex];
   3138 		const tcu::TextureFormat	format						= mapVkFormat(attachment.getFormat());
   3139 		vector<PixelValue>&			reference					= referenceAttachments[attachmentIndex];
   3140 		const bool					isStencilAttachment			= hasStencilComponent(format.order);
   3141 		const bool					isDepthOrStencilAttachment	= hasDepthComponent(format.order) || isStencilAttachment;
   3142 
   3143 		if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
   3144 		{
   3145 			if (isDepthOrStencilAttachment)
   3146 				markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
   3147 			else
   3148 				markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
   3149 		}
   3150 
   3151 		if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
   3152 			markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
   3153 	}
   3154 }
   3155 
   3156 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>&			referenceImages,
   3157 									  const vector<vector<PixelValue> >&	referenceValues,
   3158 									  const UVec2&							targetSize,
   3159 									  const RenderPass&						renderPassInfo)
   3160 {
   3161 	referenceImages.resize(referenceValues.size());
   3162 
   3163 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   3164 	{
   3165 		const Attachment			attachment			= renderPassInfo.getAttachments()[attachmentNdx];
   3166 		const tcu::TextureFormat	format				= mapVkFormat(attachment.getFormat());
   3167 		const vector<PixelValue>&	reference			= referenceValues[attachmentNdx];
   3168 		const bool					hasDepth			= tcu::hasDepthComponent(format.order);
   3169 		const bool					hasStencil			= tcu::hasStencilComponent(format.order);
   3170 		const bool					hasDepthOrStencil	= hasDepth || hasStencil;
   3171 		tcu::TextureLevel&			referenceImage		= referenceImages[attachmentNdx];
   3172 
   3173 		referenceImage.setStorage(format, targetSize.x(), targetSize.y());
   3174 
   3175 		if (hasDepthOrStencil)
   3176 		{
   3177 			if (hasDepth)
   3178 			{
   3179 				const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
   3180 
   3181 				for (deUint32 y = 0; y < targetSize.y(); y++)
   3182 				for (deUint32 x = 0; x < targetSize.x(); x++)
   3183 				{
   3184 					if (reference[x + y * targetSize.x()].getValue(0))
   3185 					{
   3186 						if (*reference[x + y * targetSize.x()].getValue(0))
   3187 							depthAccess.setPixDepth(1.0f, x, y);
   3188 						else
   3189 							depthAccess.setPixDepth(0.0f, x, y);
   3190 					}
   3191 					else // Fill with 3x3 grid
   3192 						depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
   3193 				}
   3194 			}
   3195 
   3196 			if (hasStencil)
   3197 			{
   3198 				const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
   3199 
   3200 				for (deUint32 y = 0; y < targetSize.y(); y++)
   3201 				for (deUint32 x = 0; x < targetSize.x(); x++)
   3202 				{
   3203 					if (reference[x + y * targetSize.x()].getValue(1))
   3204 					{
   3205 						if (*reference[x + y * targetSize.x()].getValue(1))
   3206 							stencilAccess.setPixStencil(0xFFu, x, y);
   3207 						else
   3208 							stencilAccess.setPixStencil(0x0u, x, y);
   3209 					}
   3210 					else // Fill with 3x3 grid
   3211 						stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
   3212 				}
   3213 			}
   3214 		}
   3215 		else
   3216 		{
   3217 			for (deUint32 y = 0; y < targetSize.y(); y++)
   3218 			for (deUint32 x = 0; x < targetSize.x(); x++)
   3219 			{
   3220 				tcu::Vec4 color;
   3221 
   3222 				for (int compNdx = 0; compNdx < 4; compNdx++)
   3223 				{
   3224 					if (reference[x + y * targetSize.x()].getValue(compNdx))
   3225 					{
   3226 						if (*reference[x + y * targetSize.x()].getValue(compNdx))
   3227 							color[compNdx] = 1.0f;
   3228 						else
   3229 							color[compNdx] = 0.0f;
   3230 					}
   3231 					else // Fill with 3x3 grid
   3232 						color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
   3233 				}
   3234 
   3235 				referenceImage.getAccess().setPixel(color, x, y);
   3236 			}
   3237 		}
   3238 	}
   3239 }
   3240 
   3241 bool verifyColorAttachment (const vector<PixelValue>&		reference,
   3242 							const ConstPixelBufferAccess&	result,
   3243 							const PixelBufferAccess&		errorImage)
   3244 {
   3245 	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
   3246 	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
   3247 	bool		ok		= true;
   3248 
   3249 	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
   3250 	DE_ASSERT(result.getWidth() == errorImage.getWidth());
   3251 	DE_ASSERT(result.getHeight() == errorImage.getHeight());
   3252 
   3253 	for (int y = 0; y < result.getHeight(); y++)
   3254 	for (int x = 0; x < result.getWidth(); x++)
   3255 	{
   3256 		const Vec4			resultColor		= result.getPixel(x, y);
   3257 		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
   3258 		bool				pixelOk			= true;
   3259 
   3260 		for (int compNdx = 0; compNdx < 4; compNdx++)
   3261 		{
   3262 			const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
   3263 
   3264 			if (maybeValue)
   3265 			{
   3266 				const bool value = *maybeValue;
   3267 
   3268 				if ((value && (resultColor[compNdx] != 1.0f))
   3269 					|| (!value && resultColor[compNdx] != 0.0f))
   3270 					pixelOk = false;
   3271 			}
   3272 		}
   3273 
   3274 		if (!pixelOk)
   3275 		{
   3276 			errorImage.setPixel(red, x, y);
   3277 			ok = false;
   3278 		}
   3279 		else
   3280 			errorImage.setPixel(green, x, y);
   3281 	}
   3282 
   3283 	return ok;
   3284 }
   3285 
   3286 bool verifyDepthAttachment (const vector<PixelValue>&		reference,
   3287 							const ConstPixelBufferAccess&	result,
   3288 							const PixelBufferAccess&		errorImage)
   3289 {
   3290 	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
   3291 	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
   3292 	bool		ok		= true;
   3293 
   3294 	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
   3295 	DE_ASSERT(result.getWidth() == errorImage.getWidth());
   3296 	DE_ASSERT(result.getHeight() == errorImage.getHeight());
   3297 
   3298 	for (int y = 0; y < result.getHeight(); y++)
   3299 	for (int x = 0; x < result.getWidth(); x++)
   3300 	{
   3301 		bool pixelOk = true;
   3302 
   3303 		const float			resultDepth		= result.getPixDepth(x, y);
   3304 		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
   3305 		const Maybe<bool>	maybeValue		= referenceValue.getValue(0);
   3306 
   3307 		if (maybeValue)
   3308 		{
   3309 			const bool value = *maybeValue;
   3310 
   3311 			if ((value && (resultDepth != 1.0f))
   3312 				|| (!value && resultDepth != 0.0f))
   3313 				pixelOk = false;
   3314 		}
   3315 
   3316 		if (!pixelOk)
   3317 		{
   3318 			errorImage.setPixel(red, x, y);
   3319 			ok = false;
   3320 		}
   3321 		else
   3322 			errorImage.setPixel(green, x, y);
   3323 	}
   3324 
   3325 	return ok;
   3326 }
   3327 
   3328 bool verifyStencilAttachment (const vector<PixelValue>&		reference,
   3329 							  const ConstPixelBufferAccess&	result,
   3330 							  const PixelBufferAccess&		errorImage)
   3331 {
   3332 	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
   3333 	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
   3334 	bool		ok		= true;
   3335 
   3336 	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
   3337 	DE_ASSERT(result.getWidth() == errorImage.getWidth());
   3338 	DE_ASSERT(result.getHeight() == errorImage.getHeight());
   3339 
   3340 	for (int y = 0; y < result.getHeight(); y++)
   3341 	for (int x = 0; x < result.getWidth(); x++)
   3342 	{
   3343 		bool pixelOk = true;
   3344 
   3345 		const deUint32		resultStencil	= result.getPixStencil(x, y);
   3346 		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
   3347 		const Maybe<bool>	maybeValue		= referenceValue.getValue(1);
   3348 
   3349 		if (maybeValue)
   3350 		{
   3351 			const bool value = *maybeValue;
   3352 
   3353 			if ((value && (resultStencil != 0xFFu))
   3354 				|| (!value && resultStencil != 0x0u))
   3355 				pixelOk = false;
   3356 		}
   3357 
   3358 		if (!pixelOk)
   3359 		{
   3360 			errorImage.setPixel(red, x, y);
   3361 			ok = false;
   3362 		}
   3363 		else
   3364 			errorImage.setPixel(green, x, y);
   3365 	}
   3366 
   3367 	return ok;
   3368 }
   3369 
   3370 bool logAndVerifyImages (TestLog&											log,
   3371 						 const DeviceInterface&								vk,
   3372 						 VkDevice											device,
   3373 						 const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
   3374 						 const vector<bool>&								attachmentIsLazy,
   3375 						 const RenderPass&									renderPassInfo,
   3376 						 const vector<Maybe<VkClearValue> >&				renderPassClearValues,
   3377 						 const vector<Maybe<VkClearValue> >&				imageClearValues,
   3378 						 const vector<SubpassRenderInfo>&					subpassRenderInfo,
   3379 						 const UVec2&										targetSize,
   3380 						 const TestConfig&									config)
   3381 {
   3382 	vector<vector<PixelValue> >	referenceValues;
   3383 	vector<tcu::TextureLevel>	referenceAttachments;
   3384 	bool						isOk					= true;
   3385 
   3386 	log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
   3387 
   3388 	renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
   3389 	renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo);
   3390 
   3391 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   3392 	{
   3393 		if (!attachmentIsLazy[attachmentNdx])
   3394 		{
   3395 			const Attachment			attachment		= renderPassInfo.getAttachments()[attachmentNdx];
   3396 			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3397 
   3398 			if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
   3399 			{
   3400 				const tcu::TextureFormat	depthFormat			= getDepthCopyFormat(attachment.getFormat());
   3401 				const VkDeviceSize			depthBufferSize		= targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
   3402 				void* const					depthPtr			= attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
   3403 
   3404 				const tcu::TextureFormat	stencilFormat		= getStencilCopyFormat(attachment.getFormat());
   3405 				const VkDeviceSize			stencilBufferSize	= targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
   3406 				void* const					stencilPtr			= attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
   3407 
   3408 				const VkMappedMemoryRange	ranges[]			=
   3409 				{
   3410 					{
   3411 						VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,								// sType;
   3412 						DE_NULL,															// pNext;
   3413 						attachmentResources[attachmentNdx]->getResultMemory().getMemory(),	// mem;
   3414 						attachmentResources[attachmentNdx]->getResultMemory().getOffset(),	// offset;
   3415 						depthBufferSize														// size;
   3416 					},
   3417 					{
   3418 						VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,										// sType;
   3419 						DE_NULL,																	// pNext;
   3420 						attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(),	// mem;
   3421 						attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(),	// offset;
   3422 						stencilBufferSize															// size;
   3423 					}
   3424 				};
   3425 				VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
   3426 
   3427 				{
   3428 					const ConstPixelBufferAccess	depthAccess			(depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
   3429 					const ConstPixelBufferAccess	stencilAccess		(stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
   3430 					tcu::TextureLevel				depthErrorImage		(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
   3431 					tcu::TextureLevel				stencilErrorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
   3432 
   3433 					log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
   3434 					log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
   3435 
   3436 					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
   3437 
   3438 					if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
   3439 						&& !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess()))
   3440 					{
   3441 						log << TestLog::Image("DepthAttachmentError" + de::toString(attachmentNdx), "Depth Attachment Error " + de::toString(attachmentNdx), depthErrorImage.getAccess());
   3442 						isOk = false;
   3443 					}
   3444 
   3445 					if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
   3446 						&& !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
   3447 					{
   3448 						log << TestLog::Image("StencilAttachmentError" + de::toString(attachmentNdx), "Stencil Attachment Error " + de::toString(attachmentNdx), stencilErrorImage.getAccess());
   3449 						isOk = false;
   3450 					}
   3451 				}
   3452 			}
   3453 			else
   3454 			{
   3455 				const VkDeviceSize			bufferSize	= targetSize.x() * targetSize.y() * format.getPixelSize();
   3456 				void* const					ptr			= attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
   3457 
   3458 				const VkMappedMemoryRange	range		=
   3459 				{
   3460 					VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,								// sType;
   3461 					DE_NULL,															// pNext;
   3462 					attachmentResources[attachmentNdx]->getResultMemory().getMemory(),	// mem;
   3463 					attachmentResources[attachmentNdx]->getResultMemory().getOffset(),	// offset;
   3464 					bufferSize															// size;
   3465 				};
   3466 				VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
   3467 
   3468 				if (tcu::hasDepthComponent(format.order))
   3469 				{
   3470 					const ConstPixelBufferAccess	access		(format, targetSize.x(), targetSize.y(), 1, ptr);
   3471 					tcu::TextureLevel				errorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
   3472 
   3473 					log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
   3474 					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
   3475 
   3476 					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
   3477 						&& !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
   3478 					{
   3479 						log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
   3480 						isOk = false;
   3481 					}
   3482 				}
   3483 				else if (tcu::hasStencilComponent(format.order))
   3484 				{
   3485 					const ConstPixelBufferAccess	access		(format, targetSize.x(), targetSize.y(), 1, ptr);
   3486 					tcu::TextureLevel				errorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
   3487 
   3488 					log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
   3489 					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
   3490 
   3491 					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
   3492 						&& !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
   3493 					{
   3494 						log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
   3495 						isOk = false;
   3496 					}
   3497 				}
   3498 				else
   3499 				{
   3500 					const ConstPixelBufferAccess	access		(format, targetSize.x(), targetSize.y(), 1, ptr);
   3501 					tcu::TextureLevel				errorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
   3502 
   3503 					log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
   3504 					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
   3505 
   3506 					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
   3507 						&& !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
   3508 					{
   3509 						log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
   3510 						isOk = false;
   3511 					}
   3512 				}
   3513 			}
   3514 		}
   3515 	}
   3516 
   3517 	return isOk;
   3518 }
   3519 
   3520 std::string getInputAttachmentType (VkFormat vkFormat)
   3521 {
   3522 	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
   3523 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
   3524 
   3525 	switch (channelClass)
   3526 	{
   3527 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
   3528 			return "isubpassInput";
   3529 
   3530 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
   3531 			return "usubpassInput";
   3532 
   3533 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
   3534 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
   3535 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
   3536 			return "subpassInput";
   3537 
   3538 		default:
   3539 			DE_FATAL("Unknown channel class");
   3540 			return "";
   3541 	}
   3542 }
   3543 
   3544 std::string getAttachmentType (VkFormat vkFormat)
   3545 {
   3546 	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
   3547 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
   3548 
   3549 	switch (channelClass)
   3550 	{
   3551 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
   3552 			return "ivec4";
   3553 
   3554 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
   3555 			return "uvec4";
   3556 
   3557 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
   3558 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
   3559 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
   3560 			return "vec4";
   3561 
   3562 		default:
   3563 			DE_FATAL("Unknown channel class");
   3564 			return "";
   3565 	}
   3566 }
   3567 
   3568 void createTestShaders (SourceCollections& dst, TestConfig config)
   3569 {
   3570 	if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
   3571 	{
   3572 		const vector<Subpass>&	subpasses	= config.renderPass.getSubpasses();
   3573 
   3574 		for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
   3575 		{
   3576 			const Subpass&		subpass					= subpasses[subpassNdx];
   3577 			deUint32			inputAttachmentBinding	= 0;
   3578 			std::ostringstream	vertexShader;
   3579 			std::ostringstream	fragmentShader;
   3580 
   3581 			vertexShader << "#version 310 es\n"
   3582 						 << "layout(location = 0) in highp vec2 a_position;\n"
   3583 						 << "void main (void) {\n"
   3584 						 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
   3585 						 << "}\n";
   3586 
   3587 			fragmentShader << "#version 310 es\n"
   3588 						   << "precision highp float;\n";
   3589 
   3590 			for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
   3591 			{
   3592 				const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
   3593 				const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
   3594 				const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3595 				const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
   3596 				const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
   3597 
   3598 				if (isDepthFormat || isStencilFormat)
   3599 				{
   3600 					if (isDepthFormat)
   3601 					{
   3602 						fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
   3603 						inputAttachmentBinding++;
   3604 					}
   3605 
   3606 					if (isStencilFormat)
   3607 					{
   3608 						fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
   3609 						inputAttachmentBinding++;
   3610 					}
   3611 				}
   3612 				else
   3613 				{
   3614 					const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
   3615 
   3616 					fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
   3617 					inputAttachmentBinding++;
   3618 				}
   3619 			}
   3620 
   3621 			for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
   3622 			{
   3623 				const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
   3624 				fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
   3625 			}
   3626 
   3627 			fragmentShader << "void main (void) {\n";
   3628 
   3629 			if (subpass.getInputAttachments().empty())
   3630 			{
   3631 				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
   3632 				{
   3633 					const deUint32		attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
   3634 					const std::string	attachmentType	= getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
   3635 
   3636 					fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4(";
   3637 
   3638 					for (size_t compNdx = 0; compNdx < 4; compNdx++)
   3639 					{
   3640 						const size_t	index	= subpassNdx + attachmentIndex + compNdx;
   3641 						const BoolOp	op		= boolOpFromIndex(index);
   3642 
   3643 						if (compNdx > 0)
   3644 							fragmentShader << ",\n\t\t";
   3645 
   3646 						fragmentShader	<< "((int(gl_FragCoord.x) % 2 == " << (index % 2)
   3647 										<< ") " << boolOpToString(op) << " ("
   3648 										<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
   3649 										<< ") ? 1.0 : 0.0)";
   3650 					}
   3651 
   3652 					fragmentShader << "));\n";
   3653 				}
   3654 
   3655 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   3656 				{
   3657 					const size_t	index	= subpassNdx + 1;
   3658 					const BoolOp	op		= boolOpFromIndex(index);
   3659 
   3660 					fragmentShader	<< "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
   3661 									<< ") " << boolOpToString(op) << " ("
   3662 									<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
   3663 									<< ") ? 1.0 : 0.0);\n";
   3664 				}
   3665 			}
   3666 			else
   3667 			{
   3668 				size_t	inputComponentCount		= 0;
   3669 				size_t	outputComponentCount	= 0;
   3670 
   3671 				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
   3672 				{
   3673 					const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
   3674 					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
   3675 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3676 					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
   3677 
   3678 					inputComponentCount += componentCount;
   3679 				}
   3680 
   3681 				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
   3682 				{
   3683 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
   3684 					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
   3685 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3686 					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
   3687 
   3688 					outputComponentCount += componentCount;
   3689 				}
   3690 
   3691 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   3692 					outputComponentCount++;
   3693 
   3694 				const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
   3695 												? ((inputComponentCount / outputComponentCount)
   3696 													+ ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
   3697 												: 1;
   3698 
   3699 				fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n"
   3700 								  "\tbool outputs[" << outputComponentCount << "];\n";
   3701 
   3702 				size_t inputValueNdx = 0;
   3703 
   3704 				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
   3705 				{
   3706 					const char* const	components[]	=
   3707 					{
   3708 						"x", "y", "z", "w"
   3709 					};
   3710 					const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
   3711 					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
   3712 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3713 					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
   3714 					const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
   3715 					const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
   3716 
   3717 					if (isDepthFormat || isStencilFormat)
   3718 					{
   3719 						if (isDepthFormat)
   3720 						{
   3721 							fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_depth" << attachmentNdx << ").x);\n";
   3722 							inputValueNdx++;
   3723 						}
   3724 
   3725 						if (isStencilFormat)
   3726 						{
   3727 							fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
   3728 							inputValueNdx++;
   3729 						}
   3730 					}
   3731 					else
   3732 					{
   3733 						for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
   3734 						{
   3735 							fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
   3736 							inputValueNdx++;
   3737 						}
   3738 					}
   3739 				}
   3740 
   3741 				size_t outputValueNdx = 0;
   3742 
   3743 				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
   3744 				{
   3745 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
   3746 					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
   3747 					const std::string			attachmentType	= getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
   3748 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
   3749 					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
   3750 
   3751 					for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
   3752 					{
   3753 						const size_t	index	= subpassNdx + attachmentIndex + outputValueNdx;
   3754 						const BoolOp	op		= boolOpFromIndex(index);
   3755 
   3756 						fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
   3757 										<< "(int(gl_FragCoord.x) % 2 == " << (index % 2)
   3758 										<< ") " << boolOpToString(op) << " ("
   3759 										<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
   3760 										<< ");\n";
   3761 
   3762 						for (size_t i = 0; i < inputsPerOutput; i++)
   3763 							fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" <<  ((outputValueNdx + compNdx) * inputsPerOutput + i) %  inputComponentCount << "];\n";
   3764 					}
   3765 
   3766 					fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
   3767 
   3768 					for (size_t compNdx = 0; compNdx < 4; compNdx++)
   3769 					{
   3770 						if (compNdx > 0)
   3771 							fragmentShader << ", ";
   3772 
   3773 						if (compNdx < componentCount)
   3774 							fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
   3775 						else
   3776 							fragmentShader << "0";
   3777 					}
   3778 
   3779 					outputValueNdx += componentCount;
   3780 
   3781 					fragmentShader << ");\n";
   3782 				}
   3783 
   3784 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   3785 				{
   3786 					const deUint32	attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
   3787 					const size_t	index			= subpassNdx + attachmentIndex;
   3788 					const BoolOp	op				= boolOpFromIndex(index);
   3789 
   3790 					fragmentShader << "\toutputs[" << outputValueNdx << "] = "
   3791 									<< "(int(gl_FragCoord.x) % 2 == " << (index % 2)
   3792 									<< ") " << boolOpToString(op) << " ("
   3793 									<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
   3794 									<< ");\n";
   3795 
   3796 					for (size_t i = 0; i < inputsPerOutput; i++)
   3797 						fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" <<  (outputValueNdx * inputsPerOutput + i) %  inputComponentCount << "];\n";
   3798 
   3799 					fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? 1.0 : 0.0;";
   3800 				}
   3801 			}
   3802 
   3803 			fragmentShader << "}\n";
   3804 
   3805 			dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
   3806 			dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
   3807 		}
   3808 	}
   3809 }
   3810 
   3811 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
   3812 {
   3813 	bool lastAttachmentWasLazy = false;
   3814 
   3815 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
   3816 	{
   3817 		if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
   3818 			&& attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
   3819 			&& attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
   3820 			&& attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
   3821 		{
   3822 			if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
   3823 			{
   3824 				attachmentIsLazy.push_back(true);
   3825 				lastAttachmentWasLazy = true;
   3826 			}
   3827 			else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
   3828 			{
   3829 				attachmentIsLazy.push_back(false);
   3830 				lastAttachmentWasLazy = false;
   3831 			}
   3832 			else
   3833 				DE_FATAL("Unknown imageMemory");
   3834 		}
   3835 		else
   3836 			attachmentIsLazy.push_back(false);
   3837 	}
   3838 }
   3839 
   3840 enum AttachmentRefType
   3841 {
   3842 	ATTACHMENTREFTYPE_COLOR,
   3843 	ATTACHMENTREFTYPE_DEPTH_STENCIL,
   3844 	ATTACHMENTREFTYPE_INPUT,
   3845 	ATTACHMENTREFTYPE_RESOLVE,
   3846 };
   3847 
   3848 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
   3849 {
   3850 	switch (layout)
   3851 	{
   3852 		case VK_IMAGE_LAYOUT_GENERAL:
   3853 		case VK_IMAGE_LAYOUT_PREINITIALIZED:
   3854 			return 0;
   3855 
   3856 		case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
   3857 			return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   3858 
   3859 		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
   3860 		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
   3861 			return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
   3862 
   3863 		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
   3864 			return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
   3865 
   3866 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
   3867 			return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   3868 
   3869 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
   3870 			return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3871 
   3872 		default:
   3873 			DE_FATAL("Unexpected image layout");
   3874 			return 0;
   3875 	}
   3876 }
   3877 
   3878 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
   3879 {
   3880 	for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
   3881 	{
   3882 		const deUint32 attachment = references[referenceNdx].getAttachment();
   3883 
   3884 		if (attachment != VK_ATTACHMENT_UNUSED)
   3885 		{
   3886 			VkImageUsageFlags usage;
   3887 
   3888 			switch (refType)
   3889 			{
   3890 				case ATTACHMENTREFTYPE_COLOR:
   3891 				case ATTACHMENTREFTYPE_RESOLVE:
   3892 					usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   3893 					break;
   3894 
   3895 				case ATTACHMENTREFTYPE_DEPTH_STENCIL:
   3896 					usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
   3897 					break;
   3898 
   3899 				case ATTACHMENTREFTYPE_INPUT:
   3900 					usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
   3901 					break;
   3902 
   3903 				default:
   3904 					DE_FATAL("Unexpected attachment reference type");
   3905 					usage = 0;
   3906 					break;
   3907 			}
   3908 
   3909 			attachmentImageUsage[attachment] |= usage;
   3910 		}
   3911 	}
   3912 }
   3913 
   3914 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
   3915 {
   3916 	if (!references.empty())
   3917 	{
   3918 		getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
   3919 	}
   3920 }
   3921 
   3922 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
   3923 {
   3924 	attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
   3925 
   3926 	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
   3927 	{
   3928 		const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
   3929 
   3930 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
   3931 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
   3932 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
   3933 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
   3934 	}
   3935 
   3936 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   3937 	{
   3938 		const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
   3939 		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
   3940 		const VkFormatFeatureFlags	supportedFeatures	= formatProperties.optimalTilingFeatures;
   3941 
   3942 		if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
   3943 			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
   3944 
   3945 		if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
   3946 			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
   3947 
   3948 		attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
   3949 		attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
   3950 
   3951 		if (!attachmentIsLazy[attachmentNdx])
   3952 		{
   3953 			if (clearValues[attachmentNdx])
   3954 				attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3955 
   3956 			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   3957 		}
   3958 	}
   3959 }
   3960 
   3961 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
   3962 {
   3963 	bool lastSubpassWasSecondary = false;
   3964 
   3965 	for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
   3966 	{
   3967 		if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
   3968 		{
   3969 			subpassIsSecondary.push_back(true);
   3970 			lastSubpassWasSecondary = true;
   3971 		}
   3972 		else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
   3973 		{
   3974 			subpassIsSecondary.push_back(false);
   3975 			lastSubpassWasSecondary = false;
   3976 		}
   3977 		else
   3978 			DE_FATAL("Unknown commandBuffer");
   3979 	}
   3980 }
   3981 
   3982 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
   3983 {
   3984 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
   3985 	{
   3986 		if (!isLazy[attachmentNdx])
   3987 			clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
   3988 		else
   3989 			clearValues.push_back(nothing<VkClearValue>());
   3990 	}
   3991 }
   3992 
   3993 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
   3994 {
   3995 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
   3996 	{
   3997 		if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
   3998 			|| attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
   3999 		{
   4000 			clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
   4001 		}
   4002 		else
   4003 			clearValues.push_back(nothing<VkClearValue>());
   4004 	}
   4005 }
   4006 
   4007 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
   4008 {
   4009 	clearValues.resize(renderPass.getSubpasses().size());
   4010 
   4011 	for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
   4012 	{
   4013 		const Subpass&						subpass				= renderPass.getSubpasses()[subpassNdx];
   4014 		const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();
   4015 
   4016 		clearValues[subpassNdx].resize(colorAttachments.size());
   4017 
   4018 		for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
   4019 		{
   4020 			const AttachmentReference&	attachmentRef	= colorAttachments[attachmentRefNdx];
   4021 			const Attachment&			attachment		= renderPass.getAttachments()[attachmentRef.getAttachment()];
   4022 
   4023 			clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
   4024 		}
   4025 	}
   4026 }
   4027 
   4028 void logSubpassRenderInfo (TestLog&					log,
   4029 						   const SubpassRenderInfo&	info)
   4030 {
   4031 	log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
   4032 
   4033 	if (info.isSecondary())
   4034 		log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
   4035 	else
   4036 		log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
   4037 
   4038 	for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
   4039 	{
   4040 		const ColorClear&	colorClear	= info.getColorClears()[attachmentNdx];
   4041 
   4042 		log << TestLog::Message << "Clearing color attachment " << attachmentNdx
   4043 			<< ". Offset: " << colorClear.getOffset()
   4044 			<< ", Size: " << colorClear.getSize()
   4045 			<< ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
   4046 	}
   4047 
   4048 	if (info.getDepthStencilClear())
   4049 	{
   4050 		const DepthStencilClear&	depthStencilClear	= *info.getDepthStencilClear();
   4051 
   4052 		log << TestLog::Message << "Clearing depth stencil attachment"
   4053 			<< ". Offset: " << depthStencilClear.getOffset()
   4054 			<< ", Size: " << depthStencilClear.getSize()
   4055 			<< ", Depth: " << depthStencilClear.getDepth()
   4056 			<< ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
   4057 	}
   4058 
   4059 	if (info.getRenderQuad())
   4060 	{
   4061 		const RenderQuad&	renderQuad	= *info.getRenderQuad();
   4062 
   4063 		log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
   4064 	}
   4065 }
   4066 
   4067 void logTestCaseInfo (TestLog&								log,
   4068 					  const TestConfig&						config,
   4069 					  const vector<bool>&					attachmentIsLazy,
   4070 					  const vector<Maybe<VkClearValue> >&	imageClearValues,
   4071 					  const vector<Maybe<VkClearValue> >&	renderPassClearValues,
   4072 					  const vector<SubpassRenderInfo>&		subpassRenderInfo)
   4073 {
   4074 	const RenderPass&	renderPass	= config.renderPass;
   4075 
   4076 	logRenderPassInfo(log, renderPass);
   4077 
   4078 	DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
   4079 	DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
   4080 	DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
   4081 
   4082 	log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
   4083 	log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
   4084 
   4085 	for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
   4086 	{
   4087 		const tcu::ScopedLogSection	section	(log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
   4088 
   4089 		if (attachmentIsLazy[attachmentNdx])
   4090 			log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
   4091 
   4092 		if (imageClearValues[attachmentNdx])
   4093 			log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
   4094 
   4095 		if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
   4096 			log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
   4097 	}
   4098 
   4099 	for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
   4100 	{
   4101 		const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
   4102 
   4103 		logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
   4104 	}
   4105 }
   4106 
   4107 float roundToViewport (float x, deUint32 offset, deUint32 size)
   4108 {
   4109 	const float		origin	= (float)(offset) + ((float(size) / 2.0f));
   4110 	const float		p		= (float)(size) / 2.0f;
   4111 	const deInt32	xi		= deRoundFloatToInt32(origin + (p * x));
   4112 
   4113 	return (((float)xi) - origin) / p;
   4114 }
   4115 
   4116 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
   4117 {
   4118 	const TestConfig::CommandBufferTypes	commandBuffer			= config.commandBufferTypes;
   4119 	const vector<Subpass>&					subpasses				= renderPass.getSubpasses();
   4120 	bool									lastSubpassWasSecondary	= false;
   4121 
   4122 	for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
   4123 	{
   4124 		const Subpass&				subpass				= subpasses[subpassNdx];
   4125 		const bool					subpassIsSecondary	= commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
   4126 														|| (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
   4127 		const UVec2					viewportSize		((config.renderSize * UVec2(2)) / UVec2(3));
   4128 		const UVec2					viewportOffset		(config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
   4129 														 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
   4130 
   4131 		vector<ColorClear>			colorClears;
   4132 		Maybe<DepthStencilClear>	depthStencilClear;
   4133 		Maybe<RenderQuad>			renderQuad;
   4134 
   4135 		lastSubpassWasSecondary		= subpassIsSecondary;
   4136 
   4137 		if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
   4138 		{
   4139 			const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();
   4140 
   4141 			for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
   4142 			{
   4143 				const AttachmentReference&	attachmentRef	= colorAttachments[attachmentRefNdx];
   4144 				const Attachment&			attachment		= renderPass.getAttachments()[attachmentRef.getAttachment()];
   4145 				const UVec2					size			((viewportSize * UVec2(2)) / UVec2(3));
   4146 				const UVec2					offset			(viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
   4147 															 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
   4148 				const VkClearColorValue		color			= randomColorClearValue(attachment, rng);
   4149 
   4150 				colorClears.push_back(ColorClear(offset, size, color));
   4151 			}
   4152 
   4153 			if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
   4154 			{
   4155 				const Attachment&	attachment	= renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
   4156 				const UVec2			size		((viewportSize * UVec2(2)) / UVec2(3));
   4157 				const UVec2			offset		(viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
   4158 												 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
   4159 				const VkClearValue	value		= randomClearValue(attachment, rng);
   4160 
   4161 				depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
   4162 			}
   4163 		}
   4164 
   4165 		if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
   4166 		{
   4167 			const float	w	= (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
   4168 			const float	h	= (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
   4169 
   4170 			const float	x0	= roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
   4171 			const float	x1	= roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
   4172 
   4173 			const float	y0	= roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
   4174 			const float	y1	= roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
   4175 
   4176 			renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
   4177 		}
   4178 
   4179 		renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
   4180 	}
   4181 }
   4182 
   4183 void checkTextureFormatSupport (TestLog&					log,
   4184 								const InstanceInterface&	vk,
   4185 								VkPhysicalDevice			device,
   4186 								const vector<Attachment>&	attachments)
   4187 {
   4188 	bool supported = true;
   4189 
   4190 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
   4191 	{
   4192 		const Attachment&			attachment					= attachments[attachmentNdx];
   4193 		const tcu::TextureFormat	format						= mapVkFormat(attachment.getFormat());
   4194 		const bool					isDepthOrStencilAttachment	= hasDepthComponent(format.order) || hasStencilComponent(format.order);
   4195 		const VkFormatFeatureFlags	flags						= isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
   4196 		VkFormatProperties			properties;
   4197 
   4198 		vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
   4199 
   4200 		if ((properties.optimalTilingFeatures & flags) != flags)
   4201 		{
   4202 			supported = false;
   4203 			log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
   4204 		}
   4205 	}
   4206 
   4207 	if (!supported)
   4208 		TCU_THROW(NotSupportedError, "Format not supported");
   4209 }
   4210 
   4211 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
   4212 {
   4213 	const UVec2							targetSize			= config.targetSize;
   4214 	const UVec2							renderPos			= config.renderPos;
   4215 	const UVec2							renderSize			= config.renderSize;
   4216 	const RenderPass&					renderPassInfo		= config.renderPass;
   4217 
   4218 	TestLog&							log					= context.getTestContext().getLog();
   4219 	de::Random							rng					(config.seed);
   4220 
   4221 	vector<bool>						attachmentIsLazy;
   4222 	vector<VkImageUsageFlags>			attachmentImageUsage;
   4223 	vector<Maybe<VkClearValue> >		imageClearValues;
   4224 	vector<Maybe<VkClearValue> >		renderPassClearValues;
   4225 
   4226 	vector<bool>						subpassIsSecondary;
   4227 	vector<SubpassRenderInfo>			subpassRenderInfo;
   4228 	vector<vector<VkClearColorValue> >	subpassColorClearValues;
   4229 
   4230 	initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
   4231 	initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
   4232 	initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
   4233 	initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
   4234 
   4235 	initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
   4236 	initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
   4237 	initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
   4238 
   4239 	logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
   4240 
   4241 	checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
   4242 
   4243 	{
   4244 		const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
   4245 
   4246 		log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
   4247 
   4248 		for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
   4249 		{
   4250 			 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
   4251 				 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
   4252 		}
   4253 	}
   4254 
   4255 	{
   4256 		const VkDevice								device								= context.getDevice();
   4257 		const DeviceInterface&						vk									= context.getDeviceInterface();
   4258 		const VkQueue								queue								= context.getUniversalQueue();
   4259 		const deUint32								queueIndex							= context.getUniversalQueueFamilyIndex();
   4260 		Allocator&									allocator							= context.getDefaultAllocator();
   4261 
   4262 		const Unique<VkRenderPass>					renderPass							(createRenderPass(vk, device, renderPassInfo));
   4263 		const Unique<VkCommandPool>					commandBufferPool					(createCommandPool(vk, device, queueIndex, 0));
   4264 		const Unique<VkCommandBuffer>				initializeImagesCommandBuffer		(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4265 		const Unique<VkCommandBuffer>				renderCommandBuffer					(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4266 		const Unique<VkCommandBuffer>				readImagesToBuffersCommandBuffer	(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4267 
   4268 		vector<de::SharedPtr<AttachmentResources> >	attachmentResources;
   4269 		vector<de::SharedPtr<SubpassRenderer> >		subpassRenderers;
   4270 		vector<VkImage>								attachmentImages;
   4271 		vector<VkImageView>							attachmentViews;
   4272 		vector<pair<VkImageView, VkImageView> >		inputAttachmentViews;
   4273 
   4274 		for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   4275 		{
   4276 			const Attachment&	attachmentInfo	= renderPassInfo.getAttachments()[attachmentNdx];
   4277 
   4278 			attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx])));
   4279 			attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
   4280 			attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
   4281 
   4282 			inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
   4283 		}
   4284 
   4285 		beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
   4286 		pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
   4287 		endCommandBuffer(vk, *initializeImagesCommandBuffer);
   4288 
   4289 		{
   4290 			const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
   4291 
   4292 			for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
   4293 				subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews, subpassRenderInfo[subpassNdx], config.renderPass.getAttachments())));
   4294 
   4295 			beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
   4296 			pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
   4297 			endCommandBuffer(vk, *renderCommandBuffer);
   4298 
   4299 			beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
   4300 			pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
   4301 			endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
   4302 			{
   4303 				const VkCommandBuffer commandBuffers[] =
   4304 				{
   4305 					*initializeImagesCommandBuffer,
   4306 					*renderCommandBuffer,
   4307 					*readImagesToBuffersCommandBuffer
   4308 				};
   4309 				const Unique<VkFence>	fence		(createFence(vk, device, 0u));
   4310 
   4311 				queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
   4312 				waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
   4313 			}
   4314 		}
   4315 
   4316 		if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
   4317 			return tcu::TestStatus::pass("Pass");
   4318 		else
   4319 			return tcu::TestStatus::fail("Result verification failed");
   4320 	}
   4321 }
   4322 
   4323 static const VkFormat s_coreColorFormats[] =
   4324 {
   4325 	VK_FORMAT_R5G6B5_UNORM_PACK16,
   4326 	VK_FORMAT_R8_UNORM,
   4327 	VK_FORMAT_R8_SNORM,
   4328 	VK_FORMAT_R8_UINT,
   4329 	VK_FORMAT_R8_SINT,
   4330 	VK_FORMAT_R8G8_UNORM,
   4331 	VK_FORMAT_R8G8_SNORM,
   4332 	VK_FORMAT_R8G8_UINT,
   4333 	VK_FORMAT_R8G8_SINT,
   4334 	VK_FORMAT_R8G8B8A8_UNORM,
   4335 	VK_FORMAT_R8G8B8A8_SNORM,
   4336 	VK_FORMAT_R8G8B8A8_UINT,
   4337 	VK_FORMAT_R8G8B8A8_SINT,
   4338 	VK_FORMAT_R8G8B8A8_SRGB,
   4339 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
   4340 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
   4341 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
   4342 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
   4343 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
   4344 	VK_FORMAT_B8G8R8A8_UNORM,
   4345 	VK_FORMAT_B8G8R8A8_SRGB,
   4346 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
   4347 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
   4348 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
   4349 	VK_FORMAT_R16_UNORM,
   4350 	VK_FORMAT_R16_SNORM,
   4351 	VK_FORMAT_R16_UINT,
   4352 	VK_FORMAT_R16_SINT,
   4353 	VK_FORMAT_R16_SFLOAT,
   4354 	VK_FORMAT_R16G16_UNORM,
   4355 	VK_FORMAT_R16G16_SNORM,
   4356 	VK_FORMAT_R16G16_UINT,
   4357 	VK_FORMAT_R16G16_SINT,
   4358 	VK_FORMAT_R16G16_SFLOAT,
   4359 	VK_FORMAT_R16G16B16A16_UNORM,
   4360 	VK_FORMAT_R16G16B16A16_SNORM,
   4361 	VK_FORMAT_R16G16B16A16_UINT,
   4362 	VK_FORMAT_R16G16B16A16_SINT,
   4363 	VK_FORMAT_R16G16B16A16_SFLOAT,
   4364 	VK_FORMAT_R32_UINT,
   4365 	VK_FORMAT_R32_SINT,
   4366 	VK_FORMAT_R32_SFLOAT,
   4367 	VK_FORMAT_R32G32_UINT,
   4368 	VK_FORMAT_R32G32_SINT,
   4369 	VK_FORMAT_R32G32_SFLOAT,
   4370 	VK_FORMAT_R32G32B32A32_UINT,
   4371 	VK_FORMAT_R32G32B32A32_SINT,
   4372 	VK_FORMAT_R32G32B32A32_SFLOAT
   4373 };
   4374 
   4375 static const VkFormat s_coreDepthStencilFormats[] =
   4376 {
   4377 	VK_FORMAT_D16_UNORM,
   4378 
   4379 	VK_FORMAT_X8_D24_UNORM_PACK32,
   4380 	VK_FORMAT_D32_SFLOAT,
   4381 
   4382 	VK_FORMAT_D24_UNORM_S8_UINT,
   4383 	VK_FORMAT_D32_SFLOAT_S8_UINT
   4384 };
   4385 
   4386 void addAttachmentTests (tcu::TestCaseGroup* group)
   4387 {
   4388 	const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
   4389 	const VkAttachmentLoadOp loadOps[] =
   4390 	{
   4391 		VK_ATTACHMENT_LOAD_OP_LOAD,
   4392 		VK_ATTACHMENT_LOAD_OP_CLEAR,
   4393 		VK_ATTACHMENT_LOAD_OP_DONT_CARE
   4394 	};
   4395 
   4396 	const VkAttachmentStoreOp storeOps[] =
   4397 	{
   4398 		VK_ATTACHMENT_STORE_OP_STORE,
   4399 		VK_ATTACHMENT_STORE_OP_DONT_CARE
   4400 	};
   4401 
   4402 	const VkImageLayout initialAndFinalColorLayouts[] =
   4403 	{
   4404 		VK_IMAGE_LAYOUT_GENERAL,
   4405 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   4406 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4407 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4408 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4409 	};
   4410 
   4411 	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
   4412 	{
   4413 		VK_IMAGE_LAYOUT_GENERAL,
   4414 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   4415 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
   4416 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4417 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4418 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4419 	};
   4420 
   4421 	const VkImageLayout subpassLayouts[] =
   4422 	{
   4423 		VK_IMAGE_LAYOUT_GENERAL,
   4424 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
   4425 	};
   4426 
   4427 	const VkImageLayout depthStencilLayouts[] =
   4428 	{
   4429 		VK_IMAGE_LAYOUT_GENERAL,
   4430 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
   4431 	};
   4432 
   4433 	const TestConfig::RenderTypes renderCommands[] =
   4434 	{
   4435 		TestConfig::RENDERTYPES_NONE,
   4436 		TestConfig::RENDERTYPES_CLEAR,
   4437 		TestConfig::RENDERTYPES_DRAW,
   4438 		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
   4439 	};
   4440 
   4441 	const TestConfig::CommandBufferTypes commandBuffers[] =
   4442 	{
   4443 		TestConfig::COMMANDBUFFERTYPES_INLINE,
   4444 		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
   4445 		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
   4446 	};
   4447 
   4448 	const TestConfig::ImageMemory imageMemories[] =
   4449 	{
   4450 		TestConfig::IMAGEMEMORY_STRICT,
   4451 		TestConfig::IMAGEMEMORY_LAZY,
   4452 		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
   4453 	};
   4454 
   4455 	const UVec2 targetSizes[] =
   4456 	{
   4457 		UVec2(64, 64),
   4458 		UVec2(63, 65)
   4459 	};
   4460 
   4461 	const UVec2 renderPositions[] =
   4462 	{
   4463 		UVec2(0, 0),
   4464 		UVec2(3, 17)
   4465 	};
   4466 
   4467 	const UVec2 renderSizes[] =
   4468 	{
   4469 		UVec2(32, 32),
   4470 		UVec2(60, 47)
   4471 	};
   4472 
   4473 	tcu::TestContext&	testCtx	= group->getTestContext();
   4474 	de::Random			rng		(1433774382u);
   4475 
   4476 	for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
   4477 	{
   4478 		const deUint32					attachmentCount			= attachmentCounts[attachmentCountNdx];
   4479 		const deUint32					testCaseCount			= (attachmentCount == 1 ? 100 : 200);
   4480 		de::MovePtr<tcu::TestCaseGroup>	attachmentCountGroup	(new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
   4481 
   4482 		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
   4483 		{
   4484 			const bool					useDepthStencil		= rng.getBool();
   4485 			VkImageLayout				depthStencilLayout	= VK_IMAGE_LAYOUT_GENERAL;
   4486 			vector<Attachment>			attachments;
   4487 			vector<AttachmentReference>	colorAttachmentReferences;
   4488 
   4489 			for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
   4490 			{
   4491 				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
   4492 				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
   4493 				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4494 				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4495 
   4496 				const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4497 				const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4498 				const VkImageLayout			subpassLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   4499 
   4500 				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4501 				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4502 
   4503 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4504 				colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   4505 			}
   4506 
   4507 			if (useDepthStencil)
   4508 			{
   4509 				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
   4510 				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
   4511 				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4512 				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4513 
   4514 				const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
   4515 				const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
   4516 
   4517 				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4518 				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4519 
   4520 				depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
   4521 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4522 			}
   4523 
   4524 			{
   4525 				const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
   4526 				const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
   4527 				const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
   4528 				const vector<Subpass>					subpasses		(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference((useDepthStencil ? (deUint32)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED), depthStencilLayout), vector<deUint32>()));
   4529 				const vector<SubpassDependency>			deps;
   4530 
   4531 				const string							testCaseName	= de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
   4532 				const RenderPass						renderPass		(attachments, subpasses, deps);
   4533 				const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
   4534 				const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
   4535 				const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
   4536 
   4537 				addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809));
   4538 			}
   4539 		}
   4540 
   4541 		group->addChild(attachmentCountGroup.release());
   4542 	}
   4543 }
   4544 
   4545 template<typename T>
   4546 T chooseRandom (de::Random& rng, const set<T>& values)
   4547 {
   4548 	size_t							ndx		= ((size_t)rng.getUint32()) % values.size();
   4549 	typename set<T>::const_iterator	iter	= values.begin();
   4550 
   4551 	for (; ndx > 0; ndx--)
   4552 		iter++;
   4553 
   4554 	return *iter;
   4555 }
   4556 
   4557 void addAttachmentAllocationTests (tcu::TestCaseGroup* group)
   4558 {
   4559 	const deUint32 attachmentCounts[] = { 4, 8 };
   4560 	const VkAttachmentLoadOp loadOps[] =
   4561 	{
   4562 		VK_ATTACHMENT_LOAD_OP_LOAD,
   4563 		VK_ATTACHMENT_LOAD_OP_CLEAR,
   4564 		VK_ATTACHMENT_LOAD_OP_DONT_CARE
   4565 	};
   4566 
   4567 	const VkAttachmentStoreOp storeOps[] =
   4568 	{
   4569 		VK_ATTACHMENT_STORE_OP_STORE,
   4570 		VK_ATTACHMENT_STORE_OP_DONT_CARE
   4571 	};
   4572 
   4573 	const VkImageLayout initialAndFinalColorLayouts[] =
   4574 	{
   4575 		VK_IMAGE_LAYOUT_GENERAL,
   4576 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   4577 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4578 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4579 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4580 	};
   4581 
   4582 	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
   4583 	{
   4584 		VK_IMAGE_LAYOUT_GENERAL,
   4585 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   4586 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
   4587 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4588 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4589 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4590 	};
   4591 
   4592 	const VkImageLayout subpassLayouts[] =
   4593 	{
   4594 		VK_IMAGE_LAYOUT_GENERAL,
   4595 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   4596 	};
   4597 
   4598 	enum AllocationType
   4599 	{
   4600 		// Each pass uses one more attachmen than previous one
   4601 		ALLOCATIONTYPE_GROW,
   4602 		// Each pass uses one less attachment than previous one
   4603 		ALLOCATIONTYPE_SHRINK,
   4604 		// Each pass drops one attachment and picks up new one
   4605 		ALLOCATIONTYPE_ROLL,
   4606 		// Start by growing and end by shrinking
   4607 		ALLOCATIONTYPE_GROW_SHRINK,
   4608 		// Each subpass has single input and single output attachment
   4609 		ALLOCATIONTYPE_IO_CHAIN,
   4610 		// Each subpass has multiple inputs and multiple outputs attachment
   4611 		ALLOCATIONTYPE_IO_GENERIC
   4612 	};
   4613 
   4614 	const AllocationType allocationTypes[] =
   4615 	{
   4616 		ALLOCATIONTYPE_GROW,
   4617 		ALLOCATIONTYPE_SHRINK,
   4618 		ALLOCATIONTYPE_ROLL,
   4619 		ALLOCATIONTYPE_GROW_SHRINK,
   4620 		ALLOCATIONTYPE_IO_CHAIN,
   4621 		ALLOCATIONTYPE_IO_GENERIC
   4622 	};
   4623 
   4624 	const char* const allocationTypeStr[] =
   4625 	{
   4626 		"grow",
   4627 		"shrink",
   4628 		"roll",
   4629 		"grow_shrink",
   4630 		"input_output_chain",
   4631 		"input_output",
   4632 	};
   4633 
   4634 	const TestConfig::RenderTypes renderCommands[] =
   4635 	{
   4636 		TestConfig::RENDERTYPES_NONE,
   4637 		TestConfig::RENDERTYPES_CLEAR,
   4638 		TestConfig::RENDERTYPES_DRAW,
   4639 		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
   4640 	};
   4641 
   4642 	const TestConfig::CommandBufferTypes commandBuffers[] =
   4643 	{
   4644 		TestConfig::COMMANDBUFFERTYPES_INLINE,
   4645 		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
   4646 		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
   4647 	};
   4648 
   4649 	const TestConfig::ImageMemory imageMemories[] =
   4650 	{
   4651 		TestConfig::IMAGEMEMORY_STRICT,
   4652 		TestConfig::IMAGEMEMORY_LAZY,
   4653 		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
   4654 	};
   4655 
   4656 	const UVec2 targetSizes[] =
   4657 	{
   4658 		UVec2(64, 64),
   4659 		UVec2(63, 65)
   4660 	};
   4661 
   4662 	const UVec2 renderPositions[] =
   4663 	{
   4664 		UVec2(0, 0),
   4665 		UVec2(3, 17)
   4666 	};
   4667 
   4668 	const UVec2 renderSizes[] =
   4669 	{
   4670 		UVec2(32, 32),
   4671 		UVec2(60, 47)
   4672 	};
   4673 
   4674 	tcu::TestContext&				testCtx	= group->getTestContext();
   4675 	de::Random						rng		(3700649827u);
   4676 
   4677 	for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
   4678 	{
   4679 		const AllocationType			allocationType		= allocationTypes[allocationTypeNdx];
   4680 		const size_t					testCaseCount		= 100;
   4681 		de::MovePtr<tcu::TestCaseGroup>	allocationTypeGroup	(new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
   4682 
   4683 		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
   4684 		{
   4685 			if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
   4686 			{
   4687 				const deUint32		attachmentCount	= 4u + rng.getUint32() % 31u;
   4688 				const deUint32		subpassCount	= 4u + rng.getUint32() % 31u;
   4689 				vector<Attachment>	attachments;
   4690 
   4691 				set<deUint32>		definedAttachments;
   4692 
   4693 				vector<Subpass>		subpasses;
   4694 				set<deUint32>		colorAttachments;
   4695 				set<deUint32>		depthStencilAttachments;
   4696 
   4697 				for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
   4698 				{
   4699 					const bool					isDepthStencilAttachment	= rng.getFloat() < 0.01f;
   4700 					const VkSampleCountFlagBits	sampleCount					= VK_SAMPLE_COUNT_1_BIT;
   4701 					const VkAttachmentLoadOp	loadOp						= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4702 					const VkAttachmentStoreOp	storeOp						= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4703 
   4704 					const VkImageLayout			initialLayout				= isDepthStencilAttachment
   4705 																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
   4706 																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4707 					const VkImageLayout			finalizeLayout				= isDepthStencilAttachment
   4708 																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
   4709 																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4710 
   4711 					const VkAttachmentLoadOp	stencilLoadOp				= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4712 					const VkAttachmentStoreOp	stencilStoreOp				= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4713 
   4714 					if (isDepthStencilAttachment)
   4715 					{
   4716 						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
   4717 
   4718 						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
   4719 							|| stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
   4720 							definedAttachments.insert(attachmentIndex);
   4721 
   4722 						depthStencilAttachments.insert(attachmentIndex);
   4723 
   4724 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4725 					}
   4726 					else
   4727 					{
   4728 						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
   4729 
   4730 						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
   4731 							definedAttachments.insert(attachmentIndex);
   4732 
   4733 						colorAttachments.insert(attachmentIndex);
   4734 
   4735 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4736 					}
   4737 				}
   4738 				vector<Maybe<deUint32> >	lastUseOfAttachment	(attachments.size(), nothing<deUint32>());
   4739 				vector<SubpassDependency>	deps;
   4740 
   4741 				for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
   4742 				{
   4743 					const deUint32				colorAttachmentCount		= depthStencilAttachments.empty()
   4744 																			? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
   4745 																			: rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
   4746 					const deUint32				inputAttachmentCount		= rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
   4747 					const bool					useDepthStencilAttachment	= !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
   4748 					std::vector<deUint32>		subpassColorAttachments		(colorAttachmentCount);
   4749 					std::vector<deUint32>		subpassInputAttachments		(inputAttachmentCount);
   4750 					Maybe<deUint32>				depthStencilAttachment		(useDepthStencilAttachment
   4751 																			? just(chooseRandom(rng, depthStencilAttachments))
   4752 																			: nothing<deUint32>());
   4753 					std::vector<deUint32>		subpassPreserveAttachments;
   4754 
   4755 					rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
   4756 					rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
   4757 
   4758 					for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
   4759 						definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
   4760 
   4761 					if (depthStencilAttachment)
   4762 						definedAttachments.insert(*depthStencilAttachment);
   4763 
   4764 					{
   4765 						std::vector<AttachmentReference>	inputAttachmentReferences;
   4766 						std::vector<AttachmentReference>	colorAttachmentReferences;
   4767 						AttachmentReference					depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
   4768 
   4769 						for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
   4770 						{
   4771 							const deUint32		colorAttachmentIndex	= subpassColorAttachments[colorAttachmentNdx];
   4772 							// \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
   4773 							const VkImageLayout	subpassLayout			= VK_IMAGE_LAYOUT_GENERAL;
   4774 
   4775 							if (lastUseOfAttachment[colorAttachmentIndex])
   4776 							{
   4777 								const bool byRegion = rng.getBool();
   4778 
   4779 								deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex,
   4780 																 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4781 																	| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4782 																	| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4783 																	| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4784 
   4785 																 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4786 																	| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4787 																	| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4788 																	| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4789 
   4790 																 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4791 																 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
   4792 
   4793 																 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   4794 							}
   4795 
   4796 							lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
   4797 
   4798 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout));
   4799 						}
   4800 
   4801 						for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
   4802 						{
   4803 							const deUint32		inputAttachmentIndex	= subpassInputAttachments[inputAttachmentNdx];
   4804 							// \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts
   4805 							const VkImageLayout	subpassLayout			= VK_IMAGE_LAYOUT_GENERAL;
   4806 
   4807 							if(lastUseOfAttachment[inputAttachmentIndex])
   4808 							{
   4809 								if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex)
   4810 								{
   4811 									deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
   4812 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4813 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4814 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4815 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4816 
   4817 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4818 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4819 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4820 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4821 
   4822 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   4823 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   4824 
   4825 																	 VK_DEPENDENCY_BY_REGION_BIT));
   4826 								}
   4827 								else
   4828 								{
   4829 									const bool byRegion = rng.getBool();
   4830 
   4831 									deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex,
   4832 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4833 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4834 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4835 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4836 
   4837 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4838 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4839 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4840 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4841 
   4842 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   4843 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   4844 
   4845 																	 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   4846 								}
   4847 
   4848 								lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
   4849 
   4850 								inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout));
   4851 							}
   4852 						}
   4853 
   4854 						if (depthStencilAttachment)
   4855 						{
   4856 							// \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
   4857 							if (lastUseOfAttachment[*depthStencilAttachment])
   4858 							{
   4859 								if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex)
   4860 								{
   4861 									deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
   4862 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4863 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4864 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4865 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4866 
   4867 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4868 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4869 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4870 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4871 
   4872 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   4873 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   4874 
   4875 																	 VK_DEPENDENCY_BY_REGION_BIT));
   4876 								}
   4877 								else
   4878 								{
   4879 									const bool byRegion = rng.getBool();
   4880 
   4881 									deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex,
   4882 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4883 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4884 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4885 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4886 
   4887 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   4888 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   4889 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   4890 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   4891 
   4892 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   4893 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   4894 
   4895 																	 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   4896 								}
   4897 							}
   4898 
   4899 							lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
   4900 							depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
   4901 						}
   4902 						else
   4903 							depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
   4904 
   4905 						vector<deUint32>	preserveAttachments;
   4906 						for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
   4907 						{
   4908 							if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
   4909 								preserveAttachments.push_back(attachmentIndex);
   4910 						}
   4911 
   4912 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   4913 												inputAttachmentReferences,
   4914 												colorAttachmentReferences,
   4915 												vector<AttachmentReference>(),
   4916 												depthStencilAttachmentReference,
   4917 												preserveAttachments));
   4918 					}
   4919 				}
   4920 				{
   4921 					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
   4922 					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
   4923 					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
   4924 
   4925 					const string							testCaseName	= de::toString(testCaseNdx);
   4926 					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
   4927 					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
   4928 					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
   4929 
   4930 					const RenderPass						renderPass		(attachments, subpasses, deps);
   4931 
   4932 					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
   4933 				}
   4934 			}
   4935 			else
   4936 			{
   4937 				const deUint32		attachmentCount	= rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
   4938 				vector<Attachment>	attachments;
   4939 				vector<Subpass>		subpasses;
   4940 
   4941 				for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
   4942 				{
   4943 					const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
   4944 					const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
   4945 					const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4946 					const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4947 
   4948 					const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4949 					const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4950 
   4951 					const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4952 					const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4953 
   4954 					attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4955 				}
   4956 
   4957 				if (allocationType == ALLOCATIONTYPE_GROW)
   4958 				{
   4959 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   4960 					{
   4961 						vector<AttachmentReference>	colorAttachmentReferences;
   4962 
   4963 						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
   4964 						{
   4965 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   4966 
   4967 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   4968 						}
   4969 
   4970 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   4971 												vector<AttachmentReference>(),
   4972 												colorAttachmentReferences,
   4973 												vector<AttachmentReference>(),
   4974 												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   4975 												vector<deUint32>()));
   4976 					}
   4977 				}
   4978 				else if (allocationType == ALLOCATIONTYPE_SHRINK)
   4979 				{
   4980 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   4981 					{
   4982 						vector<AttachmentReference>	colorAttachmentReferences;
   4983 
   4984 						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
   4985 						{
   4986 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   4987 
   4988 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   4989 						}
   4990 
   4991 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   4992 													vector<AttachmentReference>(),
   4993 													colorAttachmentReferences,
   4994 													vector<AttachmentReference>(),
   4995 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   4996 													vector<deUint32>()));
   4997 					}
   4998 				}
   4999 				else if (allocationType == ALLOCATIONTYPE_ROLL)
   5000 				{
   5001 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
   5002 					{
   5003 						vector<AttachmentReference>	colorAttachmentReferences;
   5004 
   5005 						for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
   5006 						{
   5007 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5008 
   5009 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
   5010 						}
   5011 
   5012 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5013 													vector<AttachmentReference>(),
   5014 													colorAttachmentReferences,
   5015 													vector<AttachmentReference>(),
   5016 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5017 													vector<deUint32>()));
   5018 					}
   5019 				}
   5020 				else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
   5021 				{
   5022 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   5023 					{
   5024 						vector<AttachmentReference>	colorAttachmentReferences;
   5025 
   5026 						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
   5027 						{
   5028 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5029 
   5030 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   5031 						}
   5032 
   5033 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5034 													vector<AttachmentReference>(),
   5035 													colorAttachmentReferences,
   5036 													vector<AttachmentReference>(),
   5037 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5038 													vector<deUint32>()));
   5039 					}
   5040 
   5041 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   5042 					{
   5043 						vector<AttachmentReference>	colorAttachmentReferences;
   5044 
   5045 						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
   5046 						{
   5047 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5048 
   5049 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   5050 						}
   5051 
   5052 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5053 											vector<AttachmentReference>(),
   5054 											colorAttachmentReferences,
   5055 											vector<AttachmentReference>(),
   5056 											AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5057 											vector<deUint32>()));
   5058 					}
   5059 				}
   5060 				else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
   5061 				{
   5062 					subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5063 											vector<AttachmentReference>(),
   5064 											vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
   5065 											vector<AttachmentReference>(),
   5066 											AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5067 											vector<deUint32>()));
   5068 
   5069 					for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
   5070 					{
   5071 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5072 												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
   5073 												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
   5074 												vector<AttachmentReference>(),
   5075 												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5076 												vector<deUint32>()));
   5077 					}
   5078 				}
   5079 				else
   5080 					DE_FATAL("Unknown allocation type");
   5081 
   5082 				{
   5083 					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
   5084 					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
   5085 					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
   5086 
   5087 					const string							testCaseName	= de::toString(testCaseNdx);
   5088 					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
   5089 					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
   5090 					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
   5091 
   5092 					vector<SubpassDependency>				deps;
   5093 
   5094 					for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
   5095 					{
   5096 						const bool byRegion				= rng.getBool();
   5097 						deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
   5098 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5099 															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5100 															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5101 															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5102 
   5103 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5104 															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5105 															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5106 															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5107 
   5108 														 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5109 														 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
   5110 
   5111 														 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   5112 					}
   5113 
   5114 					const RenderPass					renderPass		(attachments, subpasses, deps);
   5115 
   5116 					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329));
   5117 				}
   5118 			}
   5119 		}
   5120 		group->addChild(allocationTypeGroup.release());
   5121 	}
   5122 }
   5123 
   5124 void addSimpleTests (tcu::TestCaseGroup* group)
   5125 {
   5126 	const UVec2	targetSize	(64, 64);
   5127 	const UVec2	renderPos	(0, 0);
   5128 	const UVec2	renderSize	(64, 64);
   5129 
   5130 	// color
   5131 	{
   5132 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5133 																		  VK_SAMPLE_COUNT_1_BIT,
   5134 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5135 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5136 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5137 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5138 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5139 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5140 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5141 																	0u,
   5142 																	vector<AttachmentReference>(),
   5143 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5144 																	vector<AttachmentReference>(),
   5145 																	AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5146 																	vector<deUint32>())),
   5147 										 vector<SubpassDependency>());
   5148 
   5149 		addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5150 	}
   5151 
   5152 	// depth
   5153 	{
   5154 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
   5155 																		  VK_SAMPLE_COUNT_1_BIT,
   5156 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5157 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5158 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5159 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5160 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5161 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5162 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5163 																	0u,
   5164 																	vector<AttachmentReference>(),
   5165 																	vector<AttachmentReference>(),
   5166 																	vector<AttachmentReference>(),
   5167 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5168 																	vector<deUint32>())),
   5169 										 vector<SubpassDependency>());
   5170 
   5171 		addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5172 	}
   5173 
   5174 	// stencil
   5175 	{
   5176 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
   5177 																		  VK_SAMPLE_COUNT_1_BIT,
   5178 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5179 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5180 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5181 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5182 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5183 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5184 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5185 																	0u,
   5186 																	vector<AttachmentReference>(),
   5187 																	vector<AttachmentReference>(),
   5188 																	vector<AttachmentReference>(),
   5189 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5190 																	vector<deUint32>())),
   5191 										 vector<SubpassDependency>());
   5192 
   5193 		addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5194 	}
   5195 
   5196 	// depth_stencil
   5197 	{
   5198 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
   5199 																		  VK_SAMPLE_COUNT_1_BIT,
   5200 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5201 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5202 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5203 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5204 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5205 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5206 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5207 																	0u,
   5208 																	vector<AttachmentReference>(),
   5209 																	vector<AttachmentReference>(),
   5210 																	vector<AttachmentReference>(),
   5211 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5212 																	vector<deUint32>())),
   5213 										 vector<SubpassDependency>());
   5214 
   5215 		addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5216 	}
   5217 
   5218 	// color_depth
   5219 	{
   5220 		const Attachment	attachments[] =
   5221 		{
   5222 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5223 					   VK_SAMPLE_COUNT_1_BIT,
   5224 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5225 					   VK_ATTACHMENT_STORE_OP_STORE,
   5226 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5227 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5228 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5229 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
   5230 			Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
   5231 					   VK_SAMPLE_COUNT_1_BIT,
   5232 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5233 					   VK_ATTACHMENT_STORE_OP_STORE,
   5234 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5235 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5236 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5237 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5238 		};
   5239 
   5240 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
   5241 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5242 																	0u,
   5243 																	vector<AttachmentReference>(),
   5244 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5245 																	vector<AttachmentReference>(),
   5246 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5247 																	vector<deUint32>())),
   5248 										 vector<SubpassDependency>());
   5249 
   5250 		addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5251 	}
   5252 
   5253 	// color_stencil
   5254 	{
   5255 		const Attachment	attachments[] =
   5256 		{
   5257 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5258 					   VK_SAMPLE_COUNT_1_BIT,
   5259 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5260 					   VK_ATTACHMENT_STORE_OP_STORE,
   5261 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5262 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5263 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5264 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
   5265 			Attachment(VK_FORMAT_S8_UINT,
   5266 					   VK_SAMPLE_COUNT_1_BIT,
   5267 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5268 					   VK_ATTACHMENT_STORE_OP_STORE,
   5269 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5270 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5271 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5272 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5273 		};
   5274 
   5275 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
   5276 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5277 																	0u,
   5278 																	vector<AttachmentReference>(),
   5279 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5280 																	vector<AttachmentReference>(),
   5281 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5282 																	vector<deUint32>())),
   5283 										 vector<SubpassDependency>());
   5284 
   5285 
   5286 		addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5287 	}
   5288 
   5289 	// color_depth_stencil
   5290 	{
   5291 		const Attachment	attachments[] =
   5292 		{
   5293 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5294 					   VK_SAMPLE_COUNT_1_BIT,
   5295 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5296 					   VK_ATTACHMENT_STORE_OP_STORE,
   5297 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5298 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5299 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5300 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
   5301 			Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
   5302 					   VK_SAMPLE_COUNT_1_BIT,
   5303 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5304 					   VK_ATTACHMENT_STORE_OP_STORE,
   5305 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5306 					   VK_ATTACHMENT_STORE_OP_STORE,
   5307 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5308 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5309 		};
   5310 
   5311 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
   5312 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5313 																	0u,
   5314 																	vector<AttachmentReference>(),
   5315 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5316 																	vector<AttachmentReference>(),
   5317 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5318 																	vector<deUint32>())),
   5319 										 vector<SubpassDependency>());
   5320 
   5321 		addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5322 	}
   5323 }
   5324 
   5325 std::string formatToName (VkFormat format)
   5326 {
   5327 	const std::string	formatStr	= de::toString(format);
   5328 	const std::string	prefix		= "VK_FORMAT_";
   5329 
   5330 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
   5331 
   5332 	return de::toLower(formatStr.substr(prefix.length()));
   5333 }
   5334 
   5335 void addFormatTests (tcu::TestCaseGroup* group)
   5336 {
   5337 	tcu::TestContext&	testCtx		= group->getTestContext();
   5338 
   5339 	const UVec2			targetSize	(64, 64);
   5340 	const UVec2			renderPos	(0, 0);
   5341 	const UVec2			renderSize	(64, 64);
   5342 
   5343 	const struct
   5344 	{
   5345 		const char* const			str;
   5346 		const VkAttachmentStoreOp	op;
   5347 	} storeOps[] =
   5348 	{
   5349 		{ "store",		VK_ATTACHMENT_STORE_OP_STORE		},
   5350 		{ "dont_care",	VK_ATTACHMENT_STORE_OP_DONT_CARE	}
   5351 	};
   5352 
   5353 	const struct
   5354 	{
   5355 		const char* const			str;
   5356 		const VkAttachmentLoadOp	op;
   5357 	} loadOps[] =
   5358 	{
   5359 		{ "clear",		VK_ATTACHMENT_LOAD_OP_CLEAR		},
   5360 		{ "load",		VK_ATTACHMENT_LOAD_OP_LOAD		},
   5361 		{ "dont_care",	VK_ATTACHMENT_LOAD_OP_DONT_CARE	}
   5362 	};
   5363 
   5364 	const struct
   5365 	{
   5366 		 const char* const				str;
   5367 		 const TestConfig::RenderTypes	types;
   5368 	} renderTypes[] =
   5369 	{
   5370 		{ "clear",		TestConfig::RENDERTYPES_CLEAR								},
   5371 		{ "draw",		TestConfig::RENDERTYPES_DRAW								},
   5372 		{ "clear_draw",	TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW	}
   5373 	};
   5374 
   5375 	// Color formats
   5376 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
   5377 	{
   5378 		const VkFormat					format		= s_coreColorFormats[formatNdx];
   5379 		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
   5380 
   5381 		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5382 		{
   5383 			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
   5384 			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5385 
   5386 			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5387 			{
   5388 				const RenderPass	renderPass	(vector<Attachment>(1, Attachment(format,
   5389 																				  VK_SAMPLE_COUNT_1_BIT,
   5390 																				  loadOp,
   5391 																				  VK_ATTACHMENT_STORE_OP_STORE,
   5392 																				  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5393 																				  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5394 																				  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5395 																				  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5396 												 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5397 																			0u,
   5398 																			vector<AttachmentReference>(),
   5399 																			vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5400 																			vector<AttachmentReference>(),
   5401 																			AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5402 																			vector<deUint32>())),
   5403 												 vector<SubpassDependency>());
   5404 
   5405 				addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5406 			}
   5407 
   5408 			formatGroup->addChild(loadOpGroup.release());
   5409 		}
   5410 
   5411 		{
   5412 			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
   5413 
   5414 			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5415 			{
   5416 				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
   5417 				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5418 
   5419 				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
   5420 				{
   5421 					const VkAttachmentStoreOp		storeOp			= storeOps[storeOpNdx].op;
   5422 					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup	(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
   5423 
   5424 					for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5425 					{
   5426 						{
   5427 							vector<Attachment>			attachments;
   5428 							vector<Subpass>				subpasses;
   5429 							vector<SubpassDependency>	deps;
   5430 
   5431 							attachments.push_back(Attachment(format,
   5432 															 VK_SAMPLE_COUNT_1_BIT,
   5433 															 loadOp,
   5434 															 storeOp,
   5435 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5436 															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5437 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5438 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5439 
   5440 							attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
   5441 															 VK_SAMPLE_COUNT_1_BIT,
   5442 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5443 															 VK_ATTACHMENT_STORE_OP_STORE,
   5444 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5445 															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5446 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5447 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5448 
   5449 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5450 														0u,
   5451 														vector<AttachmentReference>(),
   5452 														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5453 														vector<AttachmentReference>(),
   5454 														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5455 														vector<deUint32>()));
   5456 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5457 														0u,
   5458 														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
   5459 														vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5460 														vector<AttachmentReference>(),
   5461 														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5462 														vector<deUint32>()));
   5463 
   5464 							deps.push_back(SubpassDependency(0, 1,
   5465 
   5466 															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5467 															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5468 
   5469 															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5470 															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5471 															vk::VK_DEPENDENCY_BY_REGION_BIT));
   5472 
   5473 							{
   5474 								const RenderPass renderPass (attachments, subpasses, deps);
   5475 
   5476 								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
   5477 							}
   5478 						}
   5479 						{
   5480 							vector<Attachment>			attachments;
   5481 							vector<Subpass>				subpasses;
   5482 							vector<SubpassDependency>	deps;
   5483 
   5484 							attachments.push_back(Attachment(format,
   5485 															 VK_SAMPLE_COUNT_1_BIT,
   5486 															 loadOp,
   5487 															 storeOp,
   5488 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5489 															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5490 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5491 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5492 
   5493 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5494 														0u,
   5495 														vector<AttachmentReference>(),
   5496 														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5497 														vector<AttachmentReference>(),
   5498 														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5499 														vector<deUint32>()));
   5500 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5501 														0u,
   5502 														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
   5503 														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
   5504 														vector<AttachmentReference>(),
   5505 														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5506 														vector<deUint32>()));
   5507 
   5508 							deps.push_back(SubpassDependency(0, 1,
   5509 															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5510 															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5511 
   5512 															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5513 															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5514 															vk::VK_DEPENDENCY_BY_REGION_BIT));
   5515 
   5516 							{
   5517 								const RenderPass renderPass (attachments, subpasses, deps);
   5518 
   5519 								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
   5520 							}
   5521 						}
   5522 					}
   5523 
   5524 					loadOpGroup->addChild(storeOpGroup.release());
   5525 				}
   5526 
   5527 				inputGroup->addChild(loadOpGroup.release());
   5528 			}
   5529 
   5530 			formatGroup->addChild(inputGroup.release());
   5531 		}
   5532 
   5533 		group->addChild(formatGroup.release());
   5534 	}
   5535 
   5536 	// Depth stencil formats
   5537 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
   5538 	{
   5539 		const VkFormat					vkFormat		= s_coreDepthStencilFormats[formatNdx];
   5540 		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
   5541 
   5542 		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5543 		{
   5544 			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
   5545 			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5546 
   5547 			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5548 			{
   5549 				const tcu::TextureFormat	format				= mapVkFormat(vkFormat);
   5550 				const bool					isStencilAttachment	= hasStencilComponent(format.order);
   5551 				const bool					isDepthAttachment	= hasDepthComponent(format.order);
   5552 				const RenderPass			renderPass			(vector<Attachment>(1, Attachment(vkFormat,
   5553 																				  VK_SAMPLE_COUNT_1_BIT,
   5554 																				  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5555 																				  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5556 																				  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5557 																				  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5558 																				  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5559 																				  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5560 												 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5561 																			0u,
   5562 																			vector<AttachmentReference>(),
   5563 																			vector<AttachmentReference>(),
   5564 																			vector<AttachmentReference>(),
   5565 																			AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5566 																			vector<deUint32>())),
   5567 												 vector<SubpassDependency>());
   5568 
   5569 				addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239));
   5570 			}
   5571 
   5572 			formatGroup->addChild(loadOpGroup.release());
   5573 		}
   5574 
   5575 		{
   5576 			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
   5577 
   5578 			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5579 			{
   5580 				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
   5581 				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5582 
   5583 				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
   5584 				{
   5585 					const VkAttachmentStoreOp		storeOp			= storeOps[storeOpNdx].op;
   5586 					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup	(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
   5587 
   5588 					for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5589 					{
   5590 						{
   5591 							vector<Attachment>			attachments;
   5592 							vector<Subpass>				subpasses;
   5593 							vector<SubpassDependency>	deps;
   5594 
   5595 							attachments.push_back(Attachment(vkFormat,
   5596 															 VK_SAMPLE_COUNT_1_BIT,
   5597 															 loadOp,
   5598 															 storeOp,
   5599 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5600 															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5601 															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5602 															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   5603 
   5604 							attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
   5605 															 VK_SAMPLE_COUNT_1_BIT,
   5606 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5607 															 VK_ATTACHMENT_STORE_OP_STORE,
   5608 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5609 															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5610 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5611 															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5612 
   5613 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5614 														0u,
   5615 														vector<AttachmentReference>(),
   5616 														vector<AttachmentReference>(),
   5617 														vector<AttachmentReference>(),
   5618 														AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5619 														vector<deUint32>()));
   5620 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5621 														0u,
   5622 														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
   5623 														vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5624 														vector<AttachmentReference>(),
   5625 														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5626 														vector<deUint32>()));
   5627 
   5628 							deps.push_back(SubpassDependency(0, 1,
   5629 															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5630 															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5631 
   5632 															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5633 															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5634 															0u));
   5635 
   5636 							deps.push_back(SubpassDependency(1, 1,
   5637 															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5638 															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5639 
   5640 															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5641 															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5642 															vk::VK_DEPENDENCY_BY_REGION_BIT));
   5643 							{
   5644 								const RenderPass renderPass (attachments, subpasses, deps);
   5645 
   5646 								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
   5647 							}
   5648 						}
   5649 						{
   5650 							vector<Attachment>			attachments;
   5651 							vector<Subpass>				subpasses;
   5652 							vector<SubpassDependency>	deps;
   5653 
   5654 							attachments.push_back(Attachment(vkFormat,
   5655 															 VK_SAMPLE_COUNT_1_BIT,
   5656 															 loadOp,
   5657 															 storeOp,
   5658 															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5659 															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5660 															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5661 															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   5662 
   5663 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5664 														0u,
   5665 														vector<AttachmentReference>(),
   5666 														vector<AttachmentReference>(),
   5667 														vector<AttachmentReference>(),
   5668 														AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5669 														vector<deUint32>()));
   5670 							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5671 														0u,
   5672 														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
   5673 														vector<AttachmentReference>(),
   5674 														vector<AttachmentReference>(),
   5675 														AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
   5676 														vector<deUint32>()));
   5677 
   5678 							deps.push_back(SubpassDependency(0, 1,
   5679 															vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5680 															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5681 
   5682 															vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   5683 															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5684 															vk::VK_DEPENDENCY_BY_REGION_BIT));
   5685 
   5686 							{
   5687 								const RenderPass renderPass (attachments, subpasses, deps);
   5688 
   5689 								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246));
   5690 							}
   5691 						}
   5692 					}
   5693 
   5694 					loadOpGroup->addChild(storeOpGroup.release());
   5695 				}
   5696 
   5697 				inputGroup->addChild(loadOpGroup.release());
   5698 			}
   5699 
   5700 			formatGroup->addChild(inputGroup.release());
   5701 		}
   5702 
   5703 		group->addChild(formatGroup.release());
   5704 	}
   5705 }
   5706 
   5707 } // anonymous
   5708 
   5709 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
   5710 {
   5711 	de::MovePtr<tcu::TestCaseGroup>	renderpassTests	(new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
   5712 
   5713 	addTestGroup(renderpassTests.get(), "simple", "Simple basic render pass tests", addSimpleTests);
   5714 	addTestGroup(renderpassTests.get(), "formats", "Tests for different image formats.", addFormatTests);
   5715 	addTestGroup(renderpassTests.get(), "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests);
   5716 	addTestGroup(renderpassTests.get(), "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests);
   5717 
   5718 	return renderpassTests.release();
   5719 }
   5720 
   5721 } // vkt
   5722