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