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