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