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