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