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_KHR:	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_KHR:	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<VkInputAttachmentAspectReferenceKHR>	inputAspects = vector<VkInputAttachmentAspectReferenceKHR>())
    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<VkInputAttachmentAspectReferenceKHR>	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<VkInputAttachmentAspectReferenceKHR>	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 VkInputAttachmentAspectReferenceKHR&	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 VkRenderPassInputAttachmentAspectCreateInfoKHR	inputAspectCreateInfo	=
   1185 		{
   1186 			VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR,
   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_KHR
   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_KHR
   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_KHR)
   1952 																	&& (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
   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_KHR)
   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_KHR)
   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_KHR ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
   2219 					| (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR ? 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_KHR)
   2234 				|| (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR))
   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_KHR;
   3042 			const bool					hasDepth		= tcu::hasDepthComponent(format.order)
   3043 														&& layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR;
   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_KHR)
   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_KHR)
   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_KHR)
   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_KHR)
   3172 									&& (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR))
   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_KHR)
   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_KHR)
   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_KHR)
   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_KHR)
   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_KHR)
   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_KHR)
   3825 						inputComponentCount += 1;
   3826 					else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
   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_KHR)
   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_KHR)
   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_KHR)
   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_KHR)
   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 		const std::string extensionName("VK_KHR_dedicated_allocation");
   4404 
   4405 		if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
   4406 			TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
   4407 	}
   4408 
   4409 	if (!renderPassInfo.getInputAspects().empty())
   4410 	{
   4411 		if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_maintenance2")))
   4412 			TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
   4413 	}
   4414 
   4415 	{
   4416 		bool requireDepthStencilLayout = false;
   4417 
   4418 		for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   4419 		{
   4420 			if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
   4421 				|| renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR
   4422 				|| renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
   4423 				|| renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
   4424 			{
   4425 				requireDepthStencilLayout = true;
   4426 				break;
   4427 			}
   4428 		}
   4429 
   4430 		for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++)
   4431 		{
   4432 			const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]);
   4433 
   4434 			for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
   4435 			{
   4436 				if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
   4437 					|| subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
   4438 				{
   4439 					requireDepthStencilLayout = true;
   4440 					break;
   4441 				}
   4442 			}
   4443 
   4444 			for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
   4445 			{
   4446 				if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
   4447 					|| subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
   4448 				{
   4449 					requireDepthStencilLayout = true;
   4450 					break;
   4451 				}
   4452 			}
   4453 
   4454 			for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
   4455 			{
   4456 				if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
   4457 					|| subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
   4458 				{
   4459 					requireDepthStencilLayout = true;
   4460 					break;
   4461 				}
   4462 			}
   4463 
   4464 			if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
   4465 				|| subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
   4466 			{
   4467 				requireDepthStencilLayout = true;
   4468 				break;
   4469 			}
   4470 		}
   4471 
   4472 		if (requireDepthStencilLayout && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_maintenance2")))
   4473 			TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
   4474 	}
   4475 
   4476 	initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
   4477 	initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
   4478 	initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
   4479 	initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
   4480 
   4481 	initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
   4482 	initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
   4483 	initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
   4484 
   4485 	logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
   4486 
   4487 	checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
   4488 
   4489 	{
   4490 		const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
   4491 
   4492 		log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
   4493 
   4494 		for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
   4495 		{
   4496 			 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
   4497 				 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
   4498 		}
   4499 	}
   4500 
   4501 	{
   4502 		const InstanceInterface&					vki									= context.getInstanceInterface();
   4503 		const VkPhysicalDevice&						physDevice							= context.getPhysicalDevice();
   4504 		const VkDevice								device								= context.getDevice();
   4505 		const DeviceInterface&						vk									= context.getDeviceInterface();
   4506 		const VkQueue								queue								= context.getUniversalQueue();
   4507 		const deUint32								queueIndex							= context.getUniversalQueueFamilyIndex();
   4508 		Allocator&									allocator							= context.getDefaultAllocator();
   4509 
   4510 		const Unique<VkRenderPass>					renderPass							(createRenderPass(vk, device, renderPassInfo));
   4511 		const Unique<VkCommandPool>					commandBufferPool					(createCommandPool(vk, device, queueIndex, 0));
   4512 		const Unique<VkCommandBuffer>				initializeImagesCommandBuffer		(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4513 		const Unique<VkCommandBuffer>				renderCommandBuffer					(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4514 		const Unique<VkCommandBuffer>				readImagesToBuffersCommandBuffer	(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
   4515 
   4516 		vector<de::SharedPtr<AttachmentResources> >	attachmentResources;
   4517 		vector<de::SharedPtr<SubpassRenderer> >		subpassRenderers;
   4518 		vector<VkImage>								attachmentImages;
   4519 		vector<VkImageView>							attachmentViews;
   4520 		vector<pair<VkImageView, VkImageView> >		inputAttachmentViews;
   4521 
   4522 		for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
   4523 		{
   4524 			const Attachment&	attachmentInfo	= renderPassInfo.getAttachments()[attachmentNdx];
   4525 
   4526 			attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
   4527 			attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
   4528 			attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
   4529 
   4530 			inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
   4531 		}
   4532 
   4533 		beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
   4534 		pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
   4535 		endCommandBuffer(vk, *initializeImagesCommandBuffer);
   4536 
   4537 		{
   4538 			const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
   4539 
   4540 			for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
   4541 				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)));
   4542 
   4543 			beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
   4544 			pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
   4545 			endCommandBuffer(vk, *renderCommandBuffer);
   4546 
   4547 			beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
   4548 			pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
   4549 			endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
   4550 			{
   4551 				const VkCommandBuffer commandBuffers[] =
   4552 				{
   4553 					*initializeImagesCommandBuffer,
   4554 					*renderCommandBuffer,
   4555 					*readImagesToBuffersCommandBuffer
   4556 				};
   4557 				const Unique<VkFence>	fence		(createFence(vk, device, 0u));
   4558 
   4559 				queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
   4560 				waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
   4561 			}
   4562 		}
   4563 
   4564 		if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
   4565 			return tcu::TestStatus::pass("Pass");
   4566 		else
   4567 			return tcu::TestStatus::fail("Result verification failed");
   4568 	}
   4569 }
   4570 
   4571 static const VkFormat s_coreColorFormats[] =
   4572 {
   4573 	VK_FORMAT_R5G6B5_UNORM_PACK16,
   4574 	VK_FORMAT_R8_UNORM,
   4575 	VK_FORMAT_R8_SNORM,
   4576 	VK_FORMAT_R8_UINT,
   4577 	VK_FORMAT_R8_SINT,
   4578 	VK_FORMAT_R8G8_UNORM,
   4579 	VK_FORMAT_R8G8_SNORM,
   4580 	VK_FORMAT_R8G8_UINT,
   4581 	VK_FORMAT_R8G8_SINT,
   4582 	VK_FORMAT_R8G8B8A8_UNORM,
   4583 	VK_FORMAT_R8G8B8A8_SNORM,
   4584 	VK_FORMAT_R8G8B8A8_UINT,
   4585 	VK_FORMAT_R8G8B8A8_SINT,
   4586 	VK_FORMAT_R8G8B8A8_SRGB,
   4587 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
   4588 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
   4589 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
   4590 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
   4591 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
   4592 	VK_FORMAT_B8G8R8A8_UNORM,
   4593 	VK_FORMAT_B8G8R8A8_SRGB,
   4594 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
   4595 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
   4596 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
   4597 	VK_FORMAT_R16_UNORM,
   4598 	VK_FORMAT_R16_SNORM,
   4599 	VK_FORMAT_R16_UINT,
   4600 	VK_FORMAT_R16_SINT,
   4601 	VK_FORMAT_R16_SFLOAT,
   4602 	VK_FORMAT_R16G16_UNORM,
   4603 	VK_FORMAT_R16G16_SNORM,
   4604 	VK_FORMAT_R16G16_UINT,
   4605 	VK_FORMAT_R16G16_SINT,
   4606 	VK_FORMAT_R16G16_SFLOAT,
   4607 	VK_FORMAT_R16G16B16A16_UNORM,
   4608 	VK_FORMAT_R16G16B16A16_SNORM,
   4609 	VK_FORMAT_R16G16B16A16_UINT,
   4610 	VK_FORMAT_R16G16B16A16_SINT,
   4611 	VK_FORMAT_R16G16B16A16_SFLOAT,
   4612 	VK_FORMAT_R32_UINT,
   4613 	VK_FORMAT_R32_SINT,
   4614 	VK_FORMAT_R32_SFLOAT,
   4615 	VK_FORMAT_R32G32_UINT,
   4616 	VK_FORMAT_R32G32_SINT,
   4617 	VK_FORMAT_R32G32_SFLOAT,
   4618 	VK_FORMAT_R32G32B32A32_UINT,
   4619 	VK_FORMAT_R32G32B32A32_SINT,
   4620 	VK_FORMAT_R32G32B32A32_SFLOAT
   4621 };
   4622 
   4623 static const VkFormat s_coreDepthStencilFormats[] =
   4624 {
   4625 	VK_FORMAT_D16_UNORM,
   4626 
   4627 	VK_FORMAT_X8_D24_UNORM_PACK32,
   4628 	VK_FORMAT_D32_SFLOAT,
   4629 
   4630 	VK_FORMAT_D24_UNORM_S8_UINT,
   4631 	VK_FORMAT_D32_SFLOAT_S8_UINT
   4632 };
   4633 
   4634 void addAttachmentTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   4635 {
   4636 	const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
   4637 	const VkAttachmentLoadOp loadOps[] =
   4638 	{
   4639 		VK_ATTACHMENT_LOAD_OP_LOAD,
   4640 		VK_ATTACHMENT_LOAD_OP_CLEAR,
   4641 		VK_ATTACHMENT_LOAD_OP_DONT_CARE
   4642 	};
   4643 
   4644 	const VkAttachmentStoreOp storeOps[] =
   4645 	{
   4646 		VK_ATTACHMENT_STORE_OP_STORE,
   4647 		VK_ATTACHMENT_STORE_OP_DONT_CARE
   4648 	};
   4649 
   4650 	const VkImageLayout initialAndFinalColorLayouts[] =
   4651 	{
   4652 		VK_IMAGE_LAYOUT_GENERAL,
   4653 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   4654 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4655 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4656 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4657 	};
   4658 
   4659 	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
   4660 	{
   4661 		VK_IMAGE_LAYOUT_GENERAL,
   4662 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   4663 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
   4664 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4665 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4666 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4667 	};
   4668 
   4669 	const VkImageLayout subpassLayouts[] =
   4670 	{
   4671 		VK_IMAGE_LAYOUT_GENERAL,
   4672 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
   4673 	};
   4674 
   4675 	const VkImageLayout depthStencilLayouts[] =
   4676 	{
   4677 		VK_IMAGE_LAYOUT_GENERAL,
   4678 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
   4679 	};
   4680 
   4681 	const TestConfig::RenderTypes renderCommands[] =
   4682 	{
   4683 		TestConfig::RENDERTYPES_NONE,
   4684 		TestConfig::RENDERTYPES_CLEAR,
   4685 		TestConfig::RENDERTYPES_DRAW,
   4686 		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
   4687 	};
   4688 
   4689 	const TestConfig::CommandBufferTypes commandBuffers[] =
   4690 	{
   4691 		TestConfig::COMMANDBUFFERTYPES_INLINE,
   4692 		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
   4693 		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
   4694 	};
   4695 
   4696 	const TestConfig::ImageMemory imageMemories[] =
   4697 	{
   4698 		TestConfig::IMAGEMEMORY_STRICT,
   4699 		TestConfig::IMAGEMEMORY_LAZY,
   4700 		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
   4701 	};
   4702 
   4703 	const UVec2 targetSizes[] =
   4704 	{
   4705 		UVec2(64, 64),
   4706 		UVec2(63, 65)
   4707 	};
   4708 
   4709 	const UVec2 renderPositions[] =
   4710 	{
   4711 		UVec2(0, 0),
   4712 		UVec2(3, 17)
   4713 	};
   4714 
   4715 	const UVec2 renderSizes[] =
   4716 	{
   4717 		UVec2(32, 32),
   4718 		UVec2(60, 47)
   4719 	};
   4720 
   4721 	tcu::TestContext&	testCtx	= group->getTestContext();
   4722 	de::Random			rng		(1433774382u);
   4723 
   4724 	for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
   4725 	{
   4726 		const deUint32					attachmentCount			= attachmentCounts[attachmentCountNdx];
   4727 		const deUint32					testCaseCount			= (attachmentCount == 1 ? 100 : 200);
   4728 		de::MovePtr<tcu::TestCaseGroup>	attachmentCountGroup	(new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
   4729 
   4730 		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
   4731 		{
   4732 			const bool					useDepthStencil		= rng.getBool();
   4733 			VkImageLayout				depthStencilLayout	= VK_IMAGE_LAYOUT_GENERAL;
   4734 			vector<Attachment>			attachments;
   4735 			vector<AttachmentReference>	colorAttachmentReferences;
   4736 
   4737 			for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
   4738 			{
   4739 				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
   4740 				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
   4741 				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4742 				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4743 
   4744 				const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4745 				const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4746 				const VkImageLayout			subpassLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   4747 
   4748 				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4749 				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4750 
   4751 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4752 				colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   4753 			}
   4754 
   4755 			if (useDepthStencil)
   4756 			{
   4757 				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
   4758 				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
   4759 				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4760 				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4761 
   4762 				const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
   4763 				const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
   4764 
   4765 				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4766 				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4767 
   4768 				depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
   4769 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4770 			}
   4771 
   4772 			{
   4773 				const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
   4774 				const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
   4775 				const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
   4776 				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>()));
   4777 				const vector<SubpassDependency>			deps;
   4778 
   4779 				const string							testCaseName	= de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
   4780 				const RenderPass						renderPass		(attachments, subpasses, deps);
   4781 				const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
   4782 				const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
   4783 				const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
   4784 
   4785 				addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809, allocationKind));
   4786 			}
   4787 		}
   4788 
   4789 		group->addChild(attachmentCountGroup.release());
   4790 	}
   4791 }
   4792 
   4793 template<typename T>
   4794 T chooseRandom (de::Random& rng, const set<T>& values)
   4795 {
   4796 	size_t							ndx		= ((size_t)rng.getUint32()) % values.size();
   4797 	typename set<T>::const_iterator	iter	= values.begin();
   4798 
   4799 	for (; ndx > 0; ndx--)
   4800 		iter++;
   4801 
   4802 	return *iter;
   4803 }
   4804 
   4805 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   4806 {
   4807 	const deUint32 attachmentCounts[] = { 4, 8 };
   4808 	const VkAttachmentLoadOp loadOps[] =
   4809 	{
   4810 		VK_ATTACHMENT_LOAD_OP_LOAD,
   4811 		VK_ATTACHMENT_LOAD_OP_CLEAR,
   4812 		VK_ATTACHMENT_LOAD_OP_DONT_CARE
   4813 	};
   4814 
   4815 	const VkAttachmentStoreOp storeOps[] =
   4816 	{
   4817 		VK_ATTACHMENT_STORE_OP_STORE,
   4818 		VK_ATTACHMENT_STORE_OP_DONT_CARE
   4819 	};
   4820 
   4821 	const VkImageLayout initialAndFinalColorLayouts[] =
   4822 	{
   4823 		VK_IMAGE_LAYOUT_GENERAL,
   4824 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   4825 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4826 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4827 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4828 	};
   4829 
   4830 	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
   4831 	{
   4832 		VK_IMAGE_LAYOUT_GENERAL,
   4833 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   4834 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
   4835 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
   4836 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   4837 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
   4838 	};
   4839 
   4840 	const VkImageLayout subpassLayouts[] =
   4841 	{
   4842 		VK_IMAGE_LAYOUT_GENERAL,
   4843 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   4844 	};
   4845 
   4846 	enum AllocationType
   4847 	{
   4848 		// Each pass uses one more attachmen than previous one
   4849 		ALLOCATIONTYPE_GROW,
   4850 		// Each pass uses one less attachment than previous one
   4851 		ALLOCATIONTYPE_SHRINK,
   4852 		// Each pass drops one attachment and picks up new one
   4853 		ALLOCATIONTYPE_ROLL,
   4854 		// Start by growing and end by shrinking
   4855 		ALLOCATIONTYPE_GROW_SHRINK,
   4856 		// Each subpass has single input and single output attachment
   4857 		ALLOCATIONTYPE_IO_CHAIN,
   4858 		// Each subpass has multiple inputs and multiple outputs attachment
   4859 		ALLOCATIONTYPE_IO_GENERIC
   4860 	};
   4861 
   4862 	const AllocationType allocationTypes[] =
   4863 	{
   4864 		ALLOCATIONTYPE_GROW,
   4865 		ALLOCATIONTYPE_SHRINK,
   4866 		ALLOCATIONTYPE_ROLL,
   4867 		ALLOCATIONTYPE_GROW_SHRINK,
   4868 		ALLOCATIONTYPE_IO_CHAIN,
   4869 		ALLOCATIONTYPE_IO_GENERIC
   4870 	};
   4871 
   4872 	const char* const allocationTypeStr[] =
   4873 	{
   4874 		"grow",
   4875 		"shrink",
   4876 		"roll",
   4877 		"grow_shrink",
   4878 		"input_output_chain",
   4879 		"input_output",
   4880 	};
   4881 
   4882 	const TestConfig::RenderTypes renderCommands[] =
   4883 	{
   4884 		TestConfig::RENDERTYPES_NONE,
   4885 		TestConfig::RENDERTYPES_CLEAR,
   4886 		TestConfig::RENDERTYPES_DRAW,
   4887 		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
   4888 	};
   4889 
   4890 	const TestConfig::CommandBufferTypes commandBuffers[] =
   4891 	{
   4892 		TestConfig::COMMANDBUFFERTYPES_INLINE,
   4893 		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
   4894 		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
   4895 	};
   4896 
   4897 	const TestConfig::ImageMemory imageMemories[] =
   4898 	{
   4899 		TestConfig::IMAGEMEMORY_STRICT,
   4900 		TestConfig::IMAGEMEMORY_LAZY,
   4901 		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
   4902 	};
   4903 
   4904 	const UVec2 targetSizes[] =
   4905 	{
   4906 		UVec2(64, 64),
   4907 		UVec2(63, 65)
   4908 	};
   4909 
   4910 	const UVec2 renderPositions[] =
   4911 	{
   4912 		UVec2(0, 0),
   4913 		UVec2(3, 17)
   4914 	};
   4915 
   4916 	const UVec2 renderSizes[] =
   4917 	{
   4918 		UVec2(32, 32),
   4919 		UVec2(60, 47)
   4920 	};
   4921 
   4922 	tcu::TestContext&				testCtx	= group->getTestContext();
   4923 	de::Random						rng		(3700649827u);
   4924 
   4925 	for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
   4926 	{
   4927 		const AllocationType			allocationType		= allocationTypes[allocationTypeNdx];
   4928 		const size_t					testCaseCount		= 100;
   4929 		de::MovePtr<tcu::TestCaseGroup>	allocationTypeGroup	(new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
   4930 
   4931 		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
   4932 		{
   4933 			if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
   4934 			{
   4935 				const deUint32		attachmentCount	= 4u + rng.getUint32() % 31u;
   4936 				const deUint32		subpassCount	= 4u + rng.getUint32() % 31u;
   4937 				vector<Attachment>	attachments;
   4938 
   4939 				set<deUint32>		definedAttachments;
   4940 
   4941 				vector<Subpass>		subpasses;
   4942 				set<deUint32>		colorAttachments;
   4943 				set<deUint32>		depthStencilAttachments;
   4944 
   4945 				for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
   4946 				{
   4947 					const bool					isDepthStencilAttachment	= rng.getFloat() < 0.01f;
   4948 					const VkSampleCountFlagBits	sampleCount					= VK_SAMPLE_COUNT_1_BIT;
   4949 					const VkAttachmentLoadOp	loadOp						= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4950 					const VkAttachmentStoreOp	storeOp						= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4951 
   4952 					const VkImageLayout			initialLayout				= isDepthStencilAttachment
   4953 																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
   4954 																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4955 					const VkImageLayout			finalizeLayout				= isDepthStencilAttachment
   4956 																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
   4957 																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   4958 
   4959 					const VkAttachmentLoadOp	stencilLoadOp				= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   4960 					const VkAttachmentStoreOp	stencilStoreOp				= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   4961 
   4962 					if (isDepthStencilAttachment)
   4963 					{
   4964 						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
   4965 
   4966 						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
   4967 							|| stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
   4968 							definedAttachments.insert(attachmentIndex);
   4969 
   4970 						depthStencilAttachments.insert(attachmentIndex);
   4971 
   4972 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4973 					}
   4974 					else
   4975 					{
   4976 						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
   4977 
   4978 						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
   4979 							definedAttachments.insert(attachmentIndex);
   4980 
   4981 						colorAttachments.insert(attachmentIndex);
   4982 
   4983 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   4984 					}
   4985 				}
   4986 				vector<Maybe<deUint32> >	lastUseOfAttachment	(attachments.size(), nothing<deUint32>());
   4987 				vector<SubpassDependency>	deps;
   4988 
   4989 				for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
   4990 				{
   4991 					const deUint32				colorAttachmentCount		= depthStencilAttachments.empty()
   4992 																			? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
   4993 																			: rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
   4994 					const deUint32				inputAttachmentCount		= rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
   4995 					const bool					useDepthStencilAttachment	= !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
   4996 					std::vector<deUint32>		subpassColorAttachments		(colorAttachmentCount);
   4997 					std::vector<deUint32>		subpassInputAttachments		(inputAttachmentCount);
   4998 					Maybe<deUint32>				depthStencilAttachment		(useDepthStencilAttachment
   4999 																			? just(chooseRandom(rng, depthStencilAttachments))
   5000 																			: nothing<deUint32>());
   5001 					std::vector<deUint32>		subpassPreserveAttachments;
   5002 
   5003 					rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
   5004 					rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
   5005 
   5006 					for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
   5007 						definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
   5008 
   5009 					if (depthStencilAttachment)
   5010 						definedAttachments.insert(*depthStencilAttachment);
   5011 
   5012 					{
   5013 						std::vector<AttachmentReference>	inputAttachmentReferences;
   5014 						std::vector<AttachmentReference>	colorAttachmentReferences;
   5015 						AttachmentReference					depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
   5016 
   5017 						for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
   5018 						{
   5019 							const deUint32		colorAttachmentIndex	= subpassColorAttachments[colorAttachmentNdx];
   5020 							// \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
   5021 							const VkImageLayout	subpassLayout			= VK_IMAGE_LAYOUT_GENERAL;
   5022 
   5023 							if (lastUseOfAttachment[colorAttachmentIndex])
   5024 							{
   5025 								const bool byRegion = rng.getBool();
   5026 
   5027 								deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex,
   5028 																 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5029 																	| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5030 																	| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5031 																	| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5032 
   5033 																 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5034 																	| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5035 																	| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5036 																	| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5037 
   5038 																 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5039 																 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
   5040 
   5041 																 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   5042 							}
   5043 
   5044 							lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
   5045 
   5046 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout));
   5047 						}
   5048 
   5049 						for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
   5050 						{
   5051 							const deUint32		inputAttachmentIndex	= subpassInputAttachments[inputAttachmentNdx];
   5052 							// \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts
   5053 							const VkImageLayout	subpassLayout			= VK_IMAGE_LAYOUT_GENERAL;
   5054 
   5055 							if(lastUseOfAttachment[inputAttachmentIndex])
   5056 							{
   5057 								if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex)
   5058 								{
   5059 									deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
   5060 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5061 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5062 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5063 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5064 
   5065 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5066 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5067 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5068 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5069 
   5070 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   5071 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5072 
   5073 																	 VK_DEPENDENCY_BY_REGION_BIT));
   5074 								}
   5075 								else
   5076 								{
   5077 									const bool byRegion = rng.getBool();
   5078 
   5079 									deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex,
   5080 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5081 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5082 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5083 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5084 
   5085 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5086 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5087 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5088 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5089 
   5090 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   5091 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5092 
   5093 																	 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   5094 								}
   5095 
   5096 								lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
   5097 
   5098 								inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout));
   5099 							}
   5100 						}
   5101 
   5102 						if (depthStencilAttachment)
   5103 						{
   5104 							// \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
   5105 							if (lastUseOfAttachment[*depthStencilAttachment])
   5106 							{
   5107 								if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex)
   5108 								{
   5109 									deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
   5110 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5111 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5112 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5113 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5114 
   5115 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5116 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5117 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5118 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5119 
   5120 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   5121 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5122 
   5123 																	 VK_DEPENDENCY_BY_REGION_BIT));
   5124 								}
   5125 								else
   5126 								{
   5127 									const bool byRegion = rng.getBool();
   5128 
   5129 									deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex,
   5130 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5131 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5132 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5133 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5134 
   5135 																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5136 																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5137 																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5138 																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5139 
   5140 																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   5141 																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5142 
   5143 																	 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   5144 								}
   5145 							}
   5146 
   5147 							lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
   5148 							depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
   5149 						}
   5150 						else
   5151 							depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
   5152 
   5153 						vector<deUint32>	preserveAttachments;
   5154 						for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
   5155 						{
   5156 							if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
   5157 								preserveAttachments.push_back(attachmentIndex);
   5158 						}
   5159 
   5160 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5161 												inputAttachmentReferences,
   5162 												colorAttachmentReferences,
   5163 												vector<AttachmentReference>(),
   5164 												depthStencilAttachmentReference,
   5165 												preserveAttachments));
   5166 					}
   5167 				}
   5168 				{
   5169 					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
   5170 					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
   5171 					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
   5172 
   5173 					const string							testCaseName	= de::toString(testCaseNdx);
   5174 					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
   5175 					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
   5176 					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
   5177 
   5178 					const RenderPass						renderPass		(attachments, subpasses, deps);
   5179 
   5180 					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
   5181 				}
   5182 			}
   5183 			else
   5184 			{
   5185 				const deUint32		attachmentCount	= rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
   5186 				vector<Attachment>	attachments;
   5187 				vector<Subpass>		subpasses;
   5188 
   5189 				for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
   5190 				{
   5191 					const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
   5192 					const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
   5193 					const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   5194 					const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   5195 
   5196 					const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   5197 					const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
   5198 
   5199 					const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
   5200 					const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
   5201 
   5202 					attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
   5203 				}
   5204 
   5205 				if (allocationType == ALLOCATIONTYPE_GROW)
   5206 				{
   5207 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   5208 					{
   5209 						vector<AttachmentReference>	colorAttachmentReferences;
   5210 
   5211 						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
   5212 						{
   5213 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5214 
   5215 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   5216 						}
   5217 
   5218 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5219 												vector<AttachmentReference>(),
   5220 												colorAttachmentReferences,
   5221 												vector<AttachmentReference>(),
   5222 												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5223 												vector<deUint32>()));
   5224 					}
   5225 				}
   5226 				else if (allocationType == ALLOCATIONTYPE_SHRINK)
   5227 				{
   5228 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   5229 					{
   5230 						vector<AttachmentReference>	colorAttachmentReferences;
   5231 
   5232 						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
   5233 						{
   5234 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5235 
   5236 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   5237 						}
   5238 
   5239 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5240 													vector<AttachmentReference>(),
   5241 													colorAttachmentReferences,
   5242 													vector<AttachmentReference>(),
   5243 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5244 													vector<deUint32>()));
   5245 					}
   5246 				}
   5247 				else if (allocationType == ALLOCATIONTYPE_ROLL)
   5248 				{
   5249 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
   5250 					{
   5251 						vector<AttachmentReference>	colorAttachmentReferences;
   5252 
   5253 						for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
   5254 						{
   5255 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5256 
   5257 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
   5258 						}
   5259 
   5260 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5261 													vector<AttachmentReference>(),
   5262 													colorAttachmentReferences,
   5263 													vector<AttachmentReference>(),
   5264 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5265 													vector<deUint32>()));
   5266 					}
   5267 				}
   5268 				else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
   5269 				{
   5270 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   5271 					{
   5272 						vector<AttachmentReference>	colorAttachmentReferences;
   5273 
   5274 						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
   5275 						{
   5276 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5277 
   5278 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   5279 						}
   5280 
   5281 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5282 													vector<AttachmentReference>(),
   5283 													colorAttachmentReferences,
   5284 													vector<AttachmentReference>(),
   5285 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5286 													vector<deUint32>()));
   5287 					}
   5288 
   5289 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
   5290 					{
   5291 						vector<AttachmentReference>	colorAttachmentReferences;
   5292 
   5293 						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
   5294 						{
   5295 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
   5296 
   5297 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
   5298 						}
   5299 
   5300 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5301 											vector<AttachmentReference>(),
   5302 											colorAttachmentReferences,
   5303 											vector<AttachmentReference>(),
   5304 											AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5305 											vector<deUint32>()));
   5306 					}
   5307 				}
   5308 				else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
   5309 				{
   5310 					subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5311 											vector<AttachmentReference>(),
   5312 											vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
   5313 											vector<AttachmentReference>(),
   5314 											AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5315 											vector<deUint32>()));
   5316 
   5317 					for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
   5318 					{
   5319 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
   5320 												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
   5321 												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
   5322 												vector<AttachmentReference>(),
   5323 												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5324 												vector<deUint32>()));
   5325 					}
   5326 				}
   5327 				else
   5328 					DE_FATAL("Unknown allocation type");
   5329 
   5330 				{
   5331 					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
   5332 					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
   5333 					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
   5334 
   5335 					const string							testCaseName	= de::toString(testCaseNdx);
   5336 					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
   5337 					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
   5338 					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
   5339 
   5340 					vector<SubpassDependency>				deps;
   5341 
   5342 					for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
   5343 					{
   5344 						const bool byRegion				= rng.getBool();
   5345 						deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
   5346 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5347 															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5348 															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5349 															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5350 
   5351 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
   5352 															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
   5353 															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
   5354 															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   5355 
   5356 														 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5357 														 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
   5358 
   5359 														 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
   5360 					}
   5361 
   5362 					const RenderPass					renderPass		(attachments, subpasses, deps);
   5363 
   5364 					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
   5365 				}
   5366 			}
   5367 		}
   5368 		group->addChild(allocationTypeGroup.release());
   5369 	}
   5370 }
   5371 
   5372 void addSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5373 {
   5374 	const UVec2	targetSize	(64, 64);
   5375 	const UVec2	renderPos	(0, 0);
   5376 	const UVec2	renderSize	(64, 64);
   5377 
   5378 	// color
   5379 	{
   5380 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5381 																		  VK_SAMPLE_COUNT_1_BIT,
   5382 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5383 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5384 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5385 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5386 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5387 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5388 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5389 																	0u,
   5390 																	vector<AttachmentReference>(),
   5391 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5392 																	vector<AttachmentReference>(),
   5393 																	AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5394 																	vector<deUint32>())),
   5395 										 vector<SubpassDependency>());
   5396 
   5397 		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));
   5398 	}
   5399 
   5400 	// depth
   5401 	{
   5402 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
   5403 																		  VK_SAMPLE_COUNT_1_BIT,
   5404 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5405 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5406 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5407 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5408 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5409 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5410 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5411 																	0u,
   5412 																	vector<AttachmentReference>(),
   5413 																	vector<AttachmentReference>(),
   5414 																	vector<AttachmentReference>(),
   5415 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5416 																	vector<deUint32>())),
   5417 										 vector<SubpassDependency>());
   5418 
   5419 		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));
   5420 	}
   5421 
   5422 	// stencil
   5423 	{
   5424 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
   5425 																		  VK_SAMPLE_COUNT_1_BIT,
   5426 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5427 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5428 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5429 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5430 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5431 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5432 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5433 																	0u,
   5434 																	vector<AttachmentReference>(),
   5435 																	vector<AttachmentReference>(),
   5436 																	vector<AttachmentReference>(),
   5437 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5438 																	vector<deUint32>())),
   5439 										 vector<SubpassDependency>());
   5440 
   5441 		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));
   5442 	}
   5443 
   5444 	// depth_stencil
   5445 	{
   5446 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
   5447 																		  VK_SAMPLE_COUNT_1_BIT,
   5448 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5449 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5450 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
   5451 																		  VK_ATTACHMENT_STORE_OP_STORE,
   5452 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5453 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5454 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5455 																	0u,
   5456 																	vector<AttachmentReference>(),
   5457 																	vector<AttachmentReference>(),
   5458 																	vector<AttachmentReference>(),
   5459 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5460 																	vector<deUint32>())),
   5461 										 vector<SubpassDependency>());
   5462 
   5463 		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));
   5464 	}
   5465 
   5466 	// color_depth
   5467 	{
   5468 		const Attachment	attachments[] =
   5469 		{
   5470 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5471 					   VK_SAMPLE_COUNT_1_BIT,
   5472 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5473 					   VK_ATTACHMENT_STORE_OP_STORE,
   5474 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5475 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5476 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5477 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
   5478 			Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
   5479 					   VK_SAMPLE_COUNT_1_BIT,
   5480 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5481 					   VK_ATTACHMENT_STORE_OP_STORE,
   5482 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5483 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5484 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5485 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5486 		};
   5487 
   5488 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
   5489 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5490 																	0u,
   5491 																	vector<AttachmentReference>(),
   5492 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5493 																	vector<AttachmentReference>(),
   5494 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5495 																	vector<deUint32>())),
   5496 										 vector<SubpassDependency>());
   5497 
   5498 		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));
   5499 	}
   5500 
   5501 	// color_stencil
   5502 	{
   5503 		const Attachment	attachments[] =
   5504 		{
   5505 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5506 					   VK_SAMPLE_COUNT_1_BIT,
   5507 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5508 					   VK_ATTACHMENT_STORE_OP_STORE,
   5509 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5510 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5511 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5512 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
   5513 			Attachment(VK_FORMAT_S8_UINT,
   5514 					   VK_SAMPLE_COUNT_1_BIT,
   5515 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5516 					   VK_ATTACHMENT_STORE_OP_STORE,
   5517 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5518 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5519 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5520 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5521 		};
   5522 
   5523 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
   5524 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5525 																	0u,
   5526 																	vector<AttachmentReference>(),
   5527 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5528 																	vector<AttachmentReference>(),
   5529 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5530 																	vector<deUint32>())),
   5531 										 vector<SubpassDependency>());
   5532 
   5533 
   5534 		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));
   5535 	}
   5536 
   5537 	// color_depth_stencil
   5538 	{
   5539 		const Attachment	attachments[] =
   5540 		{
   5541 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
   5542 					   VK_SAMPLE_COUNT_1_BIT,
   5543 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5544 					   VK_ATTACHMENT_STORE_OP_STORE,
   5545 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5546 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5547 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5548 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
   5549 			Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
   5550 					   VK_SAMPLE_COUNT_1_BIT,
   5551 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5552 					   VK_ATTACHMENT_STORE_OP_STORE,
   5553 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
   5554 					   VK_ATTACHMENT_STORE_OP_STORE,
   5555 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5556 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5557 		};
   5558 
   5559 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
   5560 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5561 																	0u,
   5562 																	vector<AttachmentReference>(),
   5563 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5564 																	vector<AttachmentReference>(),
   5565 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5566 																	vector<deUint32>())),
   5567 										 vector<SubpassDependency>());
   5568 
   5569 		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));
   5570 	}
   5571 }
   5572 
   5573 std::string formatToName (VkFormat format)
   5574 {
   5575 	const std::string	formatStr	= de::toString(format);
   5576 	const std::string	prefix		= "VK_FORMAT_";
   5577 
   5578 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
   5579 
   5580 	return de::toLower(formatStr.substr(prefix.length()));
   5581 }
   5582 
   5583 void addFormatTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   5584 {
   5585 	tcu::TestContext&	testCtx		= group->getTestContext();
   5586 
   5587 	const UVec2			targetSize	(64, 64);
   5588 	const UVec2			renderPos	(0, 0);
   5589 	const UVec2			renderSize	(64, 64);
   5590 
   5591 	const struct
   5592 	{
   5593 		const char* const			str;
   5594 		const VkAttachmentStoreOp	op;
   5595 	} storeOps[] =
   5596 	{
   5597 		{ "store",		VK_ATTACHMENT_STORE_OP_STORE		},
   5598 		{ "dont_care",	VK_ATTACHMENT_STORE_OP_DONT_CARE	}
   5599 	};
   5600 
   5601 	const struct
   5602 	{
   5603 		const char* const			str;
   5604 		const VkAttachmentLoadOp	op;
   5605 	} loadOps[] =
   5606 	{
   5607 		{ "clear",		VK_ATTACHMENT_LOAD_OP_CLEAR		},
   5608 		{ "load",		VK_ATTACHMENT_LOAD_OP_LOAD		},
   5609 		{ "dont_care",	VK_ATTACHMENT_LOAD_OP_DONT_CARE	}
   5610 	};
   5611 
   5612 	const struct
   5613 	{
   5614 		 const char* const				str;
   5615 		 const TestConfig::RenderTypes	types;
   5616 	} renderTypes[] =
   5617 	{
   5618 		{ "clear",		TestConfig::RENDERTYPES_CLEAR								},
   5619 		{ "draw",		TestConfig::RENDERTYPES_DRAW								},
   5620 		{ "clear_draw",	TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW	}
   5621 	};
   5622 
   5623 	// Color formats
   5624 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
   5625 	{
   5626 		const VkFormat					format		= s_coreColorFormats[formatNdx];
   5627 		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
   5628 
   5629 		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5630 		{
   5631 			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
   5632 			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5633 
   5634 			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5635 			{
   5636 				const RenderPass	renderPass	(vector<Attachment>(1, Attachment(format,
   5637 																				  VK_SAMPLE_COUNT_1_BIT,
   5638 																				  loadOp,
   5639 																				  VK_ATTACHMENT_STORE_OP_STORE,
   5640 																				  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5641 																				  VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5642 																				  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5643 																				  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5644 												 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5645 																			0u,
   5646 																			vector<AttachmentReference>(),
   5647 																			vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5648 																			vector<AttachmentReference>(),
   5649 																			AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5650 																			vector<deUint32>())),
   5651 												 vector<SubpassDependency>());
   5652 
   5653 				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));
   5654 			}
   5655 
   5656 			formatGroup->addChild(loadOpGroup.release());
   5657 		}
   5658 
   5659 		{
   5660 			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
   5661 
   5662 			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5663 			{
   5664 				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
   5665 				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5666 
   5667 				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
   5668 				{
   5669 					const VkAttachmentStoreOp		storeOp			= storeOps[storeOpNdx].op;
   5670 					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup	(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
   5671 
   5672 					for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
   5673 					{
   5674 						const bool useInputAspect = useInputAspectNdx != 0;
   5675 
   5676 						for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5677 						{
   5678 							{
   5679 								vector<Attachment>							attachments;
   5680 								vector<Subpass>								subpasses;
   5681 								vector<SubpassDependency>					deps;
   5682 								vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   5683 
   5684 								attachments.push_back(Attachment(format,
   5685 																 VK_SAMPLE_COUNT_1_BIT,
   5686 																 loadOp,
   5687 																 storeOp,
   5688 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5689 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5690 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5691 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5692 
   5693 								attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
   5694 																 VK_SAMPLE_COUNT_1_BIT,
   5695 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5696 																 VK_ATTACHMENT_STORE_OP_STORE,
   5697 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5698 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5699 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5700 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5701 
   5702 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5703 															0u,
   5704 															vector<AttachmentReference>(),
   5705 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5706 															vector<AttachmentReference>(),
   5707 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5708 															vector<deUint32>()));
   5709 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5710 															0u,
   5711 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
   5712 															vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5713 															vector<AttachmentReference>(),
   5714 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5715 															vector<deUint32>()));
   5716 
   5717 								deps.push_back(SubpassDependency(0, 1,
   5718 
   5719 																vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5720 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5721 
   5722 																vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5723 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5724 																vk::VK_DEPENDENCY_BY_REGION_BIT));
   5725 
   5726 								if (useInputAspect)
   5727 								{
   5728 									const VkInputAttachmentAspectReferenceKHR inputAspect =
   5729 									{
   5730 										0u,
   5731 										0u,
   5732 										VK_IMAGE_ASPECT_COLOR_BIT
   5733 									};
   5734 
   5735 									inputAspects.push_back(inputAspect);
   5736 								}
   5737 
   5738 								{
   5739 									const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   5740 
   5741 									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));
   5742 								}
   5743 							}
   5744 							{
   5745 								vector<Attachment>							attachments;
   5746 								vector<Subpass>								subpasses;
   5747 								vector<SubpassDependency>					deps;
   5748 								vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   5749 
   5750 								attachments.push_back(Attachment(format,
   5751 																 VK_SAMPLE_COUNT_1_BIT,
   5752 																 loadOp,
   5753 																 storeOp,
   5754 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5755 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5756 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5757 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5758 
   5759 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5760 															0u,
   5761 															vector<AttachmentReference>(),
   5762 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5763 															vector<AttachmentReference>(),
   5764 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5765 															vector<deUint32>()));
   5766 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5767 															0u,
   5768 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
   5769 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
   5770 															vector<AttachmentReference>(),
   5771 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5772 															vector<deUint32>()));
   5773 
   5774 								deps.push_back(SubpassDependency(0, 1,
   5775 																vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5776 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5777 
   5778 																vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5779 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5780 																vk::VK_DEPENDENCY_BY_REGION_BIT));
   5781 
   5782 								if (useInputAspect)
   5783 								{
   5784 									const VkInputAttachmentAspectReferenceKHR inputAspect =
   5785 									{
   5786 										0u,
   5787 										0u,
   5788 										VK_IMAGE_ASPECT_COLOR_BIT
   5789 									};
   5790 
   5791 									inputAspects.push_back(inputAspect);
   5792 								}
   5793 
   5794 								{
   5795 									const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   5796 
   5797 									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));
   5798 								}
   5799 							}
   5800 						}
   5801 					}
   5802 
   5803 					loadOpGroup->addChild(storeOpGroup.release());
   5804 				}
   5805 
   5806 				inputGroup->addChild(loadOpGroup.release());
   5807 			}
   5808 
   5809 			formatGroup->addChild(inputGroup.release());
   5810 		}
   5811 
   5812 		group->addChild(formatGroup.release());
   5813 	}
   5814 
   5815 	// Depth stencil formats
   5816 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
   5817 	{
   5818 		const VkFormat					vkFormat			= s_coreDepthStencilFormats[formatNdx];
   5819 		const tcu::TextureFormat		format				= mapVkFormat(vkFormat);
   5820 		const bool						isStencilAttachment	= hasStencilComponent(format.order);
   5821 		const bool						isDepthAttachment	= hasDepthComponent(format.order);
   5822 		de::MovePtr<tcu::TestCaseGroup>	formatGroup			(new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
   5823 
   5824 		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5825 		{
   5826 			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
   5827 			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5828 
   5829 			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5830 			{
   5831 				{
   5832 					const RenderPass			renderPass			(vector<Attachment>(1, Attachment(vkFormat,
   5833 																					  VK_SAMPLE_COUNT_1_BIT,
   5834 																					  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5835 																					  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5836 																					  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5837 																					  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5838 																					  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5839 																					  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5840 													 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5841 																				0u,
   5842 																				vector<AttachmentReference>(),
   5843 																				vector<AttachmentReference>(),
   5844 																				vector<AttachmentReference>(),
   5845 																				AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5846 																				vector<deUint32>())),
   5847 													 vector<SubpassDependency>());
   5848 
   5849 					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));
   5850 				}
   5851 
   5852 				if (isStencilAttachment && isDepthAttachment)
   5853 				{
   5854 					{
   5855 						const RenderPass			renderPass			(vector<Attachment>(1, Attachment(vkFormat,
   5856 																								  VK_SAMPLE_COUNT_1_BIT,
   5857 																								  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5858 																								  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5859 																								  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5860 																								  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5861 																								  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5862 																								  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5863 																		 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5864 																									0u,
   5865 																									vector<AttachmentReference>(),
   5866 																									vector<AttachmentReference>(),
   5867 																									vector<AttachmentReference>(),
   5868 																									AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR),
   5869 																									vector<deUint32>())),
   5870 																		 vector<SubpassDependency>());
   5871 
   5872 						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));
   5873 					}
   5874 
   5875 					{
   5876 						const RenderPass			renderPass			(vector<Attachment>(1, Attachment(vkFormat,
   5877 																						  VK_SAMPLE_COUNT_1_BIT,
   5878 																						  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5879 																						  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5880 																						  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5881 																						  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5882 																						  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5883 																						  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
   5884 																		 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5885 																									0u,
   5886 																									vector<AttachmentReference>(),
   5887 																									vector<AttachmentReference>(),
   5888 																									vector<AttachmentReference>(),
   5889 																									AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR),
   5890 																									vector<deUint32>())),
   5891 																		 vector<SubpassDependency>());
   5892 
   5893 						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));
   5894 					}
   5895 				}
   5896 			}
   5897 
   5898 			formatGroup->addChild(loadOpGroup.release());
   5899 		}
   5900 
   5901 		{
   5902 			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
   5903 
   5904 			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
   5905 			{
   5906 				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
   5907 				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
   5908 
   5909 				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
   5910 				{
   5911 					const VkAttachmentStoreOp		storeOp			= storeOps[storeOpNdx].op;
   5912 					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup	(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
   5913 
   5914 					for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
   5915 					{
   5916 						const bool useInputAspect = useInputAspectNdx != 0;
   5917 
   5918 						for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
   5919 						{
   5920 							{
   5921 								vector<Attachment>							attachments;
   5922 								vector<Subpass>								subpasses;
   5923 								vector<SubpassDependency>					deps;
   5924 								vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   5925 
   5926 								attachments.push_back(Attachment(vkFormat,
   5927 																 VK_SAMPLE_COUNT_1_BIT,
   5928 																 loadOp,
   5929 																 storeOp,
   5930 																 loadOp,
   5931 																 storeOp,
   5932 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5933 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   5934 
   5935 								attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
   5936 																 VK_SAMPLE_COUNT_1_BIT,
   5937 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5938 																 VK_ATTACHMENT_STORE_OP_STORE,
   5939 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   5940 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5941 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5942 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   5943 
   5944 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5945 															0u,
   5946 															vector<AttachmentReference>(),
   5947 															vector<AttachmentReference>(),
   5948 															vector<AttachmentReference>(),
   5949 															AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   5950 															vector<deUint32>()));
   5951 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   5952 															0u,
   5953 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
   5954 															vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   5955 															vector<AttachmentReference>(),
   5956 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   5957 															vector<deUint32>()));
   5958 
   5959 								deps.push_back(SubpassDependency(0, 1,
   5960 																vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5961 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5962 
   5963 																vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5964 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5965 																0u));
   5966 
   5967 								deps.push_back(SubpassDependency(1, 1,
   5968 																vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   5969 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   5970 
   5971 																vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   5972 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   5973 																vk::VK_DEPENDENCY_BY_REGION_BIT));
   5974 
   5975 								if (useInputAspect)
   5976 								{
   5977 									const VkInputAttachmentAspectReferenceKHR inputAspect =
   5978 									{
   5979 										0u,
   5980 										0u,
   5981 										(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
   5982 											| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
   5983 									};
   5984 
   5985 									inputAspects.push_back(inputAspect);
   5986 								}
   5987 
   5988 								{
   5989 									const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   5990 
   5991 									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));
   5992 								}
   5993 							}
   5994 							{
   5995 								vector<Attachment>							attachments;
   5996 								vector<Subpass>								subpasses;
   5997 								vector<SubpassDependency>					deps;
   5998 								vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   5999 
   6000 								attachments.push_back(Attachment(vkFormat,
   6001 																 VK_SAMPLE_COUNT_1_BIT,
   6002 																 loadOp,
   6003 																 storeOp,
   6004 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   6005 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   6006 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   6007 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   6008 
   6009 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6010 															0u,
   6011 															vector<AttachmentReference>(),
   6012 															vector<AttachmentReference>(),
   6013 															vector<AttachmentReference>(),
   6014 															AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   6015 															vector<deUint32>()));
   6016 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6017 															0u,
   6018 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
   6019 															vector<AttachmentReference>(),
   6020 															vector<AttachmentReference>(),
   6021 															AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
   6022 															vector<deUint32>()));
   6023 
   6024 								deps.push_back(SubpassDependency(0, 1,
   6025 																vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   6026 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   6027 
   6028 																vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   6029 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   6030 																vk::VK_DEPENDENCY_BY_REGION_BIT));
   6031 
   6032 
   6033 								if (useInputAspect)
   6034 								{
   6035 									const VkInputAttachmentAspectReferenceKHR inputAspect =
   6036 									{
   6037 										0u,
   6038 										0u,
   6039 
   6040 										(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
   6041 											| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
   6042 									};
   6043 
   6044 									inputAspects.push_back(inputAspect);
   6045 								}
   6046 
   6047 								{
   6048 									const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   6049 
   6050 									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));
   6051 								}
   6052 							}
   6053 
   6054 							if (isStencilAttachment && isDepthAttachment)
   6055 							{
   6056 								// Depth read only
   6057 								{
   6058 									vector<Attachment>							attachments;
   6059 									vector<Subpass>								subpasses;
   6060 									vector<SubpassDependency>					deps;
   6061 									vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   6062 
   6063 									attachments.push_back(Attachment(vkFormat,
   6064 																	 VK_SAMPLE_COUNT_1_BIT,
   6065 																	 loadOp,
   6066 																	 storeOp,
   6067 																	 loadOp,
   6068 																	 storeOp,
   6069 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   6070 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   6071 
   6072 									attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
   6073 																	 VK_SAMPLE_COUNT_1_BIT,
   6074 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   6075 																	 VK_ATTACHMENT_STORE_OP_STORE,
   6076 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   6077 																	 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   6078 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   6079 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   6080 
   6081 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6082 																0u,
   6083 																vector<AttachmentReference>(),
   6084 																vector<AttachmentReference>(),
   6085 																vector<AttachmentReference>(),
   6086 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   6087 																vector<deUint32>()));
   6088 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6089 																0u,
   6090 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)),
   6091 																vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   6092 																vector<AttachmentReference>(),
   6093 																AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   6094 																vector<deUint32>()));
   6095 
   6096 									deps.push_back(SubpassDependency(0, 1,
   6097 																	vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   6098 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   6099 
   6100 																	vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   6101 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   6102 																	0u));
   6103 
   6104 									if (useInputAspect)
   6105 									{
   6106 										const VkInputAttachmentAspectReferenceKHR inputAspect =
   6107 										{
   6108 											0u,
   6109 											0u,
   6110 
   6111 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
   6112 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
   6113 										};
   6114 
   6115 										inputAspects.push_back(inputAspect);
   6116 									}
   6117 
   6118 									{
   6119 										const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   6120 
   6121 										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));
   6122 									}
   6123 								}
   6124 								{
   6125 									vector<Attachment>							attachments;
   6126 									vector<Subpass>								subpasses;
   6127 									vector<SubpassDependency>					deps;
   6128 									vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   6129 
   6130 									attachments.push_back(Attachment(vkFormat,
   6131 																	 VK_SAMPLE_COUNT_1_BIT,
   6132 																	 loadOp,
   6133 																	 storeOp,
   6134 																	 loadOp,
   6135 																	 storeOp,
   6136 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   6137 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   6138 
   6139 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6140 																0u,
   6141 																vector<AttachmentReference>(),
   6142 																vector<AttachmentReference>(),
   6143 																vector<AttachmentReference>(),
   6144 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   6145 																vector<deUint32>()));
   6146 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6147 																0u,
   6148 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)),
   6149 																vector<AttachmentReference>(),
   6150 																vector<AttachmentReference>(),
   6151 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR),
   6152 																vector<deUint32>()));
   6153 
   6154 									deps.push_back(SubpassDependency(0, 1,
   6155 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   6156 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   6157 
   6158 																	vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   6159 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   6160 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
   6161 
   6162 									deps.push_back(SubpassDependency(1, 1,
   6163 																	vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   6164 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   6165 
   6166 																	vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   6167 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   6168 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
   6169 
   6170 
   6171 									if (useInputAspect)
   6172 									{
   6173 										const VkInputAttachmentAspectReferenceKHR inputAspect =
   6174 										{
   6175 											0u,
   6176 											0u,
   6177 
   6178 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
   6179 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
   6180 										};
   6181 
   6182 										inputAspects.push_back(inputAspect);
   6183 									}
   6184 
   6185 									{
   6186 										const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   6187 
   6188 										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));
   6189 									}
   6190 								}
   6191 								// Stencil read only
   6192 								{
   6193 									vector<Attachment>							attachments;
   6194 									vector<Subpass>								subpasses;
   6195 									vector<SubpassDependency>					deps;
   6196 									vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   6197 
   6198 									attachments.push_back(Attachment(vkFormat,
   6199 																	 VK_SAMPLE_COUNT_1_BIT,
   6200 																	 loadOp,
   6201 																	 storeOp,
   6202 																	 loadOp,
   6203 																	 storeOp,
   6204 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   6205 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   6206 
   6207 									attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
   6208 																	 VK_SAMPLE_COUNT_1_BIT,
   6209 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   6210 																	 VK_ATTACHMENT_STORE_OP_STORE,
   6211 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   6212 																	 VK_ATTACHMENT_STORE_OP_DONT_CARE,
   6213 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   6214 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
   6215 
   6216 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6217 																0u,
   6218 																vector<AttachmentReference>(),
   6219 																vector<AttachmentReference>(),
   6220 																vector<AttachmentReference>(),
   6221 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   6222 																vector<deUint32>()));
   6223 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6224 																0u,
   6225 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)),
   6226 																vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
   6227 																vector<AttachmentReference>(),
   6228 																AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
   6229 																vector<deUint32>()));
   6230 
   6231 									deps.push_back(SubpassDependency(0, 1,
   6232 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   6233 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   6234 
   6235 																	vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   6236 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   6237 																	0u));
   6238 
   6239 									if (useInputAspect)
   6240 									{
   6241 										const VkInputAttachmentAspectReferenceKHR inputAspect =
   6242 										{
   6243 											0u,
   6244 											0u,
   6245 
   6246 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
   6247 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
   6248 										};
   6249 
   6250 										inputAspects.push_back(inputAspect);
   6251 									}
   6252 
   6253 									{
   6254 										const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   6255 
   6256 										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));
   6257 									}
   6258 								}
   6259 								{
   6260 									vector<Attachment>							attachments;
   6261 									vector<Subpass>								subpasses;
   6262 									vector<SubpassDependency>					deps;
   6263 									vector<VkInputAttachmentAspectReferenceKHR>	inputAspects;
   6264 
   6265 									attachments.push_back(Attachment(vkFormat,
   6266 																	 VK_SAMPLE_COUNT_1_BIT,
   6267 																	 loadOp,
   6268 																	 storeOp,
   6269 																	 loadOp,
   6270 																	 storeOp,
   6271 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   6272 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
   6273 
   6274 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6275 																0u,
   6276 																vector<AttachmentReference>(),
   6277 																vector<AttachmentReference>(),
   6278 																vector<AttachmentReference>(),
   6279 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
   6280 																vector<deUint32>()));
   6281 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
   6282 																0u,
   6283 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)),
   6284 																vector<AttachmentReference>(),
   6285 																vector<AttachmentReference>(),
   6286 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR),
   6287 																vector<deUint32>()));
   6288 
   6289 									deps.push_back(SubpassDependency(0, 1,
   6290 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
   6291 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   6292 
   6293 																	vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
   6294 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   6295 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
   6296 
   6297 									deps.push_back(SubpassDependency(1, 1,
   6298 																	vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   6299 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   6300 
   6301 																	vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   6302 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
   6303 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
   6304 
   6305 
   6306 									if (useInputAspect)
   6307 									{
   6308 										const VkInputAttachmentAspectReferenceKHR inputAspect =
   6309 										{
   6310 											0u,
   6311 											0u,
   6312 
   6313 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
   6314 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
   6315 										};
   6316 
   6317 										inputAspects.push_back(inputAspect);
   6318 									}
   6319 
   6320 									{
   6321 										const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
   6322 
   6323 										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));
   6324 									}
   6325 								}
   6326 							}
   6327 						}
   6328 					}
   6329 
   6330 					loadOpGroup->addChild(storeOpGroup.release());
   6331 				}
   6332 
   6333 				inputGroup->addChild(loadOpGroup.release());
   6334 			}
   6335 
   6336 			formatGroup->addChild(inputGroup.release());
   6337 		}
   6338 
   6339 		group->addChild(formatGroup.release());
   6340 	}
   6341 }
   6342 
   6343 void addRenderPassTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
   6344 {
   6345 	addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, allocationKind);
   6346 	addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, allocationKind);
   6347 	addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, allocationKind);
   6348 	addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, allocationKind);
   6349 }
   6350 
   6351 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx)
   6352 {
   6353 	de::MovePtr<tcu::TestCaseGroup>	suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
   6354 
   6355 	addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED);
   6356 
   6357 	return suballocationTestsGroup;
   6358 }
   6359 
   6360 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx)
   6361 {
   6362 	de::MovePtr<tcu::TestCaseGroup>	dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
   6363 
   6364 	addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED);
   6365 
   6366 	return dedicatedAllocationTestsGroup;
   6367 }
   6368 
   6369 } // anonymous
   6370 
   6371 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
   6372 {
   6373 	de::MovePtr<tcu::TestCaseGroup>	renderpassTests					(new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
   6374 	de::MovePtr<tcu::TestCaseGroup>	suballocationTestGroup			= createSuballocationTests(testCtx);
   6375 	de::MovePtr<tcu::TestCaseGroup>	dedicatedAllocationTestGroup	= createDedicatedAllocationTests(testCtx);
   6376 
   6377 	suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
   6378 	suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx));
   6379 
   6380 	renderpassTests->addChild(suballocationTestGroup.release());
   6381 	renderpassTests->addChild(dedicatedAllocationTestGroup.release());
   6382 
   6383 	return renderpassTests.release();
   6384 }
   6385 
   6386 } // vkt
   6387