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