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