• 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::__anone08f04e90111::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::__anone08f04e90111::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 	VkStencilOp		stencilOp		= writeStencil ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP;
2014 
2015 	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
2016 	{
2017 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// sType
2018 		DE_NULL,													// pNext
2019 		(VkPipelineDepthStencilStateCreateFlags)0u,
2020 		writeDepth,													// depthTestEnable
2021 		writeDepth,													// depthWriteEnable
2022 		VK_COMPARE_OP_ALWAYS,										// depthCompareOp
2023 		VK_FALSE,													// depthBoundsEnable
2024 		writeStencil,												// stencilTestEnable
2025 		{
2026 			stencilOp,												// stencilFailOp
2027 			stencilOp,												// stencilPassOp
2028 			stencilOp,												// stencilDepthFailOp
2029 			VK_COMPARE_OP_ALWAYS,									// stencilCompareOp
2030 			~0u,													// stencilCompareMask
2031 			~0u,													// stencilWriteMask
2032 			((stencilIndex % 2) == 0) ? ~0x0u : 0x0u				// stencilReference
2033 		},															// front
2034 		{
2035 			stencilOp,												// stencilFailOp
2036 			stencilOp,												// stencilPassOp
2037 			stencilOp,												// stencilDepthFailOp
2038 			VK_COMPARE_OP_ALWAYS,									// stencilCompareOp
2039 			~0u,													// stencilCompareMask
2040 			~0u,													// stencilWriteMask
2041 			((stencilIndex % 2) == 0) ? ~0x0u : 0x0u				// stencilReference
2042 		},															// back
2043 
2044 		0.0f,														// minDepthBounds;
2045 		1.0f														// maxDepthBounds;
2046 	};
2047 
2048 	const VkPipelineColorBlendStateCreateInfo blendState =
2049 	{
2050 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,			// sType
2051 		DE_NULL,															// pNext
2052 		(VkPipelineColorBlendStateCreateFlags)0u,
2053 		VK_FALSE,															// logicOpEnable
2054 		VK_LOGIC_OP_COPY,													// logicOp
2055 		(deUint32)attachmentBlendStates.size(),								// attachmentCount
2056 		attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
2057 		{ 0.0f, 0.0f, 0.0f, 0.0f }											// blendConst
2058 	};
2059 
2060 #ifndef CTS_USES_VULKANSC
2061 	std::vector<vk::VkFormat> colorAttachmentFormats;
2062 	for (deUint32 i = 0; i < renderInfo.getColorAttachmentCount(); ++i)
2063 		colorAttachmentFormats.push_back(renderInfo.getColorAttachment(i).getFormat());
2064 
2065 	vk::VkFormat depthFormat = VK_FORMAT_UNDEFINED;
2066 	vk::VkFormat stencilFormat = VK_FORMAT_UNDEFINED;
2067 	if (renderInfo.getDepthStencilAttachment())
2068 	{
2069 		const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
2070 		vk::VkFormat depthStencilFormat = attachment.getFormat();
2071 		if (depthStencilFormat != VK_FORMAT_UNDEFINED)
2072 		{
2073 			if (tcu::hasDepthComponent(mapVkFormat(depthStencilFormat).order))
2074 			{
2075 				depthFormat = depthStencilFormat;
2076 			}
2077 			if (tcu::hasStencilComponent(mapVkFormat(depthStencilFormat).order))
2078 			{
2079 				stencilFormat = depthStencilFormat;
2080 			}
2081 		}
2082 	}
2083 
2084 
2085 	VkPipelineRenderingCreateInfoKHR renderingCreateInfo
2086 	{
2087 		VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
2088 		DE_NULL,
2089 		0u,
2090 		static_cast<deUint32>(colorAttachmentFormats.size()),
2091 		colorAttachmentFormats.data(),
2092 		depthFormat,
2093 		stencilFormat
2094 	};
2095 #endif // CTS_USES_VULKANSC
2096 
2097 	return makeGraphicsPipeline(vk,												// const DeviceInterface&                        vk
2098 								device,											// const VkDevice                                device
2099 								pipelineLayout,									// const VkPipelineLayout                        pipelineLayout
2100 								vertexShaderModule,								// const VkShaderModule                          vertexShaderModule
2101 								DE_NULL,										// const VkShaderModule                          tessellationControlShaderModule
2102 								DE_NULL,										// const VkShaderModule                          tessellationEvalShaderModule
2103 								DE_NULL,										// const VkShaderModule                          geometryShaderModule
2104 								fragmentShaderModule,							// const VkShaderModule                          fragmentShaderModule
2105 								renderPass,										// const VkRenderPass                            renderPass
2106 								renderInfo.getSubpassIndex(),					// const deUint32                                subpass
2107 								&vertexInputState,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
2108 								&inputAssemblyState,							// const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2109 								DE_NULL,										// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2110 								&viewportState,									// const VkPipelineViewportStateCreateInfo*      pViewportStat;
2111 								&rasterizationState,							// const VkPipelineRasterizationStateCreateInfo* pRasterizationState
2112 								&multisampleState,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
2113 								&depthStencilState,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
2114 								renderInfo.getOmitBlendState()
2115 									? DE_NULL : &blendState,					// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
2116 								DE_NULL,										// const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
2117 #ifndef CTS_USES_VULKANSC
2118 								(renderPass == DE_NULL)
2119 									? &renderingCreateInfo : DE_NULL);			// const void*                                   pNext)
2120 #else
2121 								DE_NULL);										// const void*                                   pNext)
2122 #endif // CTS_USES_VULKANSC
2123 }
2124 
2125 #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)2126 void beginDynamicRendering(const DeviceInterface&								vk,
2127 						   VkCommandBuffer										commandBuffer,
2128 						   const RenderPass&									renderPassInfo,
2129 						   const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
2130 						   const VkRect2D&										renderArea,
2131 						   const vector<Maybe<VkClearValue> >&					renderPassClearValues,
2132 						   const VkRenderingFlagsKHR							renderingFlags = 0u)
2133 {
2134 	const float			clearNan		= tcu::Float32::nan().asFloat();
2135 	const VkClearValue	clearValueNan	= makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan);
2136 
2137 	// translate structures that were prepared to construct renderpass to structures needed for dynamic rendering
2138 
2139 	std::vector<vk::VkRenderingAttachmentInfoKHR>	colorAttachmentVect;
2140 	const Subpass&									subpassInfo				= renderPassInfo.getSubpasses()[0];
2141 	const vector<AttachmentReference>&				colorAttachmentsInfo	= subpassInfo.getColorAttachments();
2142 	const vector<AttachmentReference>&				resolveAttachmentsInfo	= subpassInfo.getResolveAttachments();
2143 
2144 	for (deUint32 i = 0; i < colorAttachmentsInfo.size(); ++i)
2145 	{
2146 		const AttachmentReference&		colorAttachmentReference	= colorAttachmentsInfo[i];
2147 		const deUint32					colorAttachmentIndex		= colorAttachmentReference.getAttachment();
2148 		const Attachment&				colorAttachmentInfo			= renderPassInfo.getAttachments()[colorAttachmentIndex];
2149 
2150 		VkResolveModeFlagBits			resolveMode					= VK_RESOLVE_MODE_NONE;
2151 		VkImageView						resolveImageView			= DE_NULL;
2152 		VkImageLayout					resolveImageLayout			= VK_IMAGE_LAYOUT_UNDEFINED;
2153 
2154 		// handle resolve attachments if they were specified
2155 		if (!resolveAttachmentsInfo.empty())
2156 		{
2157 			const AttachmentReference&	resolveAttachmentReference	= resolveAttachmentsInfo[i];
2158 			const deUint32				resolveAttachmentIndex		= resolveAttachmentReference.getAttachment();
2159 			const Attachment&			resolveAttachmentInfo		= renderPassInfo.getAttachments()[resolveAttachmentIndex];
2160 
2161 			resolveMode			= VK_RESOLVE_MODE_AVERAGE_BIT;
2162 			resolveImageView	= attachmentResources[resolveAttachmentIndex]->getAttachmentView();
2163 			resolveImageLayout	= resolveAttachmentInfo.getInitialLayout();
2164 		}
2165 
2166 		colorAttachmentVect.push_back({
2167 			vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,			// VkStructureType			sType
2168 			DE_NULL,														// const void*				pNext
2169 			attachmentResources[colorAttachmentIndex]->getAttachmentView(),	// VkImageView				imageView
2170 			colorAttachmentReference.getImageLayout(),						// VkImageLayout			imageLayout
2171 			resolveMode,													// VkResolveModeFlagBits	resolveMode
2172 			resolveImageView,												// VkImageView				resolveImageView
2173 			resolveImageLayout,												// VkImageLayout			resolveImageLayout
2174 			colorAttachmentInfo.getLoadOp(),								// VkAttachmentLoadOp		loadOp
2175 			colorAttachmentInfo.getStoreOp(),								// VkAttachmentStoreOp		storeOp
2176 			(renderPassClearValues[colorAttachmentIndex] ?
2177 				*renderPassClearValues[colorAttachmentIndex] :
2178 				clearValueNan)												// VkClearValue				clearValue
2179 			});
2180 	}
2181 
2182 	VkRenderingAttachmentInfoKHR*	pDepthAttachment	= DE_NULL;
2183 	VkRenderingAttachmentInfoKHR*	pStencilAttachment	= DE_NULL;
2184 	VkRenderingAttachmentInfoKHR	depthAttachment
2185 	{
2186 		vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,				// VkStructureType			sType;
2187 		DE_NULL,															// const void*				pNext;
2188 		DE_NULL,															// VkImageView				imageView;
2189 		VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout			imageLayout;
2190 		VK_RESOLVE_MODE_NONE,												// VkResolveModeFlagBits	resolveMode;
2191 		DE_NULL,															// VkImageView				resolveImageView;
2192 		VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout			resolveImageLayout;
2193 		VK_ATTACHMENT_LOAD_OP_LOAD,											// VkAttachmentLoadOp		loadOp;
2194 		VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp		storeOp;
2195 		clearValueNan														// VkClearValue				clearValue;
2196 	};
2197 	VkRenderingAttachmentInfoKHR	stencilAttachment					= depthAttachment;
2198 	const AttachmentReference&		depthStencilAttachmentReference		= subpassInfo.getDepthStencilAttachment();
2199 	const deUint32					dsAttachmentIndex					= depthStencilAttachmentReference.getAttachment();
2200 
2201 	if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
2202 	{
2203 		const Attachment&			dsAttachmentInfo	= renderPassInfo.getAttachments()[dsAttachmentIndex];
2204 		const tcu::TextureFormat	format				= mapVkFormat(dsAttachmentInfo.getFormat());
2205 
2206 		if (tcu::hasDepthComponent(format.order))
2207 		{
2208 			depthAttachment.imageView		= attachmentResources[dsAttachmentIndex]->getAttachmentView();
2209 			depthAttachment.imageLayout		= depthStencilAttachmentReference.getImageLayout();
2210 			depthAttachment.loadOp			= dsAttachmentInfo.getLoadOp();
2211 			depthAttachment.storeOp			= dsAttachmentInfo.getStoreOp();
2212 
2213 			if (renderPassClearValues[dsAttachmentIndex])
2214 				depthAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2215 
2216 			pDepthAttachment = &depthAttachment;
2217 		}
2218 
2219 		if (tcu::hasStencilComponent(format.order))
2220 		{
2221 			stencilAttachment.imageView = attachmentResources[dsAttachmentIndex]->getAttachmentView();
2222 			stencilAttachment.imageLayout = depthStencilAttachmentReference.getImageLayout();
2223 			stencilAttachment.loadOp = dsAttachmentInfo.getStencilLoadOp();
2224 			stencilAttachment.storeOp = dsAttachmentInfo.getStencilStoreOp();
2225 
2226 			if (renderPassClearValues[dsAttachmentIndex])
2227 				stencilAttachment.clearValue = *renderPassClearValues[dsAttachmentIndex];
2228 
2229 			pStencilAttachment = &stencilAttachment;
2230 		}
2231 	}
2232 
2233 	vk::VkRenderingInfoKHR renderingInfo
2234 	{
2235 		vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2236 		DE_NULL,
2237 		renderingFlags,														// VkRenderingFlagsKHR					flags;
2238 		renderArea,															// VkRect2D								renderArea;
2239 		1u,																	// deUint32								layerCount;
2240 		0u,																	// deUint32								viewMask;
2241 		static_cast<deUint32>(colorAttachmentVect.size()),					// deUint32								colorAttachmentCount;
2242 		colorAttachmentVect.empty() ? DE_NULL : &colorAttachmentVect[0],	// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
2243 		pDepthAttachment,													// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
2244 		pStencilAttachment													// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
2245 	};
2246 
2247 	vk.cmdBeginRendering(commandBuffer, &renderingInfo);
2248 }
2249 
endDynamicRendering(const DeviceInterface & vk,VkCommandBuffer commandBuffer)2250 void endDynamicRendering(const DeviceInterface&	vk, VkCommandBuffer commandBuffer)
2251 {
2252 	vk.cmdEndRendering(commandBuffer);
2253 }
2254 #endif // CTS_USES_VULKANSC
2255 
2256 class SubpassRenderer
2257 {
2258 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)2259 	SubpassRenderer (Context&												context,
2260 					 const DeviceInterface&									vk,
2261 					 VkDevice												device,
2262 					 Allocator&												allocator,
2263 					 const RenderPass&										renderPassInfo,
2264 					 const vector<de::SharedPtr<AttachmentResources> >&		attachmentResources,
2265 					 const VkRect2D&										renderArea,
2266 					 const vector<Maybe<VkClearValue> >&					renderPassClearValues,
2267 					 VkRenderPass											renderPass,
2268 					 VkFramebuffer											framebuffer,
2269 					 VkCommandPool											commandBufferPool,
2270 					 deUint32												queueFamilyIndex,
2271 					 const vector<VkImage>&									attachmentImages,
2272 					 const vector<pair<VkImageView, VkImageView> >&			attachmentViews,
2273 					 const SubpassRenderInfo&								renderInfo,
2274 					 const AllocationKind									allocationKind,
2275 					 const bool												dynamicRendering,
2276 					 const bool												secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2277 		: m_renderInfo	(renderInfo)
2278 	{
2279 		// unreference values not used by Vulkan SC, no need to pu this under ifdef
2280 		DE_UNREF(attachmentResources);
2281 		DE_UNREF(renderArea);
2282 		DE_UNREF(renderPassClearValues);
2283 
2284 		const InstanceInterface&				vki				= context.getInstanceInterface();
2285 		const VkPhysicalDevice&					physDevice		= context.getPhysicalDevice();
2286 		const vector<Attachment>&				attachmentInfos	= renderPassInfo.getAttachments();
2287 		const deUint32							subpassIndex	= renderInfo.getSubpassIndex();
2288 		vector<VkDescriptorSetLayoutBinding>	bindings;
2289 
2290 		for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount();  colorAttachmentNdx++)
2291 		{
2292 			const deUint32 attachmentNdx	= (renderInfo.getColorAttachmentIndex(colorAttachmentNdx) == VK_ATTACHMENT_UNUSED) ? colorAttachmentNdx
2293 											: renderInfo.getColorAttachmentIndex(colorAttachmentNdx);
2294 
2295 			m_colorAttachmentImages.push_back(attachmentImages[attachmentNdx]);
2296 		}
2297 
2298 		if (renderInfo.getDepthStencilAttachmentIndex())
2299 			m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
2300 
2301 		if (renderInfo.getRenderQuad())
2302 		{
2303 			const RenderQuad&	renderQuad	= *renderInfo.getRenderQuad();
2304 
2305 			if (renderInfo.getInputAttachmentCount() > 0)
2306 			{
2307 				deUint32								bindingIndex	= 0;
2308 
2309 				for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2310 				{
2311 					const Attachment			attachmentInfo	= attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2312 					const VkImageLayout			layout			= renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2313 					const tcu::TextureFormat	format			= mapVkFormat(attachmentInfo.getFormat());
2314 					const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
2315 					const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
2316 					const deUint32				bindingCount	= (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2317 																	&& (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2318 																? 2u
2319 																: 1u;
2320 
2321 					for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
2322 					{
2323 						const VkDescriptorSetLayoutBinding binding =
2324 						{
2325 							bindingIndex,
2326 							vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2327 							1u,
2328 							vk::VK_SHADER_STAGE_FRAGMENT_BIT,
2329 							DE_NULL
2330 						};
2331 
2332 						bindings.push_back(binding);
2333 						bindingIndex++;
2334 					}
2335 				}
2336 
2337 				const VkDescriptorSetLayoutCreateInfo createInfo =
2338 				{
2339 					vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2340 					DE_NULL,
2341 
2342 					0u,
2343 					(deUint32)bindings.size(),
2344 					&bindings[0]
2345 				};
2346 
2347 				m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
2348 			}
2349 
2350 			const VkDescriptorSetLayout			descriptorSetLayout		= *m_descriptorSetLayout;
2351 			const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
2352 			{
2353 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType;
2354 				DE_NULL,												// pNext;
2355 				(vk::VkPipelineLayoutCreateFlags)0,
2356 				m_descriptorSetLayout ? 1u :0u ,						// setLayoutCount;
2357 				m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL,	// pSetLayouts;
2358 				0u,														// pushConstantRangeCount;
2359 				DE_NULL,												// pPushConstantRanges;
2360 			};
2361 
2362 			m_vertexShaderModule	= createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
2363 			m_fragmentShaderModule	= createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
2364 			m_pipelineLayout		= createPipelineLayout(vk, device, &pipelineLayoutParams);
2365 			m_pipeline				= createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
2366 
2367 			// Round up the vertex buffer size to honor nonCoherentAtomSize.
2368 			const auto	properties			= vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2369 			const auto	vertexBufferSize	= de::roundUp(static_cast<VkDeviceSize>(renderQuad.getVertexDataSize()), properties.limits.nonCoherentAtomSize);
2370 
2371 			m_vertexBuffer			= createBuffer(vk, device, 0u, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
2372 			m_vertexBufferMemory	= allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
2373 
2374 			bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
2375 
2376 			uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer(), properties.limits.nonCoherentAtomSize);
2377 
2378 			if (renderInfo.getInputAttachmentCount() > 0)
2379 			{
2380 				{
2381 					const VkDescriptorPoolSize poolSize =
2382 					{
2383 						vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2384 						// \note Reserve 2 per input attachment since depthStencil attachments require 2.
2385 						renderInfo.getInputAttachmentCount() * 2u
2386 					};
2387 					const VkDescriptorPoolCreateInfo createInfo =
2388 					{
2389 						vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2390 						DE_NULL,
2391 						VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2392 
2393 						// \note Reserve 2 per input attachment since depthStencil attachments require 2.
2394 						renderInfo.getInputAttachmentCount() * 2u,
2395 						1u,
2396 						&poolSize
2397 					};
2398 
2399 					m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
2400 				}
2401 				{
2402 					const VkDescriptorSetAllocateInfo	allocateInfo =
2403 					{
2404 						vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2405 						DE_NULL,
2406 
2407 						*m_descriptorPool,
2408 						1u,
2409 						&descriptorSetLayout
2410 					};
2411 
2412 					m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
2413 				}
2414 				{
2415 					vector<VkWriteDescriptorSet>	writes			(bindings.size());
2416 					vector<VkDescriptorImageInfo>	imageInfos		(bindings.size());
2417 					deUint32						bindingIndex	= 0;
2418 
2419 					for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2420 					{
2421 						const Attachment			attachmentInfo			= attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2422 						const tcu::TextureFormat	format					= mapVkFormat(attachmentInfo.getFormat());
2423 						const bool					isDepthFormat			= tcu::hasDepthComponent(format.order);
2424 						const bool					isStencilFormat			= tcu::hasStencilComponent(format.order);
2425 						const VkImageLayout			inputAttachmentLayout	= renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2426 
2427 
2428 						if (isDepthFormat && isStencilFormat)
2429 						{
2430 							if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
2431 							{
2432 								const VkDescriptorImageInfo	imageInfo =
2433 								{
2434 									(VkSampler)0,
2435 									attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2436 									inputAttachmentLayout
2437 								};
2438 								imageInfos[bindingIndex] = imageInfo;
2439 
2440 								{
2441 									const VkWriteDescriptorSet	write =
2442 									{
2443 										VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2444 										DE_NULL,
2445 
2446 										*m_descriptorSet,
2447 										bindingIndex,
2448 										0u,
2449 										1u,
2450 										VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2451 										&imageInfos[bindingIndex],
2452 										DE_NULL,
2453 										DE_NULL
2454 									};
2455 									writes[bindingIndex] = write;
2456 
2457 									bindingIndex++;
2458 								}
2459 							}
2460 
2461 							if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2462 							{
2463 								const VkDescriptorImageInfo	imageInfo =
2464 								{
2465 									(VkSampler)0,
2466 									attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2467 									inputAttachmentLayout
2468 								};
2469 								imageInfos[bindingIndex] = imageInfo;
2470 
2471 								{
2472 									const VkWriteDescriptorSet	write =
2473 									{
2474 										VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2475 										DE_NULL,
2476 
2477 										*m_descriptorSet,
2478 										bindingIndex,
2479 										0u,
2480 										1u,
2481 										VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2482 										&imageInfos[bindingIndex],
2483 										DE_NULL,
2484 										DE_NULL
2485 									};
2486 									writes[bindingIndex] = write;
2487 
2488 									bindingIndex++;
2489 								}
2490 							}
2491 						}
2492 						else
2493 						{
2494 							const VkDescriptorImageInfo	imageInfo =
2495 							{
2496 								(VkSampler)0,
2497 								attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2498 								inputAttachmentLayout
2499 							};
2500 							imageInfos[bindingIndex] = imageInfo;
2501 
2502 							{
2503 								const VkWriteDescriptorSet	write =
2504 								{
2505 									VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2506 									DE_NULL,
2507 
2508 									*m_descriptorSet,
2509 									bindingIndex,
2510 									0u,
2511 									1u,
2512 									VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2513 									&imageInfos[bindingIndex],
2514 									DE_NULL,
2515 									DE_NULL
2516 								};
2517 								writes[bindingIndex] = write;
2518 
2519 								bindingIndex++;
2520 							}
2521 						}
2522 					}
2523 
2524 					vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2525 				}
2526 			}
2527 		}
2528 
2529 		if (renderInfo.isSecondary())
2530 		{
2531 			m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2532 
2533 			beginCommandBuffer(vk, *m_commandBuffer, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0,
2534 							   (VkQueryPipelineStatisticFlags)0, &renderInfo, dynamicRendering, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
2535 
2536 			if (dynamicRendering && secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2537 			{
2538 #ifndef CTS_USES_VULKANSC
2539 				beginDynamicRendering(vk, *m_commandBuffer, renderPassInfo, attachmentResources, renderArea, renderPassClearValues);
2540 				pushRenderCommands(vk, *m_commandBuffer);
2541 				endDynamicRendering(vk, *m_commandBuffer);
2542 #endif // CTS_USES_VULKANSC
2543 			}
2544 			else
2545 				pushRenderCommands(vk, *m_commandBuffer);
2546 
2547 			endCommandBuffer(vk, *m_commandBuffer);
2548 		}
2549 	}
2550 
isSecondary(void) const2551 	bool isSecondary (void) const
2552 	{
2553 		return !!m_commandBuffer;
2554 	}
2555 
getCommandBuffer(void) const2556 	VkCommandBuffer getCommandBuffer (void) const
2557 	{
2558 		DE_ASSERT(isSecondary());
2559 		return *m_commandBuffer;
2560 	}
2561 
pushRenderCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer)2562 	void pushRenderCommands (const DeviceInterface&		vk,
2563 							 VkCommandBuffer			commandBuffer)
2564 	{
2565 		if (!m_renderInfo.getColorClears().empty())
2566 		{
2567 			const vector<ColorClear>&	colorClears	(m_renderInfo.getColorClears());
2568 
2569 			for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2570 			{
2571 				const ColorClear&		colorClear	= colorClears[attachmentNdx];
2572 				const VkClearAttachment	attachment	=
2573 				{
2574 					VK_IMAGE_ASPECT_COLOR_BIT,
2575 					attachmentNdx,
2576 					makeClearValue(colorClear.getColor()),
2577 				};
2578 				const VkClearRect		rect		=
2579 				{
2580 					{
2581 						{ (deInt32)colorClear.getOffset().x(),	(deInt32)colorClear.getOffset().y()	},
2582 						{ colorClear.getSize().x(),				colorClear.getSize().y()			}
2583 					},					// rect
2584 					0u,					// baseArrayLayer
2585 					1u,					// layerCount
2586 				};
2587 
2588 				vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2589 			}
2590 		}
2591 
2592 		if (m_renderInfo.getDepthStencilClear())
2593 		{
2594 			const DepthStencilClear&	depthStencilClear	= *m_renderInfo.getDepthStencilClear();
2595 			const deUint32				attachmentNdx		= m_renderInfo.getColorAttachmentCount();
2596 			tcu::TextureFormat			format				= mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2597 			const VkImageLayout			layout				= *m_renderInfo.getDepthStencilAttachmentLayout();
2598 			const VkClearAttachment		attachment			=
2599 			{
2600 				(VkImageAspectFlags)((hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2601 					| (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2602 				attachmentNdx,
2603 				makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2604 			};
2605 			const VkClearRect				rect				=
2606 			{
2607 				{
2608 					{ (deInt32)depthStencilClear.getOffset().x(),	(deInt32)depthStencilClear.getOffset().y()	},
2609 					{ depthStencilClear.getSize().x(),				depthStencilClear.getSize().y()				}
2610 				},							// rect
2611 				0u,							// baseArrayLayer
2612 				1u,							// layerCount
2613 			};
2614 
2615 			if ((tcu::hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
2616 				|| (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL))
2617 			{
2618 				vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2619 			}
2620 		}
2621 
2622 		vector<VkImageMemoryBarrier>	selfDeps;
2623 		VkPipelineStageFlags			srcStages = 0;
2624 		VkPipelineStageFlags			dstStages = 0;
2625 
2626 		for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2627 		{
2628 			for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2629 			{
2630 				if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2631 				{
2632 					const VkImageMemoryBarrier	barrier   =
2633 					{
2634 						VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
2635 						DE_NULL,										// pNext
2636 
2637 						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// srcAccessMask
2638 						VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// dstAccessMask
2639 
2640 						VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
2641 						VK_IMAGE_LAYOUT_GENERAL,						// newLayout
2642 
2643 						VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex
2644 						VK_QUEUE_FAMILY_IGNORED,						// destQueueFamilyIndex
2645 
2646 						m_colorAttachmentImages[colorAttachmentNdx],	// image
2647 						{												// subresourceRange
2648 							VK_IMAGE_ASPECT_COLOR_BIT,						// aspect
2649 							0,												// baseMipLevel
2650 							1,												// mipLevels
2651 							0,												// baseArraySlice
2652 							1												// arraySize
2653 						}
2654 					};
2655 
2656 					srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2657 					dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2658 
2659 					selfDeps.push_back(barrier);
2660 				}
2661 			}
2662 
2663 			if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2664 			{
2665 				const tcu::TextureFormat	format		= mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2666 				const bool					hasDepth	= hasDepthComponent(format.order);
2667 				const bool					hasStencil	= hasStencilComponent(format.order);
2668 				const VkImageMemoryBarrier	barrier		=
2669 				{
2670 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			                // sType;
2671 					DE_NULL,										                // pNext;
2672 
2673 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	                // srcAccessMask
2674 					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			                // dstAccessMask
2675 
2676 					m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx),      // oldLayout
2677 					m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx),      // newLayout;
2678 
2679 					VK_QUEUE_FAMILY_IGNORED,						                // srcQueueFamilyIndex;
2680 					VK_QUEUE_FAMILY_IGNORED,						                // destQueueFamilyIndex;
2681 
2682 					m_depthStencilAttachmentImage,					                // image;
2683 					{												                // subresourceRange;
2684 						(hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2685 							| (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u),	// aspect;
2686 						0,															// baseMipLevel;
2687 						1,															// mipLevels;
2688 						0,															// baseArraySlice;
2689 						1															// arraySize;
2690 					}
2691 				};
2692 
2693 				srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2694 				dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2695 
2696 				selfDeps.push_back(barrier);
2697 			}
2698 		}
2699 
2700 		if (!selfDeps.empty())
2701 		{
2702 			DE_ASSERT(srcStages != 0);
2703 			DE_ASSERT(dstStages != 0);
2704 			vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2705 		}
2706 
2707 		if (m_renderInfo.getRenderQuad())
2708 		{
2709 			const VkDeviceSize	offset			= 0;
2710 			const VkBuffer		vertexBuffer	= *m_vertexBuffer;
2711 
2712 			vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2713 
2714 			if (m_descriptorSet)
2715 			{
2716 				const VkDescriptorSet descriptorSet = *m_descriptorSet;
2717 				vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2718 			}
2719 
2720 			vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2721 			vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2722 		}
2723 	}
2724 
2725 private:
2726 	const SubpassRenderInfo		m_renderInfo;
2727 	Move<VkCommandBuffer>		m_commandBuffer;
2728 	Move<VkPipeline>			m_pipeline;
2729 	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
2730 	Move<VkPipelineLayout>		m_pipelineLayout;
2731 
2732 	Move<VkShaderModule>		m_vertexShaderModule;
2733 	Move<VkShaderModule>		m_fragmentShaderModule;
2734 
2735 	Move<VkDescriptorPool>		m_descriptorPool;
2736 	Move<VkDescriptorSet>		m_descriptorSet;
2737 	Move<VkBuffer>				m_vertexBuffer;
2738 	de::MovePtr<Allocation>		m_vertexBufferMemory;
2739 	vector<VkImage>				m_colorAttachmentImages;
2740 	VkImage						m_depthStencilAttachmentImage;
2741 };
2742 
pushImageInitializationCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const vector<Attachment> & attachmentInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,deUint32 queueIndex,const vector<Maybe<VkClearValue>> & clearValues)2743 void pushImageInitializationCommands (const DeviceInterface&								vk,
2744 									  VkCommandBuffer										commandBuffer,
2745 									  const vector<Attachment>&								attachmentInfo,
2746 									  const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
2747 									  deUint32												queueIndex,
2748 									  const vector<Maybe<VkClearValue> >&					clearValues)
2749 {
2750 	{
2751 		vector<VkImageMemoryBarrier>	initializeLayouts;
2752 
2753 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2754 		{
2755 			if (!clearValues[attachmentNdx])
2756 				continue;
2757 
2758 			const VkImageMemoryBarrier barrier =
2759 			{
2760 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,							// sType;
2761 				DE_NULL,														// pNext;
2762 
2763 				(VkAccessFlags)0,												// srcAccessMask
2764 				getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT,			// dstAccessMask
2765 
2766 				VK_IMAGE_LAYOUT_UNDEFINED,										// oldLayout
2767 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,							// newLayout;
2768 
2769 				queueIndex,														// srcQueueFamilyIndex;
2770 				queueIndex,														// destQueueFamilyIndex;
2771 
2772 				attachmentResources[attachmentNdx]->getImage(),					// image;
2773 				{																// subresourceRange;
2774 					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
2775 					0,																	// baseMipLevel;
2776 					1,																	// mipLevels;
2777 					0,																	// baseArraySlice;
2778 					1																	// arraySize;
2779 				}
2780 			};
2781 
2782 			initializeLayouts.push_back(barrier);
2783 		}
2784 
2785 		if (!initializeLayouts.empty())
2786 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2787 								  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2788 								  0, (const VkMemoryBarrier*)DE_NULL,
2789 								  0, (const VkBufferMemoryBarrier*)DE_NULL,
2790 								  (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2791 	}
2792 
2793 	for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2794 	{
2795 		if (!clearValues[attachmentNdx])
2796 			continue;
2797 
2798 		const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2799 
2800 		if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2801 		{
2802 			const float						clearNan		= tcu::Float32::nan().asFloat();
2803 			const float						clearDepth		= hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2804 			const deUint32					clearStencil	= hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2805 			const VkClearDepthStencilValue	depthStencil	=
2806 			{
2807 				clearDepth,
2808 				clearStencil
2809 			};
2810 			const VkImageSubresourceRange range =
2811 			{
2812 				(VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2813 									 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2814 				0,
2815 				1,
2816 				0,
2817 				1
2818 			};
2819 
2820 			vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2821 		}
2822 		else
2823 		{
2824 			const VkImageSubresourceRange	range		=
2825 			{
2826 				VK_IMAGE_ASPECT_COLOR_BIT,	// aspectMask;
2827 				0,							// baseMipLevel;
2828 				1,							// mipLevels;
2829 				0,							// baseArrayLayer;
2830 				1							// layerCount;
2831 			};
2832 			const VkClearColorValue			clearColor	= clearValues[attachmentNdx]->color;
2833 
2834 			vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2835 		}
2836 	}
2837 
2838 	{
2839 		vector<VkImageMemoryBarrier>	renderPassLayouts;
2840 
2841 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2842 		{
2843 			const VkImageLayout			oldLayout	= clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2844 			const VkImageMemoryBarrier	barrier		=
2845 			{
2846 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// sType;
2847 				DE_NULL,												// pNext;
2848 
2849 				getMemoryFlagsForLayout(oldLayout),																		// srcAccessMask
2850 				getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()),	// dstAccessMask
2851 
2852 				oldLayout,												// oldLayout
2853 				attachmentInfo[attachmentNdx].getInitialLayout(),		// newLayout;
2854 
2855 				queueIndex,												// srcQueueFamilyIndex;
2856 				queueIndex,												// destQueueFamilyIndex;
2857 
2858 				attachmentResources[attachmentNdx]->getImage(),			// image;
2859 				{														// subresourceRange;
2860 					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
2861 					0,																	// baseMipLevel;
2862 					1,																	// mipLevels;
2863 					0,																	// baseArraySlice;
2864 					1																	// arraySize;
2865 				}
2866 			};
2867 
2868 			renderPassLayouts.push_back(barrier);
2869 		}
2870 
2871 		if (!renderPassLayouts.empty())
2872 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2873 								  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0,
2874 								  0, (const VkMemoryBarrier*)DE_NULL,
2875 								  0, (const VkBufferMemoryBarrier*)DE_NULL,
2876 								  (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2877 	}
2878 }
2879 
2880 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)2881 void pushRenderPassCommands (const DeviceInterface&							vk,
2882 							 VkCommandBuffer								commandBuffer,
2883 							 VkRenderPass									renderPass,
2884 							 VkFramebuffer									framebuffer,
2885 							 const vector<de::SharedPtr<SubpassRenderer> >&	subpassRenderers,
2886 							 const VkRect2D&								renderArea,
2887 							 const vector<Maybe<VkClearValue> >&			renderPassClearValues,
2888 							 TestConfig::RenderTypes						render)
2889 {
2890 	const float											clearNan				= tcu::Float32::nan().asFloat();
2891 	vector<VkClearValue>								attachmentClearValues;
2892 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
2893 
2894 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2895 	{
2896 		if (renderPassClearValues[attachmentNdx])
2897 			attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2898 		else
2899 			attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2900 	}
2901 
2902 	{
2903 		for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2904 		{
2905 			const VkSubpassContents								contents			= subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2906 			const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, contents);
2907 			const VkRenderPassBeginInfo							renderPassBeginInfo	= createRenderPassBeginInfo(renderPass,
2908 																												framebuffer,
2909 																												renderArea,
2910 																												(deUint32)attachmentClearValues.size(),
2911 																												attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0]);
2912 
2913 			if (subpassNdx == 0)
2914 				RenderpassSubpass::cmdBeginRenderPass(vk, commandBuffer, &renderPassBeginInfo, &subpassBeginInfo);
2915 			else
2916 				RenderpassSubpass::cmdNextSubpass(vk, commandBuffer, &subpassBeginInfo, &subpassEndInfo);
2917 
2918 			if (render)
2919 			{
2920 				if (contents == VK_SUBPASS_CONTENTS_INLINE)
2921 				{
2922 					subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2923 				}
2924 				else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2925 				{
2926 					const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2927 					vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2928 				}
2929 				else
2930 					DE_FATAL("Invalid contents");
2931 			}
2932 		}
2933 
2934 		RenderpassSubpass::cmdEndRenderPass(vk, commandBuffer, &subpassEndInfo);
2935 	}
2936 }
2937 
2938 #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)2939 void pushDynamicRenderingCommands (const DeviceInterface&								vk,
2940 								   VkCommandBuffer										commandBuffer,
2941 								   const RenderPass&									renderPassInfo,
2942 								   const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
2943 								   const vector<de::SharedPtr<SubpassRenderer> >&		subpassRenderers,
2944 								   const VkRect2D&										renderArea,
2945 								   const vector<Maybe<VkClearValue> >&					renderPassClearValues,
2946 								   deUint32												queueIndex,
2947 								   TestConfig::RenderTypes								renderType,
2948 								   bool													secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2949 {
2950 	DE_ASSERT(subpassRenderers.size() == 1);
2951 
2952 	vector<VkImageMemoryBarrier>		imageBarriersBeforeRendering;
2953 	vector<VkImageMemoryBarrier>		imageBarriersAfterRendering;
2954 
2955 	const Subpass&						subpassInfo					= renderPassInfo.getSubpasses()[0];
2956 	const vector<AttachmentReference>&	colorAttachmentsInfo		= subpassInfo.getColorAttachments();
2957 
2958 	for (deUint32 i = 0 ; i < colorAttachmentsInfo.size() ; ++i)
2959 	{
2960 		const AttachmentReference&		colorAttachmentReference	= colorAttachmentsInfo[i];
2961 		const deUint32					colorAttachmentIndex		= colorAttachmentReference.getAttachment();
2962 		const Attachment&				colorAttachmentInfo			= renderPassInfo.getAttachments()[colorAttachmentIndex];
2963 
2964 		const VkImageLayout				initialLayout				= colorAttachmentInfo.getInitialLayout();
2965 		const VkImageLayout				renderingLayout				= colorAttachmentReference.getImageLayout();
2966 		const VkImageLayout				finalLayout					= colorAttachmentInfo.getFinalLayout();
2967 
2968 		const VkImageMemoryBarrier barrierBeforeRendering
2969 		{
2970 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// sType
2971 			DE_NULL,															// pNext
2972 
2973 			getAllMemoryWriteFlags() | getMemoryFlagsForLayout(initialLayout),	// srcAccessMask
2974 			getMemoryFlagsForLayout(renderingLayout),							// dstAccessMask
2975 
2976 			initialLayout,														// oldLayout
2977 			renderingLayout,													// newLayout
2978 
2979 			queueIndex,															// srcQueueFamilyIndex
2980 			queueIndex,															// destQueueFamilyIndex
2981 
2982 			attachmentResources[colorAttachmentIndex]->getImage(),				// image
2983 			{																	// subresourceRange
2984 				getImageAspectFlags(colorAttachmentInfo.getFormat()),			// aspect;
2985 				0,																// baseMipLevel
2986 				1,																// mipLevels
2987 				0,																// baseArraySlice
2988 				1																// arraySize
2989 			}
2990 		};
2991 		imageBarriersBeforeRendering.push_back(barrierBeforeRendering);
2992 
2993 		const VkImageMemoryBarrier barrierAfterRendering
2994 		{
2995 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// sType
2996 			DE_NULL,															// pNext
2997 
2998 			getMemoryFlagsForLayout(renderingLayout),							// srcAccessMask
2999 			getAllMemoryReadFlags() | getMemoryFlagsForLayout(finalLayout),		// dstAccessMask
3000 
3001 			renderingLayout,													// oldLayout
3002 			finalLayout,														// newLayout
3003 
3004 			queueIndex,															// srcQueueFamilyIndex
3005 			queueIndex,															// destQueueFamilyIndex
3006 
3007 			attachmentResources[colorAttachmentIndex]->getImage(),				// image
3008 			{																	// subresourceRange
3009 				getImageAspectFlags(colorAttachmentInfo.getFormat()),			// aspect;
3010 				0,																// baseMipLevel
3011 				1,																// mipLevels
3012 				0,																// baseArraySlice
3013 				1																// arraySize
3014 			}
3015 		};
3016 		imageBarriersAfterRendering.push_back(barrierAfterRendering);
3017 	}
3018 
3019 	const AttachmentReference&		depthStencilAttachmentReference	= subpassInfo.getDepthStencilAttachment();
3020 	const deUint32					dsAttachmentIndex				= depthStencilAttachmentReference.getAttachment();
3021 
3022 	if (dsAttachmentIndex != VK_ATTACHMENT_UNUSED)
3023 	{
3024 		const Attachment&			dsAttachmentInfo	= renderPassInfo.getAttachments()[dsAttachmentIndex];
3025 
3026 		const VkImageLayout initialLayout		= dsAttachmentInfo.getInitialLayout();
3027 		const VkImageLayout renderingLayout		= depthStencilAttachmentReference.getImageLayout();
3028 		const VkImageLayout finalLayout			= dsAttachmentInfo.getFinalLayout();
3029 
3030 		const VkImageMemoryBarrier barrierBeforeRendering
3031 		{
3032 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// sType
3033 			DE_NULL,															// pNext
3034 
3035 			getAllMemoryWriteFlags() | getMemoryFlagsForLayout(initialLayout),	// srcAccessMask
3036 			getMemoryFlagsForLayout(renderingLayout),							// dstAccessMask
3037 
3038 			initialLayout,														// oldLayout
3039 			renderingLayout,													// newLayout
3040 
3041 			queueIndex,															// srcQueueFamilyIndex
3042 			queueIndex,															// destQueueFamilyIndex
3043 
3044 			attachmentResources[dsAttachmentIndex]->getImage(),					// image
3045 			{																	// subresourceRange
3046 				getImageAspectFlags(dsAttachmentInfo.getFormat()),				// aspect;
3047 				0,																// baseMipLevel
3048 				1,																// mipLevels
3049 				0,																// baseArraySlice
3050 				1																// arraySize
3051 			}
3052 		};
3053 		imageBarriersBeforeRendering.push_back(barrierBeforeRendering);
3054 
3055 		const VkImageMemoryBarrier barrierAfterRendering
3056 		{
3057 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// sType
3058 			DE_NULL,															// pNext
3059 
3060 			getMemoryFlagsForLayout(renderingLayout),							// srcAccessMask
3061 			getAllMemoryReadFlags() | getMemoryFlagsForLayout(finalLayout),		// dstAccessMask
3062 
3063 			renderingLayout,													// oldLayout
3064 			finalLayout,														// newLayout
3065 
3066 			queueIndex,															// srcQueueFamilyIndex
3067 			queueIndex,															// destQueueFamilyIndex
3068 
3069 			attachmentResources[dsAttachmentIndex]->getImage(),					// image
3070 			{																	// subresourceRange
3071 				getImageAspectFlags(dsAttachmentInfo.getFormat()),				// aspect;
3072 				0,																// baseMipLevel
3073 				1,																// mipLevels
3074 				0,																// baseArraySlice
3075 				1																// arraySize
3076 			}
3077 		};
3078 		imageBarriersAfterRendering.push_back(barrierAfterRendering);
3079 	}
3080 
3081 	if (!imageBarriersBeforeRendering.empty())
3082 		vk.cmdPipelineBarrier(commandBuffer,
3083 							  getAllPipelineStageFlags(),
3084 							  getAllPipelineStageFlags(),
3085 							  (VkDependencyFlags)0,
3086 							  0, (const VkMemoryBarrier*)DE_NULL,
3087 							  0, (const VkBufferMemoryBarrier*)DE_NULL,
3088 							  (deUint32)imageBarriersBeforeRendering.size(),
3089 							  &imageBarriersBeforeRendering[0]);
3090 
3091 	bool executeRenderCommands = (renderType != TestConfig::RENDERTYPES_NONE);
3092 
3093 	if (secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3094 	{
3095 		// when secondary command buffer completely contains dynamic renderpass
3096 		// then we need to execute it even when render type is none
3097 		executeRenderCommands = true;
3098 	}
3099 	else
3100 	{
3101 		VkRenderingFlagsKHR renderingFlags = 0u;
3102 		if (subpassRenderers[0]->isSecondary())
3103 			renderingFlags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR;
3104 
3105 		beginDynamicRendering(vk, commandBuffer, renderPassInfo, attachmentResources, renderArea, renderPassClearValues, renderingFlags);
3106 	}
3107 
3108 	if (executeRenderCommands)
3109 	{
3110 		if (subpassRenderers[0]->isSecondary())
3111 		{
3112 			const VkCommandBuffer cmd = subpassRenderers[0]->getCommandBuffer();
3113 			vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
3114 		}
3115 		else
3116 			subpassRenderers[0]->pushRenderCommands(vk, commandBuffer);
3117 	}
3118 
3119 	if (!secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3120 		endDynamicRendering(vk, commandBuffer);
3121 
3122 	if (!imageBarriersAfterRendering.empty())
3123 		vk.cmdPipelineBarrier(commandBuffer,
3124 							  getAllPipelineStageFlags(),
3125 							  getAllPipelineStageFlags(),
3126 							  (VkDependencyFlags)0,
3127 							  0, (const VkMemoryBarrier*)DE_NULL,
3128 							  0, (const VkBufferMemoryBarrier*)DE_NULL,
3129 							  (deUint32)imageBarriersAfterRendering.size(),
3130 							  &imageBarriersAfterRendering[0]);
3131 }
3132 #endif // CTS_USES_VULKANSC
3133 
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)3134 void pushRenderPassCommands (const DeviceInterface&								vk,
3135 							 VkCommandBuffer									commandBuffer,
3136 							 VkRenderPass										renderPass,
3137 							 const RenderPass&									renderPassInfo,
3138 							 const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
3139 							 VkFramebuffer										framebuffer,
3140 							 const vector<de::SharedPtr<SubpassRenderer> >&		subpassRenderers,
3141 							 const VkRect2D&									renderArea,
3142 							 const vector<Maybe<VkClearValue> >&				renderPassClearValues,
3143 							 deUint32											queueIndex,
3144 							 TestConfig::RenderTypes							render,
3145 							 RenderingType										renderingType,
3146 							 bool												secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3147 {
3148 	// unreference arguments not used by Vulkan SC, no need to put them under ifdef
3149 	DE_UNREF(renderPassInfo);
3150 	DE_UNREF(attachmentResources);
3151 	DE_UNREF(queueIndex);
3152 	DE_UNREF(secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3153 
3154 	switch (renderingType)
3155 	{
3156 		case RENDERING_TYPE_RENDERPASS_LEGACY:
3157 			return pushRenderPassCommands<RenderpassSubpass1>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderArea, renderPassClearValues, render);
3158 		case RENDERING_TYPE_RENDERPASS2:
3159 			return pushRenderPassCommands<RenderpassSubpass2>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers, renderArea, renderPassClearValues, render);
3160 
3161 #ifndef CTS_USES_VULKANSC
3162 		case RENDERING_TYPE_DYNAMIC_RENDERING:
3163 			return pushDynamicRenderingCommands(vk, commandBuffer, renderPassInfo, attachmentResources, subpassRenderers, renderArea, renderPassClearValues, queueIndex, render, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
3164 #endif // CTS_USES_VULKANSC
3165 
3166 		default:
3167 			TCU_THROW(InternalError, "Impossible");
3168 	}
3169 }
3170 
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)3171 void pushReadImagesToBuffers (const DeviceInterface&								vk,
3172 							  VkCommandBuffer										commandBuffer,
3173 							  deUint32												queueIndex,
3174 
3175 							  const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
3176 							  const vector<Attachment>&								attachmentInfo,
3177 							  const vector<bool>&									isLazy,
3178 
3179 							  const UVec2&											targetSize)
3180 {
3181 	{
3182 		vector<VkImageMemoryBarrier>	imageBarriers;
3183 
3184 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3185 		{
3186 			if (isLazy[attachmentNdx])
3187 				continue;
3188 
3189 			const VkImageLayout			oldLayout	= attachmentInfo[attachmentNdx].getFinalLayout();
3190 			const VkImageMemoryBarrier	barrier		=
3191 			{
3192 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,							// sType
3193 				DE_NULL,														// pNext
3194 
3195 				getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout),	// srcAccessMask
3196 				getAllMemoryReadFlags(),										// dstAccessMask
3197 
3198 				oldLayout,														// oldLayout
3199 				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,							// newLayout
3200 
3201 				queueIndex,														// srcQueueFamilyIndex
3202 				queueIndex,														// destQueueFamilyIndex
3203 
3204 				attachmentResources[attachmentNdx]->getImage(),					// image
3205 				{																// subresourceRange
3206 					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
3207 					0,																	// baseMipLevel
3208 					1,																	// mipLevels
3209 					0,																	// baseArraySlice
3210 					1																	// arraySize
3211 				}
3212 			};
3213 
3214 			imageBarriers.push_back(barrier);
3215 		}
3216 
3217 		if (!imageBarriers.empty())
3218 			vk.cmdPipelineBarrier(commandBuffer,
3219 								  getAllPipelineStageFlags(),
3220 								  getAllPipelineStageFlags(),
3221 								  (VkDependencyFlags)0,
3222 								  0, (const VkMemoryBarrier*)DE_NULL,
3223 								  0, (const VkBufferMemoryBarrier*)DE_NULL,
3224 								  (deUint32)imageBarriers.size(), &imageBarriers[0]);
3225 	}
3226 
3227 	for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3228 	{
3229 		if (isLazy[attachmentNdx])
3230 			continue;
3231 
3232 		const tcu::TextureFormat::ChannelOrder	order	= mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3233 		const VkBufferImageCopy					rect	=
3234 		{
3235 			0, // bufferOffset
3236 			0, // bufferRowLength
3237 			0, // bufferImageHeight
3238 			{							// imageSubresource
3239 				(vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order),	// aspect
3240 				0,						// mipLevel
3241 				0,						// arraySlice
3242 				1						// arraySize
3243 			},
3244 			{ 0, 0, 0 },				// imageOffset
3245 			{ targetSize.x(), targetSize.y(), 1u }		// imageExtent
3246 		};
3247 
3248 		vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
3249 
3250 		if (tcu::TextureFormat::DS == order)
3251 		{
3252 			const VkBufferImageCopy stencilRect =
3253 			{
3254 				0,										// bufferOffset
3255 				0,										// bufferRowLength
3256 				0,										// bufferImageHeight
3257 				{									// imageSubresource
3258 					VK_IMAGE_ASPECT_STENCIL_BIT,	// aspect
3259 					0,								// mipLevel
3260 					0,								// arraySlice
3261 					1								// arraySize
3262 				},
3263 				{ 0, 0, 0 },							// imageOffset
3264 				{ targetSize.x(), targetSize.y(), 1u }	// imageExtent
3265 			};
3266 
3267 			vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
3268 		}
3269 	}
3270 
3271 	{
3272 		vector<VkBufferMemoryBarrier>	bufferBarriers;
3273 
3274 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
3275 		{
3276 			if (isLazy[attachmentNdx])
3277 				continue;
3278 
3279 			const tcu::TextureFormat::ChannelOrder	order			= mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
3280 			const VkBufferMemoryBarrier				bufferBarrier	=
3281 			{
3282 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3283 				DE_NULL,
3284 
3285 				getAllMemoryWriteFlags(),
3286 				getAllMemoryReadFlags(),
3287 
3288 				queueIndex,
3289 				queueIndex,
3290 
3291 				attachmentResources[attachmentNdx]->getBuffer(),
3292 				0,
3293 				attachmentResources[attachmentNdx]->getBufferSize()
3294 			};
3295 
3296 			bufferBarriers.push_back(bufferBarrier);
3297 
3298 			if (tcu::TextureFormat::DS == order)
3299 			{
3300 				const VkBufferMemoryBarrier secondaryBufferBarrier =
3301 				{
3302 					VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3303 					DE_NULL,
3304 
3305 					getAllMemoryWriteFlags(),
3306 					getAllMemoryReadFlags(),
3307 
3308 					queueIndex,
3309 					queueIndex,
3310 
3311 					attachmentResources[attachmentNdx]->getSecondaryBuffer(),
3312 					0,
3313 					attachmentResources[attachmentNdx]->getSecondaryBufferSize()
3314 				};
3315 
3316 				bufferBarriers.push_back(secondaryBufferBarrier);
3317 			}
3318 		}
3319 
3320 		if (!bufferBarriers.empty())
3321 			vk.cmdPipelineBarrier(commandBuffer,
3322 								  getAllPipelineStageFlags(),
3323 								  getAllPipelineStageFlags(),
3324 								  (VkDependencyFlags)0,
3325 								  0, (const VkMemoryBarrier*)DE_NULL,
3326 								  (deUint32)bufferBarriers.size(), &bufferBarriers[0],
3327 								  0, (const VkImageMemoryBarrier*)DE_NULL);
3328 	}
3329 }
3330 
3331 class PixelValue
3332 {
3333 public:
3334 				PixelValue		(const Maybe<bool>&	x = tcu::Nothing,
3335 								 const Maybe<bool>&	y = tcu::Nothing,
3336 								 const Maybe<bool>&	z = tcu::Nothing,
3337 								 const Maybe<bool>&	w = tcu::Nothing);
3338 
3339 	void		setUndefined	(size_t ndx);
3340 	void		setValue		(size_t ndx, bool value);
3341 	Maybe<bool>	getValue		(size_t ndx) const;
3342 
3343 private:
3344 	deUint16	m_status;
3345 };
3346 
PixelValue(const Maybe<bool> & x,const Maybe<bool> & y,const Maybe<bool> & z,const Maybe<bool> & w)3347 PixelValue::PixelValue (const Maybe<bool>&	x,
3348 						const Maybe<bool>&	y,
3349 						const Maybe<bool>&	z,
3350 						const Maybe<bool>&	w)
3351 	: m_status (0)
3352 {
3353 	const Maybe<bool> values[] =
3354 	{
3355 		x, y, z, w
3356 	};
3357 
3358 	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
3359 	{
3360 		if (values[ndx])
3361 			setValue(ndx, *values[ndx]);
3362 		else
3363 			setUndefined(ndx);
3364 	}
3365 
3366 	DE_ASSERT(m_status <= 0xFFu);
3367 }
3368 
setUndefined(size_t ndx)3369 void PixelValue::setUndefined (size_t ndx)
3370 {
3371 	DE_ASSERT(ndx < 4);
3372 	DE_ASSERT(m_status <= 0xFFu);
3373 
3374 	m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
3375 	DE_ASSERT(m_status <= 0xFFu);
3376 }
3377 
setValue(size_t ndx,bool value)3378 void PixelValue::setValue (size_t ndx, bool value)
3379 {
3380 	DE_ASSERT(ndx < 4);
3381 	DE_ASSERT(m_status <= 0xFFu);
3382 
3383 	m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2)));
3384 
3385 	if (value)
3386 		m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1)));
3387 	else
3388 		m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
3389 
3390 	DE_ASSERT(m_status <= 0xFFu);
3391 }
3392 
getValue(size_t ndx) const3393 Maybe<bool> PixelValue::getValue (size_t ndx) const
3394 {
3395 	DE_ASSERT(ndx < 4);
3396 	DE_ASSERT(m_status <= 0xFFu);
3397 
3398 	if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
3399 	{
3400 		return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
3401 	}
3402 	else
3403 		return tcu::Nothing;
3404 }
3405 
clearReferenceValues(vector<PixelValue> & values,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size,const BVec4 & mask,const PixelValue & value)3406 void clearReferenceValues (vector<PixelValue>&	values,
3407 						   const UVec2&			targetSize,
3408 						   const UVec2&			offset,
3409 						   const UVec2&			size,
3410 						   const BVec4&			mask,
3411 						   const PixelValue&	value)
3412 {
3413 	DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
3414 	DE_ASSERT(offset.x() + size.x() <= targetSize.x());
3415 	DE_ASSERT(offset.y() + size.y() <= targetSize.y());
3416 
3417 	for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
3418 	for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
3419 	{
3420 		for (int compNdx = 0; compNdx < 4; compNdx++)
3421 		{
3422 			if (mask[compNdx])
3423 			{
3424 				if (value.getValue(compNdx))
3425 					values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
3426 				else
3427 					values[x + y * targetSize.x()].setUndefined(compNdx);
3428 			}
3429 		}
3430 	}
3431 }
3432 
markUndefined(vector<PixelValue> & values,const BVec4 & mask,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size)3433 void markUndefined (vector<PixelValue>&	values,
3434 					const BVec4&		mask,
3435 					const UVec2&		targetSize,
3436 					const UVec2&		offset,
3437 					const UVec2&		size)
3438 {
3439 	DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
3440 
3441 	for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
3442 	for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
3443 	{
3444 		for (int compNdx = 0; compNdx < 4; compNdx++)
3445 		{
3446 			if (mask[compNdx])
3447 				values[x + y * targetSize.x()].setUndefined(compNdx);
3448 		}
3449 	}
3450 }
3451 
clearValueToPixelValue(const VkClearValue & value,const tcu::TextureFormat & format,const DepthValuesArray & depthValues)3452 PixelValue clearValueToPixelValue (const VkClearValue&			value,
3453 								   const tcu::TextureFormat&	format,
3454 								   const DepthValuesArray&		depthValues)
3455 {
3456 	const bool	isDepthAttachment			= hasDepthComponent(format.order);
3457 	const bool	isStencilAttachment			= hasStencilComponent(format.order);
3458 	const bool	isDepthOrStencilAttachment	= isDepthAttachment || isStencilAttachment;
3459 	PixelValue	pixelValue;
3460 
3461 	if (isDepthOrStencilAttachment)
3462 	{
3463 		if (isDepthAttachment)
3464 		{
3465 			if (value.depthStencil.depth == float(depthValues[1]) / 255.0f)
3466 				pixelValue.setValue(0, true);
3467 			else if (value.depthStencil.depth == float(depthValues[0]) / 255.0f)
3468 				pixelValue.setValue(0, false);
3469 			else
3470 				DE_FATAL("Unknown depth value");
3471 		}
3472 
3473 		if (isStencilAttachment)
3474 		{
3475 			if (value.depthStencil.stencil == 0xFFu)
3476 				pixelValue.setValue(1, true);
3477 			else if (value.depthStencil.stencil == 0x0u)
3478 				pixelValue.setValue(1, false);
3479 			else
3480 				DE_FATAL("Unknown stencil value");
3481 		}
3482 	}
3483 	else
3484 	{
3485 		const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
3486 		const tcu::BVec4				channelMask		= tcu::getTextureFormatChannelMask(format);
3487 
3488 		switch (channelClass)
3489 		{
3490 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3491 				for (int i = 0; i < 4; i++)
3492 				{
3493 					if (channelMask[i])
3494 					{
3495 						if (value.color.int32[i] == 1)
3496 							pixelValue.setValue(i, true);
3497 						else if (value.color.int32[i] == 0)
3498 							pixelValue.setValue(i, false);
3499 						else
3500 							DE_FATAL("Unknown clear color value");
3501 					}
3502 				}
3503 				break;
3504 
3505 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3506 				for (int i = 0; i < 4; i++)
3507 				{
3508 					if (channelMask[i])
3509 					{
3510 						if (value.color.uint32[i] == 1u)
3511 							pixelValue.setValue(i, true);
3512 						else if (value.color.uint32[i] == 0u)
3513 							pixelValue.setValue(i, false);
3514 						else
3515 							DE_FATAL("Unknown clear color value");
3516 					}
3517 				}
3518 				break;
3519 
3520 			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3521 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3522 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3523 				for (int i = 0; i < 4; i++)
3524 				{
3525 					if (channelMask[i])
3526 					{
3527 						if (value.color.float32[i] == 1.0f)
3528 							pixelValue.setValue(i, true);
3529 						else if (value.color.float32[i] == 0.0f)
3530 							pixelValue.setValue(i, false);
3531 						else
3532 							DE_FATAL("Unknown clear color value");
3533 					}
3534 				}
3535 				break;
3536 
3537 			default:
3538 				DE_FATAL("Unknown channel class");
3539 		}
3540 	}
3541 
3542 	return pixelValue;
3543 }
3544 
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)3545 void renderReferenceValues (vector<vector<PixelValue> >&		referenceAttachments,
3546 							const RenderPass&					renderPassInfo,
3547 							const UVec2&						targetSize,
3548 							const vector<Maybe<VkClearValue> >&	imageClearValues,
3549 							const vector<Maybe<VkClearValue> >&	renderPassClearValues,
3550 							const vector<SubpassRenderInfo>&	subpassRenderInfo,
3551 							const UVec2&						renderPos,
3552 							const UVec2&						renderSize,
3553 							const deUint32						drawStartNdx,
3554 							const DepthValuesArray&				depthValues)
3555 {
3556 	const vector<Subpass>&	subpasses		= renderPassInfo.getSubpasses();
3557 	vector<bool>			attachmentUsed	(renderPassInfo.getAttachments().size(), false);
3558 
3559 	referenceAttachments.resize(renderPassInfo.getAttachments().size());
3560 
3561 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3562 	{
3563 		const Attachment			attachment	= renderPassInfo.getAttachments()[attachmentNdx];
3564 		const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
3565 		vector<PixelValue>&			reference	= referenceAttachments[attachmentNdx];
3566 
3567 		reference.resize(targetSize.x() * targetSize.y());
3568 
3569 		if (imageClearValues[attachmentNdx])
3570 			clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format, depthValues));
3571 	}
3572 
3573 	for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3574 	{
3575 		const Subpass&						subpass				= subpasses[subpassNdx];
3576 		const SubpassRenderInfo&			renderInfo			= subpassRenderInfo[subpassNdx];
3577 		const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();
3578 
3579 		// Apply load op if attachment was used for the first time
3580 		for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
3581 		{
3582 			const deUint32 attachmentIndex = getAttachmentNdx(colorAttachments, attachmentNdx);
3583 
3584 			if (!attachmentUsed[attachmentIndex] && colorAttachments[attachmentNdx].getAttachment() != VK_ATTACHMENT_UNUSED)
3585 			{
3586 				const Attachment&			attachment	= renderPassInfo.getAttachments()[attachmentIndex];
3587 				vector<PixelValue>&			reference	= referenceAttachments[attachmentIndex];
3588 				const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
3589 
3590 				DE_ASSERT(!tcu::hasDepthComponent(format.order));
3591 				DE_ASSERT(!tcu::hasStencilComponent(format.order));
3592 
3593 				if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3594 					clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3595 				else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3596 					markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3597 
3598 				attachmentUsed[attachmentIndex] = true;
3599 			}
3600 		}
3601 
3602 		// Apply load op to depth/stencil attachment if it was used for the first time
3603 		if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3604 		{
3605 			const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3606 
3607 			// Apply load op if attachment was used for the first time
3608 			if (!attachmentUsed[attachmentIndex])
3609 			{
3610 				const Attachment&			attachment	= renderPassInfo.getAttachments()[attachmentIndex];
3611 				vector<PixelValue>&			reference	= referenceAttachments[attachmentIndex];
3612 				const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
3613 
3614 				if (tcu::hasDepthComponent(format.order))
3615 				{
3616 					if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3617 						clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3618 					else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3619 						markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3620 				}
3621 
3622 				if (tcu::hasStencilComponent(format.order))
3623 				{
3624 					if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3625 						clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
3626 					else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3627 						markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3628 				}
3629 
3630 				attachmentUsed[attachmentIndex] = true;
3631 			}
3632 		}
3633 
3634 		for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
3635 		{
3636 			const ColorClear&			colorClear		= renderInfo.getColorClears()[colorClearNdx];
3637 			const UVec2					offset			= colorClear.getOffset();
3638 			const UVec2					size			= colorClear.getSize();
3639 			const deUint32				attachmentIndex	= subpass.getColorAttachments()[colorClearNdx].getAttachment();
3640 			const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3641 			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3642 			vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
3643 			VkClearValue				value;
3644 
3645 			value.color = colorClear.getColor();
3646 
3647 			clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format, depthValues));
3648 		}
3649 
3650 		if (renderInfo.getDepthStencilClear())
3651 		{
3652 			const DepthStencilClear&	dsClear			= *renderInfo.getDepthStencilClear();
3653 			const UVec2					offset			= dsClear.getOffset();
3654 			const UVec2					size			= dsClear.getSize();
3655 			const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
3656 			const VkImageLayout			layout			= subpass.getDepthStencilAttachment().getImageLayout();
3657 			const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3658 			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3659 			const bool					hasStencil		= tcu::hasStencilComponent(format.order)
3660 														&& layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
3661 			const bool					hasDepth		= tcu::hasDepthComponent(format.order)
3662 														&& layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
3663 			vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
3664 			VkClearValue				value;
3665 
3666 			value.depthStencil.depth = dsClear.getDepth();
3667 			value.depthStencil.stencil = dsClear.getStencil();
3668 
3669 			clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format, depthValues));
3670 		}
3671 
3672 		if (renderInfo.getRenderQuad())
3673 		{
3674 			const RenderQuad&	renderQuad	= *renderInfo.getRenderQuad();
3675 			const Vec2			posA		= renderQuad.getCornerA();
3676 			const Vec2			posB		= renderQuad.getCornerB();
3677 			const Vec2			origin		= Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3678 			const Vec2			p			= Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3679 			const IVec2			posAI		(deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
3680 											 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
3681 			const IVec2			posBI		(deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
3682 											 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
3683 
3684 			DE_ASSERT(posAI.x() < posBI.x());
3685 			DE_ASSERT(posAI.y() < posBI.y());
3686 
3687 			if (subpass.getInputAttachments().empty())
3688 			{
3689 				for (size_t attachmentRefNdx = drawStartNdx; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3690 				{
3691 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3692 
3693 					if (attachmentIndex == VK_ATTACHMENT_UNUSED)
3694 						continue;
3695 
3696 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3697 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3698 					const tcu::BVec4			channelMask		= tcu::getTextureFormatChannelMask(format);
3699 					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
3700 
3701 					for (int y = posAI.y(); y < (int)posBI.y(); y++)
3702 					for (int x = posAI.x(); x < (int)posBI.x(); x++)
3703 					{
3704 						for (int compNdx = 0; compNdx < 4; compNdx++)
3705 						{
3706 							const size_t	index	= subpassNdx + attachmentIndex + compNdx;
3707 							const BoolOp	op		= boolOpFromIndex(index);
3708 							const bool		boolX	= x % 2 == (int)(index % 2);
3709 							const bool		boolY	= y % 2 == (int)((index / 2) % 2);
3710 
3711 							if (channelMask[compNdx])
3712 								reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
3713 						}
3714 					}
3715 				}
3716 
3717 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3718 				{
3719 					const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
3720 					const VkImageLayout			layout			= subpass.getDepthStencilAttachment().getImageLayout();
3721 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3722 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3723 					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
3724 
3725 					for (int y = posAI.y(); y < (int)posBI.y(); y++)
3726 					for (int x = posAI.x(); x < (int)posBI.x(); x++)
3727 					{
3728 						if (tcu::hasDepthComponent(format.order)
3729 							&& layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3730 							&& layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3731 						{
3732 							const size_t	index	= subpassNdx + 1;
3733 							const BoolOp	op		= boolOpFromIndex(index);
3734 							const bool		boolX	= x % 2 == (int)(index % 2);
3735 							const bool		boolY	= y % 2 == (int)((index / 2) % 2);
3736 
3737 							reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
3738 						}
3739 
3740 						if (tcu::hasStencilComponent(format.order)
3741 							&& layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3742 							&& layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3743 						{
3744 							const size_t	index	= subpassNdx;
3745 							reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3746 						}
3747 					}
3748 				}
3749 			}
3750 			else
3751 			{
3752 				size_t					outputComponentCount	= 0;
3753 				vector<Maybe<bool> >	inputs;
3754 
3755 				DE_ASSERT(posAI.x() < posBI.x());
3756 				DE_ASSERT(posAI.y() < posBI.y());
3757 
3758 				for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3759 				{
3760 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3761 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3762 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3763 					const int					componentCount	= tcu::getNumUsedChannels(format.order);
3764 
3765 					outputComponentCount += (size_t)componentCount;
3766 				}
3767 
3768 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3769 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3770 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3771 				{
3772 					const Attachment&			attachment	(renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]);
3773 					const tcu::TextureFormat	format		(mapVkFormat(attachment.getFormat()));
3774 
3775 					if (tcu::hasDepthComponent(format.order))
3776 						outputComponentCount++;
3777 				}
3778 
3779 				if (outputComponentCount > 0)
3780 				{
3781 					for (int y = posAI.y(); y < (int)posBI.y(); y++)
3782 					for (int x = posAI.x(); x < (int)posBI.x(); x++)
3783 					{
3784 						for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3785 						{
3786 							const deUint32				attachmentIndex	= subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3787 							const VkImageLayout			layout			= subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout();
3788 							const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3789 							const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3790 							const int					componentCount	= tcu::getNumUsedChannels(format.order);
3791 
3792 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
3793 							{
3794 								if ((compNdx != 0 || layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3795 									&& (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL))
3796 								{
3797 									inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3798 								}
3799 							}
3800 						}
3801 
3802 						const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3803 														? ((inputs.size() / outputComponentCount)
3804 															+ ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3805 														: 1;
3806 
3807 						size_t outputValueNdx = 0;
3808 
3809 						for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3810 						{
3811 							const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3812 							const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3813 							const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3814 							vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
3815 							const int					componentCount	= tcu::getNumUsedChannels(format.order);
3816 
3817 							for (int compNdx = 0; compNdx < componentCount; compNdx++)
3818 							{
3819 								const size_t	index	= subpassNdx + attachmentIndex + outputValueNdx;
3820 								const BoolOp	op		= boolOpFromIndex(index);
3821 								const bool		boolX	= x % 2 == (int)(index % 2);
3822 								const bool		boolY	= y % 2 == (int)((index / 2) % 2);
3823 								Maybe<bool>		output	= tcu::just(performBoolOp(op, boolX, boolY));
3824 
3825 								for (size_t i = 0; i < inputsPerOutput; i++)
3826 								{
3827 									if (!output)
3828 										break;
3829 									else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3830 										output = tcu::Nothing;
3831 									else
3832 										output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3833 								}
3834 
3835 								if (output)
3836 									reference[x + y * targetSize.x()].setValue(compNdx, *output);
3837 								else
3838 									reference[x + y * targetSize.x()].setUndefined(compNdx);
3839 							}
3840 
3841 							outputValueNdx += componentCount;
3842 						}
3843 
3844 						if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3845 							&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3846 							&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
3847 						{
3848 							const deUint32		attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
3849 							vector<PixelValue>&	reference		= referenceAttachments[attachmentIndex];
3850 							const size_t		index			= subpassNdx + attachmentIndex;
3851 							const BoolOp		op				= boolOpFromIndex(index);
3852 							const bool			boolX			= x % 2 == (int)(index % 2);
3853 							const bool			boolY			= y % 2 == (int)((index / 2) % 2);
3854 							Maybe<bool>			output			= tcu::just(performBoolOp(op, boolX, boolY));
3855 
3856 							for (size_t i = 0; i < inputsPerOutput; i++)
3857 							{
3858 								if (!output)
3859 									break;
3860 								else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3861 									output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3862 								else
3863 									output = tcu::Nothing;
3864 							}
3865 
3866 							if (output)
3867 								reference[x + y * targetSize.x()].setValue(0, *output);
3868 							else
3869 								reference[x + y * targetSize.x()].setUndefined(0);
3870 						}
3871 
3872 						inputs.clear();
3873 					}
3874 				}
3875 
3876 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3877 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3878 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
3879 				{
3880 					const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
3881 					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
3882 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
3883 					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
3884 
3885 					if (tcu::hasStencilComponent(format.order))
3886 					{
3887 						for (int y = posAI.y(); y < (int)posBI.y(); y++)
3888 						for (int x = posAI.x(); x < (int)posBI.x(); x++)
3889 						{
3890 							const size_t	index	= subpassNdx;
3891 							reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3892 						}
3893 					}
3894 				}
3895 			}
3896 		}
3897 	}
3898 
3899 	// Mark all attachments that were used but not stored as undefined
3900 	for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3901 	{
3902 		const Attachment			attachment					= renderPassInfo.getAttachments()[attachmentIndex];
3903 		const tcu::TextureFormat	format						= mapVkFormat(attachment.getFormat());
3904 		vector<PixelValue>&			reference					= referenceAttachments[attachmentIndex];
3905 		const bool					isStencilAttachment			= hasStencilComponent(format.order);
3906 		const bool					isDepthOrStencilAttachment	= hasDepthComponent(format.order) || isStencilAttachment;
3907 
3908 		if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3909 		{
3910 			if (isDepthOrStencilAttachment)
3911 				markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3912 			else
3913 				markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3914 		}
3915 
3916 		if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3917 			markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3918 	}
3919 }
3920 
renderReferenceImagesFromValues(vector<tcu::TextureLevel> & referenceImages,const vector<vector<PixelValue>> & referenceValues,const UVec2 & targetSize,const RenderPass & renderPassInfo,const DepthValuesArray & depthValues)3921 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>&			referenceImages,
3922 									  const vector<vector<PixelValue> >&	referenceValues,
3923 									  const UVec2&							targetSize,
3924 									  const RenderPass&						renderPassInfo,
3925 									  const DepthValuesArray&				depthValues)
3926 {
3927 	referenceImages.resize(referenceValues.size());
3928 
3929 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3930 	{
3931 		const Attachment			attachment			= renderPassInfo.getAttachments()[attachmentNdx];
3932 		const tcu::TextureFormat	format				= mapVkFormat(attachment.getFormat());
3933 		const vector<PixelValue>&	reference			= referenceValues[attachmentNdx];
3934 		const bool					hasDepth			= tcu::hasDepthComponent(format.order);
3935 		const bool					hasStencil			= tcu::hasStencilComponent(format.order);
3936 		const bool					hasDepthOrStencil	= hasDepth || hasStencil;
3937 		tcu::TextureLevel&			referenceImage		= referenceImages[attachmentNdx];
3938 
3939 		referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3940 
3941 		if (hasDepthOrStencil)
3942 		{
3943 			if (hasDepth)
3944 			{
3945 				const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3946 
3947 				for (deUint32 y = 0; y < targetSize.y(); y++)
3948 				for (deUint32 x = 0; x < targetSize.x(); x++)
3949 				{
3950 					if (reference[x + y * targetSize.x()].getValue(0))
3951 					{
3952 						if (*reference[x + y * targetSize.x()].getValue(0))
3953 							depthAccess.setPixDepth(float(depthValues[1]) / 255.0f, x, y);
3954 						else
3955 							depthAccess.setPixDepth(float(depthValues[0]) / 255.0f, x, y);
3956 					}
3957 					else // Fill with 3x3 grid
3958 						depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3959 				}
3960 			}
3961 
3962 			if (hasStencil)
3963 			{
3964 				const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3965 
3966 				for (deUint32 y = 0; y < targetSize.y(); y++)
3967 				for (deUint32 x = 0; x < targetSize.x(); x++)
3968 				{
3969 					if (reference[x + y * targetSize.x()].getValue(1))
3970 					{
3971 						if (*reference[x + y * targetSize.x()].getValue(1))
3972 							stencilAccess.setPixStencil(0xFFu, x, y);
3973 						else
3974 							stencilAccess.setPixStencil(0x0u, x, y);
3975 					}
3976 					else // Fill with 3x3 grid
3977 						stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3978 				}
3979 			}
3980 		}
3981 		else
3982 		{
3983 			for (deUint32 y = 0; y < targetSize.y(); y++)
3984 			for (deUint32 x = 0; x < targetSize.x(); x++)
3985 			{
3986 				tcu::Vec4 color;
3987 
3988 				for (int compNdx = 0; compNdx < 4; compNdx++)
3989 				{
3990 					if (reference[x + y * targetSize.x()].getValue(compNdx))
3991 					{
3992 						if (*reference[x + y * targetSize.x()].getValue(compNdx))
3993 							color[compNdx] = 1.0f;
3994 						else
3995 							color[compNdx] = 0.0f;
3996 					}
3997 					else // Fill with 3x3 grid
3998 						color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3999 				}
4000 
4001 				referenceImage.getAccess().setPixel(color, x, y);
4002 			}
4003 		}
4004 	}
4005 }
4006 
verifyColorAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage,const deBool useFormatCompCount)4007 bool verifyColorAttachment (const vector<PixelValue>&		reference,
4008 							const ConstPixelBufferAccess&	result,
4009 							const PixelBufferAccess&		errorImage,
4010 							const deBool					useFormatCompCount)
4011 {
4012 	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
4013 	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
4014 	bool		ok		= true;
4015 
4016 	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4017 	DE_ASSERT(result.getWidth() == errorImage.getWidth());
4018 	DE_ASSERT(result.getHeight() == errorImage.getHeight());
4019 
4020 	for (int y = 0; y < result.getHeight(); y++)
4021 	for (int x = 0; x < result.getWidth(); x++)
4022 	{
4023 		const Vec4			resultColor		= result.getPixel(x, y);
4024 		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
4025 		bool				pixelOk			= true;
4026 		const deUint32		componentCount	= useFormatCompCount ? (deUint32)tcu::getNumUsedChannels(result.getFormat().order) : 4;
4027 
4028 		for (deUint32 compNdx = 0; compNdx < componentCount; compNdx++)
4029 		{
4030 			const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
4031 
4032 			if (maybeValue)
4033 			{
4034 				const bool value = *maybeValue;
4035 
4036 				if ((value && (resultColor[compNdx] != 1.0f))
4037 					|| (!value && resultColor[compNdx] != 0.0f))
4038 					pixelOk = false;
4039 			}
4040 		}
4041 
4042 		if (!pixelOk)
4043 		{
4044 			errorImage.setPixel(red, x, y);
4045 			ok = false;
4046 		}
4047 		else
4048 			errorImage.setPixel(green, x, y);
4049 	}
4050 
4051 	return ok;
4052 }
4053 
4054 // Setting the alpha value to 1.0f by default helps visualization when the alpha channel is not used.
4055 const tcu::Vec4	kDefaultColorForLog	{0.0f, 0.0f, 0.0f, 1.0f};
4056 const float		kTrueComponent		= 1.0f;
4057 const float		kFalseComponent		= 0.5f;
4058 const float		kUnsetComponentLow	= 0.0f;
4059 const float		kUnsetComponentHigh	= 0.25f;
4060 
renderColorImageForLog(const ConstPixelBufferAccess & image,int numChannels)4061 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const ConstPixelBufferAccess& image, int numChannels)
4062 {
4063 	// Same channel order, but using UNORM_INT8 for the color format.
4064 	const auto							order			= image.getFormat().order;
4065 	const tcu::TextureFormat			loggableFormat	{order, tcu::TextureFormat::UNORM_INT8};
4066 	const int							width			= image.getWidth();
4067 	const int							height			= image.getHeight();
4068 	std::unique_ptr<tcu::TextureLevel>	result			{new tcu::TextureLevel{loggableFormat, width, height}};
4069 	auto								access			= result->getAccess();
4070 	tcu::Vec4							outColor		= kDefaultColorForLog;
4071 
4072 	for (int x = 0; x < width; ++x)
4073 	for (int y = 0; y < height; ++y)
4074 	{
4075 		const auto value = image.getPixel(x, y);
4076 		for (int c = 0; c < numChannels; ++c)
4077 		{
4078 			if (value[c] == 0.0f)
4079 				outColor[c] = kFalseComponent;
4080 			else if (value[c] == 1.0f)
4081 				outColor[c] = kTrueComponent;
4082 			else
4083 				DE_ASSERT(false);
4084 		}
4085 		access.setPixel(outColor, x, y);
4086 	}
4087 
4088 	return result;
4089 }
4090 
renderColorImageForLog(const vector<PixelValue> & reference,const UVec2 & targetSize,int numChannels)4091 std::unique_ptr<tcu::TextureLevel> renderColorImageForLog (const vector<PixelValue>& reference, const UVec2& targetSize, int numChannels)
4092 {
4093 	const tcu::TextureFormat			loggableFormat	{tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
4094 	const int							width			= static_cast<int>(targetSize.x());
4095 	const int							height			= static_cast<int>(targetSize.y());
4096 	std::unique_ptr<tcu::TextureLevel>	result			{new tcu::TextureLevel{loggableFormat, width, height}};
4097 	auto								access			= result->getAccess();
4098 	tcu::Vec4							outColor		= kDefaultColorForLog;
4099 
4100 	for (int x = 0; x < width; ++x)
4101 	for (int y = 0; y < height; ++y)
4102 	{
4103 		const int index = x + y * width;
4104 		for (int c = 0; c < numChannels; ++c)
4105 		{
4106 			const auto maybeValue = reference[index].getValue(c);
4107 			if (maybeValue)
4108 				outColor[c] = ((*maybeValue) ? kTrueComponent : kFalseComponent);
4109 			else
4110 				outColor[c] = ((((x / 3) % 2) == ((y / 3) % 2)) ? kUnsetComponentLow : kUnsetComponentHigh);
4111 		}
4112 		access.setPixel(outColor, x, y);
4113 	}
4114 
4115 	return result;
4116 }
4117 
verifyDepthAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage,const DepthValuesArray & depthValues,float epsilon)4118 bool verifyDepthAttachment (const vector<PixelValue>&		reference,
4119 							const ConstPixelBufferAccess&	result,
4120 							const PixelBufferAccess&		errorImage,
4121 							const DepthValuesArray&			depthValues,
4122 							float							epsilon)
4123 {
4124 	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
4125 	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
4126 	bool		ok		= true;
4127 
4128 	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4129 	DE_ASSERT(result.getWidth() == errorImage.getWidth());
4130 	DE_ASSERT(result.getHeight() == errorImage.getHeight());
4131 
4132 	for (int y = 0; y < result.getHeight(); y++)
4133 	for (int x = 0; x < result.getWidth(); x++)
4134 	{
4135 		bool pixelOk = true;
4136 
4137 		const float			resultDepth		= result.getPixDepth(x, y);
4138 		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
4139 		const Maybe<bool>	maybeValue		= referenceValue.getValue(0);
4140 
4141 		if (maybeValue)
4142 		{
4143 			const bool value = *maybeValue;
4144 
4145 			if ((value && !depthsEqual(resultDepth, float(depthValues[1]) / 255.0f, epsilon))
4146 				|| (!value && !depthsEqual(resultDepth, float(depthValues[0]) / 255.0f, epsilon)))
4147 				pixelOk = false;
4148 		}
4149 
4150 		if (!pixelOk)
4151 		{
4152 			errorImage.setPixel(red, x, y);
4153 			ok = false;
4154 		}
4155 		else
4156 			errorImage.setPixel(green, x, y);
4157 	}
4158 
4159 	return ok;
4160 }
4161 
verifyStencilAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)4162 bool verifyStencilAttachment (const vector<PixelValue>&		reference,
4163 							  const ConstPixelBufferAccess&	result,
4164 							  const PixelBufferAccess&		errorImage)
4165 {
4166 	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
4167 	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
4168 	bool		ok		= true;
4169 
4170 	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
4171 	DE_ASSERT(result.getWidth() == errorImage.getWidth());
4172 	DE_ASSERT(result.getHeight() == errorImage.getHeight());
4173 
4174 	for (int y = 0; y < result.getHeight(); y++)
4175 	for (int x = 0; x < result.getWidth(); x++)
4176 	{
4177 		bool pixelOk = true;
4178 
4179 		const deUint32		resultStencil	= result.getPixStencil(x, y);
4180 		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
4181 		const Maybe<bool>	maybeValue		= referenceValue.getValue(1);
4182 
4183 		if (maybeValue)
4184 		{
4185 			const bool value = *maybeValue;
4186 
4187 			if ((value && (resultStencil != 0xFFu))
4188 				|| (!value && resultStencil != 0x0u))
4189 				pixelOk = false;
4190 		}
4191 
4192 		if (!pixelOk)
4193 		{
4194 			errorImage.setPixel(red, x, y);
4195 			ok = false;
4196 		}
4197 		else
4198 			errorImage.setPixel(green, x, y);
4199 	}
4200 
4201 	return ok;
4202 }
4203 
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)4204 bool logAndVerifyImages (TestLog&											log,
4205 						 const DeviceInterface&								vk,
4206 						 VkDevice											device,
4207 						 const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
4208 						 const vector<bool>&								attachmentIsLazy,
4209 						 const RenderPass&									renderPassInfo,
4210 						 const vector<Maybe<VkClearValue> >&				renderPassClearValues,
4211 						 const vector<Maybe<VkClearValue> >&				imageClearValues,
4212 						 const vector<SubpassRenderInfo>&					subpassRenderInfo,
4213 						 const UVec2&										targetSize,
4214 						 const TestConfig&									config)
4215 {
4216 	vector<vector<PixelValue> >	referenceValues;
4217 	vector<tcu::TextureLevel>	referenceAttachments;
4218 	bool						isOk					= true;
4219 
4220 	log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
4221 
4222 	renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize, config.drawStartNdx, config.depthValues);
4223 	renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo, config.depthValues);
4224 
4225 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4226 	{
4227 		if (!attachmentIsLazy[attachmentNdx])
4228 		{
4229 			bool						attachmentOK	= true;
4230 			const Attachment			attachment		= renderPassInfo.getAttachments()[attachmentNdx];
4231 			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
4232 
4233 			if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
4234 			{
4235 				const tcu::TextureFormat	depthFormat			= getDepthCopyFormat(attachment.getFormat());
4236 				void* const					depthPtr			= attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4237 
4238 				const tcu::TextureFormat	stencilFormat		= getStencilCopyFormat(attachment.getFormat());
4239 				void* const					stencilPtr			= attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
4240 
4241 				invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4242 				invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getSecondaryResultMemory());
4243 
4244 				{
4245 					bool							depthOK				= true;
4246 					bool							stencilOK			= true;
4247 					const ConstPixelBufferAccess	depthAccess			(depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
4248 					const ConstPixelBufferAccess	stencilAccess		(stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
4249 					tcu::TextureLevel				depthErrorImage		(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4250 					tcu::TextureLevel				stencilErrorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4251 
4252 					if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
4253 						&& !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4254 					{
4255 						depthOK = false;
4256 					}
4257 
4258 					if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
4259 						&& !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
4260 					{
4261 						stencilOK = false;
4262 					}
4263 
4264 					if (!depthOK || !stencilOK)
4265 					{
4266 						const auto attachmentNdxStr = de::toString(attachmentNdx);
4267 
4268 						// Output images.
4269 						log << TestLog::ImageSet("OutputAttachments" + attachmentNdxStr, "Output depth and stencil attachments " + attachmentNdxStr);
4270 						log << TestLog::Image("Attachment" + attachmentNdxStr + "Depth", "Attachment " + attachmentNdxStr + " Depth", depthAccess);
4271 						log << TestLog::Image("Attachment" + attachmentNdxStr + "Stencil", "Attachment " + attachmentNdxStr + " Stencil", stencilAccess);
4272 						log << TestLog::EndImageSet;
4273 
4274 						// Reference images. These will be logged as image sets due to having depth and stencil aspects.
4275 						log << TestLog::Image("AttachmentReferences" + attachmentNdxStr, "Reference images " + attachmentNdxStr, referenceAttachments[attachmentNdx].getAccess());
4276 
4277 						// Error masks.
4278 						log << TestLog::ImageSet("ErrorMasks" + attachmentNdxStr, "Error masks " + attachmentNdxStr);
4279 						if (!depthOK)
4280 							log << TestLog::Image("DepthAttachmentError" + attachmentNdxStr, "Depth Attachment Error " + attachmentNdxStr, depthErrorImage.getAccess());
4281 						if (!stencilOK)
4282 							log << TestLog::Image("StencilAttachmentError" + attachmentNdxStr, "Stencil Attachment Error " + attachmentNdxStr, stencilErrorImage.getAccess());
4283 						log << TestLog::EndImageSet;
4284 
4285 						attachmentOK = false;
4286 					}
4287 				}
4288 			}
4289 			else
4290 			{
4291 				void* const	ptr	= attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
4292 
4293 				invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
4294 
4295 				bool							depthOK		= true;
4296 				bool							stencilOK	= true;
4297 				bool							colorOK		= true;
4298 				const ConstPixelBufferAccess	access		(format, targetSize.x(), targetSize.y(), 1, ptr);
4299 				tcu::TextureLevel				errorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
4300 
4301 				if (tcu::hasDepthComponent(format.order))
4302 				{
4303 					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4304 						&& !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
4305 					{
4306 						depthOK = false;
4307 					}
4308 				}
4309 				else if (tcu::hasStencilComponent(format.order))
4310 				{
4311 					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4312 						&& !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
4313 					{
4314 						stencilOK = false;
4315 					}
4316 				}
4317 				else
4318 				{
4319 					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
4320 						&& !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(), config.useFormatCompCount))
4321 					{
4322 						colorOK = false;
4323 					}
4324 				}
4325 
4326 				if (!depthOK || !stencilOK || !colorOK)
4327 				{
4328 					log << TestLog::ImageSet("TestImages", "Output attachment, reference image and error mask");
4329 					if (!depthOK || !stencilOK)
4330 					{
4331 						// Log without conversions.
4332 						log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
4333 						log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
4334 					}
4335 					else
4336 					{
4337 						// Convert color images to better reflect test status and output in any format.
4338 						const auto numChannels		= tcu::getNumUsedChannels(access.getFormat().order);
4339 						const auto attachmentForLog	= renderColorImageForLog(access, numChannels);
4340 						const auto referenceForLog	= renderColorImageForLog(referenceValues[attachmentNdx], targetSize, numChannels);
4341 
4342 						log << TestLog::Message << "Check the attachment formats and test data to verify which components affect the test result." << TestLog::EndMessage;
4343 						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;
4344 						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;
4345 
4346 						log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), attachmentForLog->getAccess());
4347 						log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceForLog->getAccess());
4348 					}
4349 					log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
4350 					log << TestLog::EndImageSet;
4351 
4352 					attachmentOK = false;
4353 				}
4354 			}
4355 
4356 			if (!attachmentOK)
4357 				isOk = false;
4358 		}
4359 	}
4360 
4361 	return isOk;
4362 }
4363 
getInputAttachmentType(VkFormat vkFormat)4364 std::string getInputAttachmentType (VkFormat vkFormat)
4365 {
4366 	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
4367 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
4368 
4369 	switch (channelClass)
4370 	{
4371 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4372 			return "isubpassInput";
4373 
4374 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4375 			return "usubpassInput";
4376 
4377 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4378 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4379 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4380 			return "subpassInput";
4381 
4382 		default:
4383 			DE_FATAL("Unknown channel class");
4384 			return "";
4385 	}
4386 }
4387 
getAttachmentType(VkFormat vkFormat,deBool useFormatCompCount)4388 std::string getAttachmentType (VkFormat vkFormat, deBool useFormatCompCount)
4389 {
4390 	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
4391 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
4392 	const size_t					componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
4393 
4394 	switch (channelClass)
4395 	{
4396 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
4397 			if (useFormatCompCount)
4398 				return (componentCount == 1 ? "int" : "ivec" + de::toString(componentCount));
4399 			else
4400 				return "ivec4";
4401 
4402 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
4403 			if (useFormatCompCount)
4404 				return (componentCount == 1 ? "uint" : "uvec" + de::toString(componentCount));
4405 			else
4406 				return "uvec4";
4407 
4408 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
4409 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
4410 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
4411 			if (useFormatCompCount)
4412 				return (componentCount == 1 ? "float" : "vec" + de::toString(componentCount));
4413 			else
4414 				return "vec4";
4415 
4416 		default:
4417 			DE_FATAL("Unknown channel class");
4418 			return "";
4419 	}
4420 }
4421 
createTestShaders(SourceCollections & dst,TestConfig config)4422 void createTestShaders (SourceCollections& dst, TestConfig config)
4423 {
4424 	if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4425 	{
4426 		const vector<Subpass>&	subpasses	= config.renderPass.getSubpasses();
4427 
4428 		for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4429 		{
4430 			const Subpass&		subpass					= subpasses[subpassNdx];
4431 			deUint32			inputAttachmentBinding	= 0;
4432 			std::ostringstream	vertexShader;
4433 			std::ostringstream	fragmentShader;
4434 
4435 			vertexShader << "#version 310 es\n"
4436 						 << "layout(location = 0) in highp vec2 a_position;\n"
4437 						 << "void main (void) {\n"
4438 						 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
4439 						 << "}\n";
4440 
4441 			fragmentShader << "#version 310 es\n"
4442 						   << "precision highp float;\n";
4443 
4444 			bool hasAnyDepthFormats = false;
4445 
4446 			for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4447 			{
4448 				const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
4449 				const VkImageLayout			layout			= subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4450 				const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
4451 				const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
4452 				const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
4453 				const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
4454 
4455 				if (isDepthFormat || isStencilFormat)
4456 				{
4457 					if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4458 					{
4459 						hasAnyDepthFormats = true;
4460 						fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
4461 						inputAttachmentBinding++;
4462 					}
4463 
4464 					if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4465 					{
4466 						fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
4467 						inputAttachmentBinding++;
4468 					}
4469 				}
4470 				else
4471 				{
4472 					const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
4473 
4474 					fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
4475 					inputAttachmentBinding++;
4476 				}
4477 			}
4478 
4479 			for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4480 			{
4481 				const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[getAttachmentNdx(subpass.getColorAttachments(), attachmentNdx)].getFormat(), config.useFormatCompCount);
4482 				fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
4483 			}
4484 
4485 			if (hasAnyDepthFormats)
4486 				fragmentShader << "\nbool depthsEqual(float a, float b, float epsilon) {\n"
4487 								<< "\treturn abs(a - b) <= epsilon;\n}\n\n";
4488 
4489 			fragmentShader << "void main (void) {\n";
4490 
4491 			if (subpass.getInputAttachments().empty())
4492 			{
4493 				for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4494 				{
4495 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
4496 
4497 					if (attachmentIndex == VK_ATTACHMENT_UNUSED)
4498 						continue;
4499 
4500 					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
4501 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
4502 					const size_t				componentCount	= config.useFormatCompCount ? (size_t)tcu::getNumUsedChannels(format.order) : 4;
4503 					const std::string			attachmentType	= getAttachmentType(attachment.getFormat(), config.useFormatCompCount);
4504 
4505 					fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(" << attachmentType + "(";
4506 
4507 					for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4508 					{
4509 						const size_t	index	= subpassNdx + attachmentIndex + compNdx;
4510 						const BoolOp	op		= boolOpFromIndex(index);
4511 
4512 						if (compNdx > 0)
4513 							fragmentShader << ",\n\t\t";
4514 
4515 						fragmentShader	<< "((int(gl_FragCoord.x) % 2 == " << (index % 2)
4516 										<< ") " << boolOpToString(op) << " ("
4517 										<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4518 										<< ") ? 1.0 : 0.0)";
4519 					}
4520 
4521 					fragmentShader << "));\n";
4522 				}
4523 
4524 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4525 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4526 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4527 				{
4528 					const size_t	index	= subpassNdx + 1;
4529 					const BoolOp	op		= boolOpFromIndex(index);
4530 
4531 					fragmentShader	<< "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
4532 									<< ") " << boolOpToString(op) << " ("
4533 									<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4534 									<< ") ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f);\n";
4535 				}
4536 			}
4537 			else
4538 			{
4539 				size_t	inputComponentCount		= 0;
4540 				size_t	outputComponentCount	= 0;
4541 
4542 				for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4543 				{
4544 					const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
4545 					const VkImageLayout			layout			= subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4546 					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
4547 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
4548 					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
4549 
4550 					if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4551 						inputComponentCount += 1;
4552 					else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4553 						inputComponentCount += 1;
4554 					else
4555 						inputComponentCount += componentCount;
4556 				}
4557 
4558 				for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4559 				{
4560 					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
4561 					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
4562 					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
4563 					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
4564 
4565 					outputComponentCount += componentCount;
4566 				}
4567 
4568 				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4569 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4570 					&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4571 				{
4572 					outputComponentCount++;
4573 				}
4574 
4575 				if (outputComponentCount > 0)
4576 				{
4577 					const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
4578 													? ((inputComponentCount / outputComponentCount)
4579 														+ ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
4580 													: 1;
4581 
4582 					fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n";
4583 
4584 					if (outputComponentCount > 0)
4585 						fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n";
4586 
4587 					size_t inputValueNdx = 0;
4588 
4589 					for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4590 					{
4591 						const char* const	components[]	=
4592 						{
4593 							"x", "y", "z", "w"
4594 						};
4595 						const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
4596 						const VkImageLayout			layout			= subpass.getInputAttachments()[attachmentNdx].getImageLayout();
4597 						const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
4598 						const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
4599 						const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
4600 						const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
4601 						const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
4602 
4603 						if (isDepthFormat || isStencilFormat)
4604 						{
4605 							if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
4606 							{
4607 								fragmentShader << "\tinputs[" << inputValueNdx << "] = depthsEqual(" << deUint32(config.depthValues[1]) <<
4608 									".0f/255.0f, float(subpassLoad(i_depth" << attachmentNdx << ").x), " <<
4609 									std::fixed << std::setprecision(12) << requiredDepthEpsilon(attachment.getFormat()) << ");\n";
4610 								inputValueNdx++;
4611 							}
4612 
4613 							if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4614 							{
4615 								fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
4616 								inputValueNdx++;
4617 							}
4618 						}
4619 						else
4620 						{
4621 							for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4622 							{
4623 								fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
4624 								inputValueNdx++;
4625 							}
4626 						}
4627 					}
4628 
4629 					size_t outputValueNdx = 0;
4630 
4631 					for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4632 					{
4633 						const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
4634 						const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
4635 						const std::string			attachmentType	= getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat(), config.useFormatCompCount);
4636 						const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
4637 						const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
4638 
4639 						for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
4640 						{
4641 							const size_t	index	= subpassNdx + attachmentIndex + outputValueNdx;
4642 							const BoolOp	op		= boolOpFromIndex(index);
4643 
4644 							fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
4645 											<< "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4646 											<< ") " << boolOpToString(op) << " ("
4647 											<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4648 											<< ");\n";
4649 
4650 							for (size_t i = 0; i < inputsPerOutput; i++)
4651 								fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" <<  ((outputValueNdx + compNdx) * inputsPerOutput + i) %  inputComponentCount << "];\n";
4652 						}
4653 
4654 						fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
4655 
4656 						for (size_t compNdx = 0; compNdx < (config.useFormatCompCount ? componentCount : 4); compNdx++)
4657 						{
4658 							if (compNdx > 0)
4659 								fragmentShader << ", ";
4660 
4661 							if (compNdx < componentCount)
4662 								fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
4663 							else
4664 								fragmentShader << "0";
4665 						}
4666 
4667 						outputValueNdx += componentCount;
4668 
4669 						fragmentShader << ");\n";
4670 					}
4671 
4672 					if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
4673 						&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
4674 						&& subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
4675 					{
4676 						const deUint32	attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
4677 						const size_t	index			= subpassNdx + attachmentIndex;
4678 						const BoolOp	op				= boolOpFromIndex(index);
4679 
4680 						fragmentShader << "\toutputs[" << outputValueNdx << "] = "
4681 										<< "(int(gl_FragCoord.x) % 2 == " << (index % 2)
4682 										<< ") " << boolOpToString(op) << " ("
4683 										<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
4684 										<< ");\n";
4685 
4686 						for (size_t i = 0; i < inputsPerOutput; i++)
4687 							fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" <<  (outputValueNdx * inputsPerOutput + i) %  inputComponentCount << "];\n";
4688 
4689 						fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? " << deUint32(config.depthValues[1]) << ".0f/255.0f : " << deUint32(config.depthValues[0]) << ".0f/255.0f;\n";
4690 					}
4691 				}
4692 			}
4693 
4694 			fragmentShader << "}\n";
4695 
4696 			dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
4697 			dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
4698 		}
4699 	}
4700 }
4701 
initializeAttachmentIsLazy(vector<bool> & attachmentIsLazy,const vector<Attachment> & attachments,TestConfig::ImageMemory imageMemory)4702 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
4703 {
4704 	bool lastAttachmentWasLazy	= false;
4705 
4706 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4707 	{
4708 		if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4709 			&& attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
4710 			&& attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
4711 			&& attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
4712 		{
4713 			if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
4714 			{
4715 				attachmentIsLazy.push_back(true);
4716 
4717 				lastAttachmentWasLazy	= true;
4718 			}
4719 			else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
4720 			{
4721 				attachmentIsLazy.push_back(false);
4722 				lastAttachmentWasLazy = false;
4723 			}
4724 			else
4725 				DE_FATAL("Unknown imageMemory");
4726 		}
4727 		else
4728 			attachmentIsLazy.push_back(false);
4729 	}
4730 }
4731 
4732 enum AttachmentRefType
4733 {
4734 	ATTACHMENTREFTYPE_COLOR,
4735 	ATTACHMENTREFTYPE_DEPTH_STENCIL,
4736 	ATTACHMENTREFTYPE_INPUT,
4737 	ATTACHMENTREFTYPE_RESOLVE,
4738 };
4739 
getImageUsageFromLayout(VkImageLayout layout)4740 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
4741 {
4742 	switch (layout)
4743 	{
4744 		case VK_IMAGE_LAYOUT_GENERAL:
4745 		case VK_IMAGE_LAYOUT_PREINITIALIZED:
4746 			return 0;
4747 
4748 		case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
4749 			return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4750 
4751 		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
4752 		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
4753 			return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4754 
4755 		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
4756 			return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4757 
4758 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
4759 			return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4760 
4761 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
4762 			return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4763 
4764 		default:
4765 			DE_FATAL("Unexpected image layout");
4766 			return 0;
4767 	}
4768 }
4769 
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,size_t count,const AttachmentReference * references)4770 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
4771 {
4772 	for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
4773 	{
4774 		const deUint32 attachment = references[referenceNdx].getAttachment();
4775 
4776 		if (attachment != VK_ATTACHMENT_UNUSED)
4777 		{
4778 			VkImageUsageFlags usage;
4779 
4780 			switch (refType)
4781 			{
4782 				case ATTACHMENTREFTYPE_COLOR:
4783 				case ATTACHMENTREFTYPE_RESOLVE:
4784 					usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4785 					break;
4786 
4787 				case ATTACHMENTREFTYPE_DEPTH_STENCIL:
4788 					usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4789 					break;
4790 
4791 				case ATTACHMENTREFTYPE_INPUT:
4792 					usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4793 					break;
4794 
4795 				default:
4796 					DE_FATAL("Unexpected attachment reference type");
4797 					usage = 0;
4798 					break;
4799 			}
4800 
4801 			attachmentImageUsage[attachment] |= usage;
4802 		}
4803 	}
4804 }
4805 
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,const vector<AttachmentReference> & references)4806 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
4807 {
4808 	if (!references.empty())
4809 	{
4810 		getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
4811 	}
4812 }
4813 
initializeAttachmentImageUsage(Context & context,vector<VkImageUsageFlags> & attachmentImageUsage,const RenderPass & renderPassInfo,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & clearValues)4814 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
4815 {
4816 	attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
4817 
4818 	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
4819 	{
4820 		const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
4821 
4822 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
4823 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
4824 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
4825 		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
4826 	}
4827 
4828 	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4829 	{
4830 		const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
4831 		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
4832 		const VkFormatFeatureFlags	supportedFeatures	= formatProperties.optimalTilingFeatures;
4833 
4834 		if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4835 			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
4836 
4837 		if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
4838 			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
4839 
4840 		attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
4841 		attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
4842 
4843 		if (!attachmentIsLazy[attachmentNdx])
4844 		{
4845 			if (clearValues[attachmentNdx])
4846 				attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4847 
4848 			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4849 		}
4850 		else
4851 		{
4852 			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);
4853 
4854 			attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
4855 			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
4856 		}
4857 	}
4858 }
4859 
initializeSubpassIsSecondary(vector<bool> & subpassIsSecondary,const vector<Subpass> & subpasses,TestConfig::CommandBufferTypes commandBuffer)4860 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
4861 {
4862 	bool lastSubpassWasSecondary = false;
4863 
4864 	for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4865 	{
4866 		if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
4867 		{
4868 			subpassIsSecondary.push_back(true);
4869 			lastSubpassWasSecondary = true;
4870 		}
4871 		else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
4872 		{
4873 			subpassIsSecondary.push_back(false);
4874 			lastSubpassWasSecondary = false;
4875 		}
4876 		else
4877 			DE_FATAL("Unknown commandBuffer");
4878 	}
4879 }
4880 
initializeImageClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,const vector<bool> & isLazy,deBool useFormatCompCount,const DepthValuesArray & depthValues)4881 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4882 {
4883 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4884 	{
4885 		if (!isLazy[attachmentNdx])
4886 			clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4887 		else
4888 			clearValues.push_back(tcu::Nothing);
4889 	}
4890 }
4891 
initializeRenderPassClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,deBool useFormatCompCount,const DepthValuesArray & depthValues)4892 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, deBool useFormatCompCount, const DepthValuesArray& depthValues)
4893 {
4894 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4895 	{
4896 		if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
4897 			|| attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4898 		{
4899 			clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
4900 		}
4901 		else
4902 			clearValues.push_back(tcu::Nothing);
4903 	}
4904 }
4905 
logSubpassRenderInfo(TestLog & log,const SubpassRenderInfo & info,TestConfig config)4906 void logSubpassRenderInfo (TestLog& log, const SubpassRenderInfo& info, TestConfig config)
4907 {
4908 	log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4909 
4910 	if (info.isSecondary())
4911 		log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4912 	else
4913 		log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4914 
4915 	for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4916 	{
4917 		const ColorClear&	colorClear	= info.getColorClears()[attachmentNdx];
4918 
4919 		log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4920 			<< ". Offset: " << colorClear.getOffset()
4921 			<< ", Size: " << colorClear.getSize()
4922 			<< ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor(), config.useFormatCompCount) << TestLog::EndMessage;
4923 	}
4924 
4925 	if (info.getDepthStencilClear())
4926 	{
4927 		const DepthStencilClear&	depthStencilClear	= *info.getDepthStencilClear();
4928 
4929 		log << TestLog::Message << "Clearing depth stencil attachment"
4930 			<< ". Offset: " << depthStencilClear.getOffset()
4931 			<< ", Size: " << depthStencilClear.getSize()
4932 			<< ", Depth: " << depthStencilClear.getDepth()
4933 			<< ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4934 	}
4935 
4936 	if (info.getRenderQuad())
4937 	{
4938 		const RenderQuad&	renderQuad	= *info.getRenderQuad();
4939 
4940 		log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4941 	}
4942 }
4943 
logTestCaseInfo(TestLog & log,const TestConfig & config,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo)4944 void logTestCaseInfo (TestLog&								log,
4945 					  const TestConfig&						config,
4946 					  const vector<bool>&					attachmentIsLazy,
4947 					  const vector<Maybe<VkClearValue> >&	imageClearValues,
4948 					  const vector<Maybe<VkClearValue> >&	renderPassClearValues,
4949 					  const vector<SubpassRenderInfo>&		subpassRenderInfo)
4950 {
4951 	const RenderPass&	renderPass	= config.renderPass;
4952 
4953 	logRenderPassInfo(log, renderPass);
4954 
4955 	DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4956 	DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4957 	DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4958 
4959 	log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4960 	log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4961 
4962 	for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4963 	{
4964 		const tcu::ScopedLogSection	section	(log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4965 
4966 		if (attachmentIsLazy[attachmentNdx])
4967 			log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4968 
4969 		if (imageClearValues[attachmentNdx])
4970 			log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4971 					*imageClearValues[attachmentNdx], config.useFormatCompCount) << " before rendering." << TestLog::EndMessage;
4972 
4973 		if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4974 			log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
4975 					*renderPassClearValues[attachmentNdx], config.useFormatCompCount) << " in the beginning of the render pass." << TestLog::EndMessage;
4976 	}
4977 
4978 	for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4979 	{
4980 		const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4981 
4982 		logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx], config);
4983 	}
4984 }
4985 
roundToViewport(float x,deUint32 offset,deUint32 size)4986 float roundToViewport (float x, deUint32 offset, deUint32 size)
4987 {
4988 	const float		origin	= (float)(offset) + ((float(size) / 2.0f));
4989 	const float		p		= (float)(size) / 2.0f;
4990 	const deInt32	xi		= deRoundFloatToInt32(origin + (p * x));
4991 
4992 	return (((float)xi) - origin) / p;
4993 }
4994 
initializeSubpassRenderInfo(vector<SubpassRenderInfo> & renderInfos,de::Random & rng,const RenderPass & renderPass,const TestConfig & config)4995 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4996 {
4997 	const TestConfig::CommandBufferTypes	commandBuffer			= config.commandBufferTypes;
4998 	const vector<Subpass>&					subpasses				= renderPass.getSubpasses();
4999 	bool									lastSubpassWasSecondary	= false;
5000 
5001 	for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
5002 	{
5003 		const Subpass&				subpass				= subpasses[subpassNdx];
5004 		const bool					subpassIsSecondary	= commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
5005 														|| (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
5006 		const bool					omitBlendState		= subpass.getOmitBlendState();
5007 		const UVec2					viewportSize		((config.renderSize * UVec2(2)) / UVec2(3));
5008 		const UVec2					viewportOffset		(config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
5009 														 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
5010 
5011 		vector<ColorClear>			colorClears;
5012 		Maybe<DepthStencilClear>	depthStencilClear;
5013 		Maybe<RenderQuad>			renderQuad;
5014 
5015 		lastSubpassWasSecondary		= subpassIsSecondary;
5016 
5017 		if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
5018 		{
5019 			const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();
5020 
5021 			for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
5022 			{
5023 				const AttachmentReference&	attachmentRef	= colorAttachments[attachmentRefNdx];
5024 				const Attachment&			attachment		= renderPass.getAttachments()[attachmentRef.getAttachment()];
5025 				const UVec2					size			((viewportSize * UVec2(2)) / UVec2(3));
5026 				const UVec2					offset			(viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
5027 															 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
5028 				const VkClearColorValue		color			= randomColorClearValue(attachment, rng, config.useFormatCompCount);
5029 
5030 				colorClears.push_back(ColorClear(offset, size, color));
5031 			}
5032 
5033 			if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
5034 			{
5035 				const Attachment&	attachment	= renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
5036 				const UVec2			size		((viewportSize * UVec2(2)) / UVec2(3));
5037 				const UVec2			offset		(viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
5038 												 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
5039 				const VkClearValue	value		= randomClearValue(attachment, rng, config.useFormatCompCount, config.depthValues);
5040 
5041 				depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
5042 			}
5043 		}
5044 
5045 		if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
5046 		{
5047 			const float	w	= (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
5048 			const float	h	= (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
5049 
5050 			const float	x0	= roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
5051 			const float	x1	= roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
5052 
5053 			const float	y0	= roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
5054 			const float	y1	= roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
5055 
5056 			renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
5057 		}
5058 
5059 		renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, config.drawStartNdx, subpassIsSecondary, omitBlendState, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
5060 	}
5061 }
5062 
checkTextureFormatSupport(TestLog & log,const InstanceInterface & vk,VkPhysicalDevice device,const vector<Attachment> & attachments)5063 void checkTextureFormatSupport (TestLog&					log,
5064 								const InstanceInterface&	vk,
5065 								VkPhysicalDevice			device,
5066 								const vector<Attachment>&	attachments)
5067 {
5068 	bool supported = true;
5069 
5070 	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
5071 	{
5072 		const Attachment&			attachment					= attachments[attachmentNdx];
5073 		const tcu::TextureFormat	format						= mapVkFormat(attachment.getFormat());
5074 		const bool					isDepthOrStencilAttachment	= hasDepthComponent(format.order) || hasStencilComponent(format.order);
5075 		const VkFormatFeatureFlags	flags						= isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
5076 		VkFormatProperties			properties;
5077 
5078 		vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
5079 
5080 		if ((properties.optimalTilingFeatures & flags) != flags)
5081 		{
5082 			supported = false;
5083 			log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
5084 		}
5085 	}
5086 
5087 	if (!supported)
5088 		TCU_THROW(NotSupportedError, "Format not supported");
5089 }
5090 
renderPassTest(Context & context,TestConfig config)5091 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
5092 {
5093 	const UVec2							targetSize			= config.targetSize;
5094 	const UVec2							renderPos			= config.renderPos;
5095 	const UVec2							renderSize			= config.renderSize;
5096 	const RenderPass&					renderPassInfo		= config.renderPass;
5097 
5098 	TestLog&							log					= context.getTestContext().getLog();
5099 	de::Random							rng					(config.seed);
5100 
5101 	vector<bool>						attachmentIsLazy;
5102 	vector<VkImageUsageFlags>			attachmentImageUsage;
5103 	vector<Maybe<VkClearValue> >		imageClearValues;
5104 	vector<Maybe<VkClearValue> >		renderPassClearValues;
5105 
5106 	vector<bool>						subpassIsSecondary;
5107 	vector<SubpassRenderInfo>			subpassRenderInfo;
5108 
5109 	if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
5110 		context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
5111 
5112 	if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5113 		context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
5114 
5115 	if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
5116 	{
5117 		if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
5118 			TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
5119 	}
5120 
5121 	if (!renderPassInfo.getInputAspects().empty())
5122 	{
5123 		if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5124 			TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
5125 	}
5126 
5127 	{
5128 		bool requireDepthStencilLayout = false;
5129 
5130 		for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5131 		{
5132 			if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5133 				|| renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
5134 				|| renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5135 				|| renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5136 			{
5137 				requireDepthStencilLayout = true;
5138 				break;
5139 			}
5140 		}
5141 
5142 		for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++)
5143 		{
5144 			const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]);
5145 
5146 			for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
5147 			{
5148 				if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5149 					|| subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5150 				{
5151 					requireDepthStencilLayout = true;
5152 					break;
5153 				}
5154 			}
5155 
5156 			for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
5157 			{
5158 				if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5159 					|| subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5160 				{
5161 					requireDepthStencilLayout = true;
5162 					break;
5163 				}
5164 			}
5165 
5166 			for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
5167 			{
5168 				if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5169 					|| subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5170 				{
5171 					requireDepthStencilLayout = true;
5172 					break;
5173 				}
5174 			}
5175 
5176 			if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
5177 				|| subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
5178 			{
5179 				requireDepthStencilLayout = true;
5180 				break;
5181 			}
5182 		}
5183 
5184 		if (requireDepthStencilLayout && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
5185 			TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
5186 	}
5187 
5188 	initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
5189 	initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy, config.useFormatCompCount, config.depthValues);
5190 	initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
5191 	initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments(), config.useFormatCompCount, config.depthValues);
5192 
5193 	initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
5194 	initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
5195 
5196 	logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
5197 
5198 	checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
5199 
5200 	{
5201 		const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
5202 
5203 		log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
5204 
5205 		for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5206 		{
5207 			 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
5208 				 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
5209 		}
5210 	}
5211 
5212 	{
5213 		const InstanceInterface&					vki									= context.getInstanceInterface();
5214 		const VkPhysicalDevice&						physDevice							= context.getPhysicalDevice();
5215 		const VkDevice								device								= context.getDevice();
5216 		const DeviceInterface&						vk									= context.getDeviceInterface();
5217 		const VkQueue								queue								= context.getUniversalQueue();
5218 		const deUint32								queueIndex							= context.getUniversalQueueFamilyIndex();
5219 		Allocator&									allocator							= context.getDefaultAllocator();
5220 
5221 		const Unique<VkCommandPool>					commandBufferPool					(createCommandPool(vk, device, 0, queueIndex));
5222 		const Unique<VkCommandBuffer>				initializeImagesCommandBuffer		(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5223 		const Unique<VkCommandBuffer>				renderCommandBuffer					(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5224 		const Unique<VkCommandBuffer>				readImagesToBuffersCommandBuffer	(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5225 
5226 		vector<de::SharedPtr<AttachmentResources> >	attachmentResources;
5227 		vector<de::SharedPtr<SubpassRenderer> >		subpassRenderers;
5228 		vector<VkImage>								attachmentImages;
5229 		vector<VkImageView>							attachmentViews;
5230 		vector<pair<VkImageView, VkImageView> >		inputAttachmentViews;
5231 
5232 		Move<VkRenderPass> renderPass;
5233 		if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5234 			renderPass = createRenderPass(vk, device, renderPassInfo, config.groupParams->renderingType);
5235 
5236 		for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
5237 		{
5238 			const Attachment&	attachmentInfo	= renderPassInfo.getAttachments()[attachmentNdx];
5239 
5240 			attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
5241 			attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
5242 			attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
5243 
5244 			inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
5245 		}
5246 
5247 		beginCommandBuffer(vk, *initializeImagesCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5248 		pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
5249 		endCommandBuffer(vk, *initializeImagesCommandBuffer);
5250 
5251 		{
5252 			Move<VkFramebuffer> framebuffer;
5253 			if (config.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
5254 				framebuffer = createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews);
5255 
5256 			const VkRect2D renderArea
5257 			{
5258 				{ (deInt32)renderPos.x(),	(deInt32)renderPos.y()	},
5259 				{ renderSize.x(),			renderSize.y()			}
5260 			};
5261 			const bool dynamicRendering = (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
5262 			const bool secondaryCmdBufferCompletelyContainsDynamicRenderpass = (config.commandBufferTypes == TestConfig::COMMANDBUFFERTYPES_SECONDARY) &&
5263 																				config.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass;
5264 
5265 			for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
5266 			{
5267 				subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, renderPassInfo, attachmentResources,
5268 																							  renderArea, renderPassClearValues, *renderPass, *framebuffer,
5269 																							  *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews,
5270 																							  subpassRenderInfo[subpassNdx], config.allocationKind, dynamicRendering,
5271 																							  secondaryCmdBufferCompletelyContainsDynamicRenderpass)));
5272 			}
5273 
5274 			beginCommandBuffer(vk, *renderCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5275 			pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, renderPassInfo, attachmentResources, *framebuffer, subpassRenderers, renderArea,
5276 								   renderPassClearValues, queueIndex, config.renderTypes, config.groupParams->renderingType, secondaryCmdBufferCompletelyContainsDynamicRenderpass);
5277 			endCommandBuffer(vk, *renderCommandBuffer);
5278 
5279 			beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
5280 			pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
5281 			endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
5282 			{
5283 				const VkCommandBuffer commandBuffers[] =
5284 				{
5285 					*initializeImagesCommandBuffer,
5286 					*renderCommandBuffer,
5287 					*readImagesToBuffersCommandBuffer
5288 				};
5289 				const Unique<VkFence>	fence		(createFence(vk, device, 0u));
5290 
5291 				queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
5292 				waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
5293 			}
5294 		}
5295 #ifdef CTS_USES_VULKANSC
5296 		if (!context.getTestContext().getCommandLine().isSubProcess())
5297 			return tcu::TestStatus::pass("Pass");
5298 #endif
5299 		if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
5300 			return tcu::TestStatus::pass("Pass");
5301 		else
5302 			return tcu::TestStatus::fail("Result verification failed");
5303 	}
5304 }
5305 
5306 class RenderPassNoDrawLoadStoreTestCase : public vkt::TestCase
5307 {
5308 public:
5309 	RenderPassNoDrawLoadStoreTestCase(tcu::TestContext& context, const std::string& name, const std::string& description, bool useRenderPass2);
5310 	TestInstance*   createInstance          (Context& context) const override;
5311 private:
5312 	bool m_renderPass2;
5313 };
5314 
5315 class RenderPassNoDrawLoadStoreTestInstance : public vkt::TestInstance
5316 {
5317 public:
5318 	RenderPassNoDrawLoadStoreTestInstance(Context& context, bool useRenderPass2);
5319 
5320 	template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
5321 	Move<VkRenderPass> createRenderPass (const DeviceInterface&	vk, VkDevice vkDevice, RenderingType type);
5322 	virtual tcu::TestStatus iterate(void);
5323 private:
5324 	bool m_renderPass2;
5325 };
5326 
RenderPassNoDrawLoadStoreTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool useRenderPass2)5327 RenderPassNoDrawLoadStoreTestCase::RenderPassNoDrawLoadStoreTestCase(tcu::TestContext& context, const std::string& name, const std::string& description, bool useRenderPass2)
5328 	: vkt::TestCase(context, name, description), m_renderPass2(useRenderPass2) {}
5329 
RenderPassNoDrawLoadStoreTestInstance(Context & context,bool useRenderPass2)5330 RenderPassNoDrawLoadStoreTestInstance::RenderPassNoDrawLoadStoreTestInstance(Context& context, bool useRenderPass2) : vkt::TestInstance(context), m_renderPass2(useRenderPass2) { }
5331 
createInstance(Context & context) const5332 TestInstance* RenderPassNoDrawLoadStoreTestCase::createInstance(Context& context) const {
5333 	return new RenderPassNoDrawLoadStoreTestInstance(context, m_renderPass2);
5334 }
5335 
5336 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,RenderingType type)5337 Move<VkRenderPass> RenderPassNoDrawLoadStoreTestInstance::createRenderPass (const DeviceInterface&	vk,
5338 									 VkDevice				vkDevice,
5339 									 RenderingType			type)
5340 {
5341 	const VkImageAspectFlags	aspectMask						= type == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
5342 
5343 	const AttachmentDesc attachmentDescription =
5344 		// Result attachment
5345 		AttachmentDesc (
5346 			nullptr,									// const void*						pNext
5347 			(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags		flags
5348 			VK_FORMAT_R8G8B8A8_UNORM,					// VkFormat							format
5349 			VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits			samples
5350 			VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp
5351 			VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp
5352 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp
5353 			VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp
5354 			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout					initialLayout
5355 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
5356 		);
5357 
5358 	const AttachmentRef resultAttachmentRefSubpass0 (
5359 		nullptr,									// const void*			pNext
5360 		0u,											// deUint32				attachment
5361 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout		layout
5362 		aspectMask									// VkImageAspectFlags	aspectMask
5363 	);
5364 
5365 	const SubpassDesc subpassDescription =
5366 		SubpassDesc (
5367 			nullptr,
5368 			(VkSubpassDescriptionFlags)0,		// VkSubpassDescriptionFlags		flags
5369 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint				pipelineBindPoint
5370 			0u,									// deUint32							viewMask
5371 			0u,									// deUint32							inputAttachmentCount
5372 			nullptr,							// const VkAttachmentReference*		pInputAttachments
5373 			1u,									// deUint32							colorAttachmentCount
5374 			&resultAttachmentRefSubpass0,		// const VkAttachmentReference*		pColorAttachments
5375 			nullptr,							// const VkAttachmentReference*		pResolveAttachments
5376 			nullptr,							// const VkAttachmentReference*		pDepthStencilAttachment
5377 			0u,									// deUint32							preserveAttachmentCount
5378 			nullptr								// const deUint32*					pPreserveAttachments
5379 		);
5380 
5381 	const RenderPassCreateInfo renderPassInfo (
5382 		nullptr,									// const void*						pNext
5383 		(VkRenderPassCreateFlags)0,					// VkRenderPassCreateFlags			flags
5384 		1u,											// deUint32							attachmentCount
5385 		&attachmentDescription,						// const VkAttachmentDescription*	pAttachments
5386 		1u,											// deUint32							subpassCount
5387 		&subpassDescription,						// const VkSubpassDescription*		pSubpasses
5388 		0u,											// deUint32							dependencyCount
5389 		nullptr,									// const VkSubpassDependency*		pDependencies
5390 		0u,											// deUint32							correlatedViewMaskCount
5391 		nullptr										// const deUint32*					pCorrelatedViewMasks
5392 	);
5393 	return renderPassInfo.createRenderPass(vk, vkDevice);
5394 }
5395 
iterate()5396 tcu::TestStatus RenderPassNoDrawLoadStoreTestInstance::iterate() {
5397 	const auto& vkd			= m_context.getDeviceInterface();
5398 	const auto  device		= m_context.getDevice();
5399 	auto& alloc				= m_context.getDefaultAllocator();
5400 
5401 	auto imageFormat		= VK_FORMAT_R8G8B8A8_UNORM;
5402 	auto imageExtent		= makeExtent3D(1, 1, 1u);
5403 
5404 	const tcu::IVec3 imageDim	(static_cast<int>(imageExtent.width), static_cast<int>(imageExtent.height), static_cast<int>(imageExtent.depth));
5405 	const tcu::IVec2 imageSize	(imageDim.x(), imageDim.y());
5406 
5407 	const std::vector<VkViewport>	viewports	{ makeViewport(imageExtent) };
5408 	const std::vector<VkRect2D>		scissors	{ makeRect2D(imageExtent) };
5409 
5410 	de::MovePtr<ImageWithMemory>  colorAttachment;
5411 
5412 	const auto  qIndex	= m_context.getUniversalQueueFamilyIndex();
5413 
5414 	const auto  subresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
5415 	const auto  imageUsage			= static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
5416 	const VkImageCreateInfo imageCreateInfo =
5417 	{
5418 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType				sType;
5419 		nullptr,								//	const void*					pNext;
5420 		0u,										//	VkImageCreateFlags			flags;
5421 		VK_IMAGE_TYPE_2D,						//	VkImageType					imageType;
5422 		imageFormat,							//	VkFormat					format;
5423 		imageExtent,							//	VkExtent3D					extent;
5424 		1u,										//	deUint32					mipLevels;
5425 		1u,										//	deUint32					arrayLayers;
5426 		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits		samples;
5427 		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling				tiling;
5428 		imageUsage,								//	VkImageUsageFlags			usage;
5429 		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode				sharingMode;
5430 		0u,										//	deUint32					queueFamilyIndexCount;
5431 		nullptr,								//	const deUint32*				pQueueFamilyIndices;
5432 		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout				initialLayout;
5433 	};
5434 
5435 	colorAttachment               = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any));
5436 	auto colorAttachmentView      = makeImageView(vkd, device, colorAttachment->get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, subresourceRange);
5437 
5438 	const auto	tcuFormat			= mapVkFormat(imageFormat);
5439 	const auto	outBufferSize		= static_cast<VkDeviceSize>(static_cast<uint32_t>(tcu::getPixelSize(tcuFormat)) * imageExtent.width * imageExtent.height);
5440 
5441 	BufferWithMemory outBuffer (vkd, device, alloc, makeBufferCreateInfo(outBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
5442 	auto&		outBufferAlloc		= outBuffer.getAllocation();
5443 	void*		outBufferData		= outBufferAlloc.getHostPtr();
5444 
5445 	Move<VkRenderPass> renderPass;
5446 	if (m_renderPass2) {
5447 		renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>
5448 			(vkd, device, RENDERING_TYPE_RENDERPASS_LEGACY);
5449 	} else {
5450 		renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>
5451 			(vkd, device, RENDERING_TYPE_RENDERPASS2);
5452 	}
5453 
5454 	// Framebuffer.
5455 	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorAttachmentView.get(), imageExtent.width, imageExtent.height);
5456 
5457 	const auto clearValueColor = makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
5458 
5459 	auto graphicsPipelineLayout = makePipelineLayout(vkd, device);
5460 	auto commandPool	= createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, qIndex);
5461 	auto commandBuffer	= allocateCommandBuffer(vkd, device, commandPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5462 
5463 	beginCommandBuffer(vkd, commandBuffer.get());
5464 
5465 	const VkRenderPassBeginInfo renderPassBeginInfo =
5466 	{
5467 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
5468 		nullptr,										// const void*             pNext;
5469 		*renderPass,									// VkRenderPass            renderPass;
5470 		*framebuffer,									// VkFramebuffer           framebuffer;
5471 		scissors.at(0),									// VkRect2D                renderArea;
5472 		1,												// uint32_t                clearValueCount;
5473 		&clearValueColor,								// const VkClearValue*     pClearValues;
5474 	};
5475 	vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
5476 	vkd.cmdEndRenderPass(*commandBuffer);
5477 	auto barrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
5478 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, colorAttachment->get(), subresourceRange);
5479 	cmdPipelineImageMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &barrier);
5480 	copyImageToBuffer(vkd, commandBuffer.get(), colorAttachment.get()->get(), outBuffer.get(), imageSize);
5481 	endCommandBuffer(vkd, commandBuffer.get());
5482 	submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), commandBuffer.get());
5483 	invalidateAlloc(vkd, device, outBufferAlloc);
5484 
5485 	tcu::ConstPixelBufferAccess outPixels(tcuFormat, imageDim, outBufferData);
5486 	auto pixel = outPixels.getPixel(0, 0);
5487 	auto expected = tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);
5488 
5489 	if (pixel != expected) {
5490 		std::stringstream output("Pixel isn't equal to clear color: ");
5491 		output << pixel << " instead of " << expected;
5492 		return tcu::TestStatus::fail(output.str());
5493 	}
5494 
5495 	return tcu::TestStatus::pass("Pass");
5496 }
5497 
5498 static const VkFormat s_coreColorFormats[] =
5499 {
5500 	VK_FORMAT_R5G6B5_UNORM_PACK16,
5501 	VK_FORMAT_R8_UNORM,
5502 	VK_FORMAT_R8_SNORM,
5503 	VK_FORMAT_R8_UINT,
5504 	VK_FORMAT_R8_SINT,
5505 	VK_FORMAT_R8G8_UNORM,
5506 	VK_FORMAT_R8G8_SNORM,
5507 	VK_FORMAT_R8G8_UINT,
5508 	VK_FORMAT_R8G8_SINT,
5509 	VK_FORMAT_R8G8B8A8_UNORM,
5510 	VK_FORMAT_R8G8B8A8_SNORM,
5511 	VK_FORMAT_R8G8B8A8_UINT,
5512 	VK_FORMAT_R8G8B8A8_SINT,
5513 	VK_FORMAT_R8G8B8A8_SRGB,
5514 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
5515 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
5516 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
5517 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
5518 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
5519 	VK_FORMAT_B8G8R8A8_UNORM,
5520 	VK_FORMAT_B8G8R8A8_SRGB,
5521 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
5522 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
5523 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
5524 	VK_FORMAT_R16_UNORM,
5525 	VK_FORMAT_R16_SNORM,
5526 	VK_FORMAT_R16_UINT,
5527 	VK_FORMAT_R16_SINT,
5528 	VK_FORMAT_R16_SFLOAT,
5529 	VK_FORMAT_R16G16_UNORM,
5530 	VK_FORMAT_R16G16_SNORM,
5531 	VK_FORMAT_R16G16_UINT,
5532 	VK_FORMAT_R16G16_SINT,
5533 	VK_FORMAT_R16G16_SFLOAT,
5534 	VK_FORMAT_R16G16B16A16_UNORM,
5535 	VK_FORMAT_R16G16B16A16_SNORM,
5536 	VK_FORMAT_R16G16B16A16_UINT,
5537 	VK_FORMAT_R16G16B16A16_SINT,
5538 	VK_FORMAT_R16G16B16A16_SFLOAT,
5539 	VK_FORMAT_R32_UINT,
5540 	VK_FORMAT_R32_SINT,
5541 	VK_FORMAT_R32_SFLOAT,
5542 	VK_FORMAT_R32G32_UINT,
5543 	VK_FORMAT_R32G32_SINT,
5544 	VK_FORMAT_R32G32_SFLOAT,
5545 	VK_FORMAT_R32G32B32A32_UINT,
5546 	VK_FORMAT_R32G32B32A32_SINT,
5547 	VK_FORMAT_R32G32B32A32_SFLOAT
5548 };
5549 
5550 static const VkFormat s_coreDepthStencilFormats[] =
5551 {
5552 	VK_FORMAT_D16_UNORM,
5553 
5554 	VK_FORMAT_X8_D24_UNORM_PACK32,
5555 	VK_FORMAT_D32_SFLOAT,
5556 
5557 	VK_FORMAT_D24_UNORM_S8_UINT,
5558 	VK_FORMAT_D32_SFLOAT_S8_UINT
5559 };
5560 
addAttachmentTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)5561 void addAttachmentTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5562 {
5563 	const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
5564 	const VkAttachmentLoadOp loadOps[] =
5565 	{
5566 		VK_ATTACHMENT_LOAD_OP_LOAD,
5567 		VK_ATTACHMENT_LOAD_OP_CLEAR,
5568 		VK_ATTACHMENT_LOAD_OP_DONT_CARE
5569 	};
5570 
5571 	const VkAttachmentStoreOp storeOps[] =
5572 	{
5573 		VK_ATTACHMENT_STORE_OP_STORE,
5574 		VK_ATTACHMENT_STORE_OP_DONT_CARE
5575 	};
5576 
5577 	const VkImageLayout initialAndFinalColorLayouts[] =
5578 	{
5579 		VK_IMAGE_LAYOUT_GENERAL,
5580 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5581 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5582 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5583 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5584 	};
5585 
5586 	const VkImageLayout initialAndFinalColorLayoutsLazy[] =
5587 	{
5588 		VK_IMAGE_LAYOUT_GENERAL,
5589 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5590 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5591 	};
5592 
5593 	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
5594 	{
5595 		VK_IMAGE_LAYOUT_GENERAL,
5596 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5597 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5598 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5599 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5600 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5601 	};
5602 
5603 	const VkImageLayout initialAndFinalDepthStencilLayoutsLazy[] =
5604 	{
5605 		VK_IMAGE_LAYOUT_GENERAL,
5606 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5607 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5608 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5609 	};
5610 
5611 	const VkImageLayout subpassLayouts[] =
5612 	{
5613 		VK_IMAGE_LAYOUT_GENERAL,
5614 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5615 	};
5616 
5617 	const VkImageLayout depthStencilLayouts[] =
5618 	{
5619 		VK_IMAGE_LAYOUT_GENERAL,
5620 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5621 	};
5622 
5623 	const TestConfig::RenderTypes renderCommands[] =
5624 	{
5625 		TestConfig::RENDERTYPES_NONE,
5626 		TestConfig::RENDERTYPES_CLEAR,
5627 		TestConfig::RENDERTYPES_DRAW,
5628 		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
5629 	};
5630 
5631 	const TestConfig::CommandBufferTypes commandBuffers[] =
5632 	{
5633 		TestConfig::COMMANDBUFFERTYPES_INLINE,
5634 		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
5635 		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
5636 	};
5637 
5638 	const TestConfig::ImageMemory imageMemories[] =
5639 	{
5640 		TestConfig::IMAGEMEMORY_STRICT,
5641 		TestConfig::IMAGEMEMORY_LAZY,
5642 		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
5643 	};
5644 
5645 	const UVec2 targetSizes[] =
5646 	{
5647 		UVec2(64, 64),
5648 		UVec2(63, 65)
5649 	};
5650 
5651 	const UVec2 renderPositions[] =
5652 	{
5653 		UVec2(0, 0),
5654 		UVec2(3, 17)
5655 	};
5656 
5657 	const UVec2 renderSizes[] =
5658 	{
5659 		UVec2(32, 32),
5660 		UVec2(60, 47)
5661 	};
5662 
5663 	tcu::TestContext&	testCtx					(group->getTestContext());
5664 	bool				useDynamicRendering		(testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
5665 	de::Random			rng						(1433774382u);
5666 
5667 	for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
5668 	{
5669 		const deUint32					attachmentCount			= attachmentCounts[attachmentCountNdx];
5670 		const deUint32					testCaseCount			= (attachmentCount == 1 ? 100 : 200);
5671 		de::MovePtr<tcu::TestCaseGroup>	attachmentCountGroup	(new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
5672 
5673 		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
5674 		{
5675 			const bool						useDepthStencil		= rng.getBool();
5676 			const TestConfig::ImageMemory	imageMemory			= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5677 			VkImageLayout					depthStencilLayout	= VK_IMAGE_LAYOUT_GENERAL;
5678 			vector<Attachment>				attachments;
5679 			vector<AttachmentReference>		colorAttachmentReferences;
5680 
5681 			// we want to make sure that dynamic rendering test cases have corresponding renderpass
5682 			// cases as this will allow drivers to easily compare GPU batches; since configurations
5683 			// for those tests are generated we need to generate configurations for all cases
5684 			// even when we know earlier that for dynamic rendering we will skip it
5685 			bool executeForDynamicRendering = true;
5686 
5687 			for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5688 			{
5689 				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
5690 				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5691 				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5692 				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5693 
5694 				const VkImageLayout			initialLayout	= (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5695 																? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5696 																: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5697 				VkImageLayout				finalizeLayout	= (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5698 																? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts))
5699 																: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy), DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
5700 				const VkImageLayout			subpassLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5701 
5702 				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5703 				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5704 
5705 				if (useDynamicRendering)
5706 				{
5707 					// with renderpass we can have automatic layout transitions; to do the same with dynamic rendering cases
5708 					// we would need to add addtional barries but since those tests won't add coverage we are skipping them
5709 					if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
5710 						(initialLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL))
5711 						finalizeLayout = initialLayout;
5712 					else
5713 						executeForDynamicRendering = false;
5714 				}
5715 
5716 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5717 				colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5718 			}
5719 
5720 			if (useDepthStencil)
5721 			{
5722 				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
5723 				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
5724 				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5725 				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5726 
5727 				const VkImageLayout			initialLayout	= (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5728 																? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5729 																: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5730 				VkImageLayout				finalizeLayout	= (imageMemory == TestConfig::IMAGEMEMORY_STRICT)
5731 																? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
5732 																: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy), DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
5733 
5734 				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5735 				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5736 
5737 				if (useDynamicRendering)
5738 				{
5739 					if ((initialLayout == VK_IMAGE_LAYOUT_GENERAL) ||
5740 						(initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) ||
5741 						(initialLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL))
5742 						finalizeLayout = initialLayout;
5743 					else
5744 						executeForDynamicRendering = false;
5745 				}
5746 
5747 				depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
5748 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5749 			}
5750 
5751 			{
5752 				const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5753 				const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5754 				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>()));
5755 				const vector<SubpassDependency>			deps;
5756 				const string							testCaseName	= de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
5757 				const RenderPass						renderPass		(attachments, subpasses, deps);
5758 				const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5759 				const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5760 				const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5761 
5762 				if (useDynamicRendering)
5763 				{
5764 					// skip dynamic rendering cases (that don't add coverage) this can be done not earlier than after grabbing all
5765 					// random numbers as we need to make sure that those tests that will be created for dynamic rendering have
5766 					// corresponding renderpass tests with the same name
5767 					if (!executeForDynamicRendering)
5768 						continue;
5769 
5770 					// dont repeat non secondary buffer cases when testing secondaryCmdBufferCompletelyContainsDynamicRenderpass flag
5771 					if (testConfigExternal.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass &&
5772 						(commandBuffer != TestConfig::COMMANDBUFFERTYPES_SECONDARY))
5773 					{
5774 						continue;
5775 					}
5776 				}
5777 
5778 				const TestConfig						testConfig		(renderPass,
5779 																		 render,
5780 																		 commandBuffer,
5781 																		 imageMemory,
5782 																		 targetSize,
5783 																		 renderPos,
5784 																		 renderSize,
5785 																		 DE_FALSE,
5786 																		 1293809,
5787 																		 0,
5788 																		 testConfigExternal.allocationKind,
5789 																		 testConfigExternal.groupParams);
5790 
5791 				addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
5792 			}
5793 		}
5794 
5795 		group->addChild(attachmentCountGroup.release());
5796 	}
5797 }
5798 
addAttachmentWriteMaskTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)5799 void addAttachmentWriteMaskTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5800 {
5801 	const deUint32 attachmentCounts[]	= { 1, 2, 3, 4, 8 };
5802 
5803 	const VkFormat attachmentFormats[]	=
5804 	{
5805 		VK_FORMAT_R8G8B8A8_UINT,
5806 		VK_FORMAT_R8G8B8A8_UNORM,
5807 		VK_FORMAT_R5G6B5_UNORM_PACK16,
5808 		VK_FORMAT_R8G8_UNORM
5809 	};
5810 
5811 	tcu::TestContext&	testCtx			= group->getTestContext();
5812 
5813 	for (deUint32 attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
5814 	{
5815 		const deUint32	attachmentCount	= attachmentCounts[attachmentCountNdx];
5816 		const string	groupName		= "attachment_count_" + de::toString(attachmentCount);
5817 
5818 		de::MovePtr<tcu::TestCaseGroup>	attachmentCountGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), de::toString(attachmentCount).c_str()));
5819 
5820 		for (deUint32 drawStartNdx = 0; drawStartNdx < (attachmentCount); drawStartNdx++)
5821 		{
5822 			deUint32					formatNdx = 0;
5823 			vector<Attachment>			attachments;
5824 			vector<AttachmentReference>	colorAttachmentReferences;
5825 
5826 			for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5827 			{
5828 				const VkFormat				format				= attachmentFormats[formatNdx];
5829 				const VkSampleCountFlagBits	sampleCount			= VK_SAMPLE_COUNT_1_BIT;
5830 				const VkAttachmentLoadOp	loadOp				= VK_ATTACHMENT_LOAD_OP_CLEAR;
5831 				const VkAttachmentStoreOp	storeOp				= VK_ATTACHMENT_STORE_OP_STORE;
5832 				const VkAttachmentLoadOp	stencilLoadOp		= VK_ATTACHMENT_LOAD_OP_CLEAR;
5833 				const VkAttachmentStoreOp	stencilStoreOp		= VK_ATTACHMENT_STORE_OP_STORE;
5834 				const VkImageLayout			initialLayout		= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5835 				const VkImageLayout			finalizeLayout		= (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
5836 																	? initialLayout : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5837 				const VkImageLayout			subpassLayout		= VK_IMAGE_LAYOUT_GENERAL;
5838 
5839 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5840 				colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5841 
5842 				if (++formatNdx == DE_LENGTH_OF_ARRAY(attachmentFormats))
5843 					formatNdx = 0;
5844 			}
5845 
5846 			{
5847 				const VkImageLayout						depthStencilLayout	= VK_IMAGE_LAYOUT_GENERAL;
5848 				const vector<Subpass>					subpass				(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
5849 				const vector<SubpassDependency>			deps;
5850 
5851 				const string							testCaseName		= "start_index_" + de::toString(drawStartNdx);
5852 				const RenderPass						renderPass			(attachments, subpass, deps);
5853 
5854 				const TestConfig::RenderTypes			render				= TestConfig::RENDERTYPES_DRAW;
5855 				const TestConfig::CommandBufferTypes	commandBuffer		= TestConfig::COMMANDBUFFERTYPES_INLINE;
5856 				const TestConfig::ImageMemory			imageMemory			= TestConfig::IMAGEMEMORY_LAZY;
5857 				const UVec2								targetSize			= UVec2(64, 64);
5858 				const UVec2								renderPos			= UVec2(0, 0);
5859 				const UVec2								renderSize			= UVec2(64, 64);
5860 				const deBool							useFormatCompCount	= DE_TRUE;
5861 				const vector<DeviceCoreFeature>			requiredFeatures	= {DEVICE_CORE_FEATURE_INDEPENDENT_BLEND};
5862 				const TestConfig						testConfig			(renderPass,
5863 																			 render,
5864 																			 commandBuffer,
5865 																			 imageMemory,
5866 																			 targetSize,
5867 																			 renderPos,
5868 																			 renderSize,
5869 																			 useFormatCompCount,
5870 																			 1293809,
5871 																			 drawStartNdx,
5872 																			 testConfigExternal.allocationKind,
5873 																			 testConfigExternal.groupParams,
5874 																			 requiredFeatures);
5875 
5876 				addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), checkSupport, createTestShaders, renderPassTest, testConfig);
5877 			}
5878 		}
5879 
5880 		group->addChild(attachmentCountGroup.release());
5881 	}
5882 }
5883 
5884 template<typename T>
chooseRandom(de::Random & rng,const set<T> & values)5885 T chooseRandom (de::Random& rng, const set<T>& values)
5886 {
5887 	size_t							ndx		= ((size_t)rng.getUint32()) % values.size();
5888 	typename set<T>::const_iterator	iter	= values.begin();
5889 
5890 	for (; ndx > 0; ndx--)
5891 		iter++;
5892 
5893 	return *iter;
5894 }
5895 
addAttachmentAllocationTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)5896 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
5897 {
5898 	const deUint32 attachmentCounts[] = { 4, 8 };
5899 	const VkAttachmentLoadOp loadOps[] =
5900 	{
5901 		VK_ATTACHMENT_LOAD_OP_LOAD,
5902 		VK_ATTACHMENT_LOAD_OP_CLEAR,
5903 		VK_ATTACHMENT_LOAD_OP_DONT_CARE
5904 	};
5905 
5906 	const VkAttachmentStoreOp storeOps[] =
5907 	{
5908 		VK_ATTACHMENT_STORE_OP_STORE,
5909 		VK_ATTACHMENT_STORE_OP_DONT_CARE
5910 	};
5911 
5912 	const VkImageLayout initialAndFinalColorLayouts[] =
5913 	{
5914 		VK_IMAGE_LAYOUT_GENERAL,
5915 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5916 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5917 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5918 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5919 	};
5920 
5921 	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
5922 	{
5923 		VK_IMAGE_LAYOUT_GENERAL,
5924 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5925 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
5926 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
5927 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5928 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
5929 	};
5930 
5931 	const VkImageLayout subpassLayoutsColor[] =
5932 	{
5933 		VK_IMAGE_LAYOUT_GENERAL,
5934 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5935 	};
5936 
5937 	const VkImageLayout subpassLayoutsDepthStencil[] =
5938 	{
5939 		VK_IMAGE_LAYOUT_GENERAL,
5940 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5941 	};
5942 
5943 	const VkImageLayout subpassLayoutsInput[] =
5944 	{
5945 		VK_IMAGE_LAYOUT_GENERAL,
5946 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
5947 	};
5948 
5949 	enum AllocationType
5950 	{
5951 		// Each pass uses one more attachmen than previous one
5952 		ALLOCATIONTYPE_GROW,
5953 		// Each pass uses one less attachment than previous one
5954 		ALLOCATIONTYPE_SHRINK,
5955 		// Each pass drops one attachment and picks up new one
5956 		ALLOCATIONTYPE_ROLL,
5957 		// Start by growing and end by shrinking
5958 		ALLOCATIONTYPE_GROW_SHRINK,
5959 		// Each subpass has single input and single output attachment
5960 		ALLOCATIONTYPE_IO_CHAIN,
5961 		// Each subpass has multiple inputs and multiple outputs attachment
5962 		ALLOCATIONTYPE_IO_GENERIC
5963 	};
5964 
5965 	const AllocationType allocationTypes[] =
5966 	{
5967 		ALLOCATIONTYPE_GROW,
5968 		ALLOCATIONTYPE_SHRINK,
5969 		ALLOCATIONTYPE_ROLL,
5970 		ALLOCATIONTYPE_GROW_SHRINK,
5971 		ALLOCATIONTYPE_IO_CHAIN,
5972 		ALLOCATIONTYPE_IO_GENERIC
5973 	};
5974 
5975 	const char* const allocationTypeStr[] =
5976 	{
5977 		"grow",
5978 		"shrink",
5979 		"roll",
5980 		"grow_shrink",
5981 		"input_output_chain",
5982 		"input_output",
5983 	};
5984 
5985 	const TestConfig::RenderTypes renderCommands[] =
5986 	{
5987 		TestConfig::RENDERTYPES_NONE,
5988 		TestConfig::RENDERTYPES_CLEAR,
5989 		TestConfig::RENDERTYPES_DRAW,
5990 		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
5991 	};
5992 
5993 	const TestConfig::CommandBufferTypes commandBuffers[] =
5994 	{
5995 		TestConfig::COMMANDBUFFERTYPES_INLINE,
5996 		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
5997 		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
5998 	};
5999 
6000 	const TestConfig::ImageMemory imageMemories[] =
6001 	{
6002 		TestConfig::IMAGEMEMORY_STRICT,
6003 		TestConfig::IMAGEMEMORY_LAZY,
6004 		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
6005 	};
6006 
6007 	const UVec2 targetSizes[] =
6008 	{
6009 		UVec2(64, 64),
6010 		UVec2(63, 65)
6011 	};
6012 
6013 	const UVec2 renderPositions[] =
6014 	{
6015 		UVec2(0, 0),
6016 		UVec2(3, 17)
6017 	};
6018 
6019 	const UVec2 renderSizes[] =
6020 	{
6021 		UVec2(32, 32),
6022 		UVec2(60, 47)
6023 	};
6024 
6025 	tcu::TestContext&				testCtx	= group->getTestContext();
6026 	de::Random						rng		(3700649827u);
6027 
6028 	for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
6029 	{
6030 		const AllocationType			allocationType		= allocationTypes[allocationTypeNdx];
6031 		const size_t					testCaseCount		= 100;
6032 		de::MovePtr<tcu::TestCaseGroup>	allocationTypeGroup	(new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
6033 
6034 		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
6035 		{
6036 			if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
6037 			{
6038 				const deUint32		attachmentCount	= 4u + rng.getUint32() % 31u;
6039 				const deUint32		subpassCount	= 4u + rng.getUint32() % 31u;
6040 				vector<Attachment>	attachments;
6041 
6042 				set<deUint32>		definedAttachments;
6043 
6044 				vector<Subpass>		subpasses;
6045 				set<deUint32>		colorAttachments;
6046 				set<deUint32>		depthStencilAttachments;
6047 
6048 				for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
6049 				{
6050 					const bool					isDepthStencilAttachment	= rng.getFloat() < 0.01f;
6051 					const VkSampleCountFlagBits	sampleCount					= VK_SAMPLE_COUNT_1_BIT;
6052 					const VkAttachmentLoadOp	loadOp						= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6053 					const VkAttachmentStoreOp	storeOp						= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6054 
6055 					const VkImageLayout			initialLayout				= isDepthStencilAttachment
6056 																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
6057 																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6058 					const VkImageLayout			finalizeLayout				= isDepthStencilAttachment
6059 																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
6060 																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6061 
6062 					const VkAttachmentLoadOp	stencilLoadOp				= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6063 					const VkAttachmentStoreOp	stencilStoreOp				= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6064 
6065 					if (isDepthStencilAttachment)
6066 					{
6067 						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
6068 
6069 						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
6070 							|| stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
6071 							definedAttachments.insert(attachmentIndex);
6072 
6073 						depthStencilAttachments.insert(attachmentIndex);
6074 
6075 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
6076 					}
6077 					else
6078 					{
6079 						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6080 
6081 						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
6082 							definedAttachments.insert(attachmentIndex);
6083 
6084 						colorAttachments.insert(attachmentIndex);
6085 
6086 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
6087 					}
6088 				}
6089 				vector<Maybe<deUint32> >	lastUseOfAttachment	(attachments.size(), tcu::Nothing);
6090 				vector<SubpassDependency>	deps;
6091 
6092 				for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
6093 				{
6094 					const deUint32				colorAttachmentCount		= depthStencilAttachments.empty()
6095 																			? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
6096 																			: rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
6097 					const deUint32				inputAttachmentCount		= rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
6098 					const bool					useDepthStencilAttachment	= !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
6099 					std::vector<deUint32>		subpassColorAttachments		(colorAttachmentCount);
6100 					std::vector<deUint32>		subpassInputAttachments		(inputAttachmentCount);
6101 					Maybe<deUint32>				depthStencilAttachment		(useDepthStencilAttachment
6102 																			? just(chooseRandom(rng, depthStencilAttachments))
6103 																			: tcu::Nothing);
6104 					std::vector<deUint32>		subpassPreserveAttachments;
6105 
6106 					rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
6107 					rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
6108 
6109 					for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
6110 						definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
6111 
6112 					if (depthStencilAttachment)
6113 						definedAttachments.insert(*depthStencilAttachment);
6114 
6115 					{
6116 						std::vector<AttachmentReference>	inputAttachmentReferences;
6117 						std::vector<AttachmentReference>	colorAttachmentReferences;
6118 						AttachmentReference					depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
6119 
6120 						for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
6121 						{
6122 							const deUint32		colorAttachmentIndex	= subpassColorAttachments[colorAttachmentNdx];
6123 
6124 							if (lastUseOfAttachment[colorAttachmentIndex])
6125 							{
6126 								deBool foundDuplicate = false;
6127 
6128 								const deUint32			srcPass			= *lastUseOfAttachment[colorAttachmentIndex];
6129 								const deUint32			dstPass			= subpassIndex;
6130 								const VkDependencyFlags dependencyFlags = rng.getBool() ? (VkDependencyFlags) VK_DEPENDENCY_BY_REGION_BIT : 0u;
6131 
6132 								const SubpassDependency newDependency(srcPass, dstPass,
6133 																	  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6134 																	  | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6135 																	  | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6136 																	  | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6137 
6138 																	  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6139 																	  | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6140 																	  | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6141 																	  | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6142 
6143 																	  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6144 																	  VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
6145 
6146 																	  dependencyFlags);
6147 
6148 								for (SubpassDependency& dependency : deps)
6149 								{
6150 									if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6151 									{
6152 										const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
6153 										dependency.setDstAccessMask(newDstFlags);
6154 										foundDuplicate = true;
6155 										break;
6156 									}
6157 								}
6158 
6159 								if (!foundDuplicate)
6160 								{
6161 									deps.push_back(newDependency);
6162 								}
6163 							}
6164 
6165 							lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
6166 
6167 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL));
6168 						}
6169 
6170 						for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
6171 						{
6172 							const deUint32		inputAttachmentIndex	= subpassInputAttachments[inputAttachmentNdx];
6173 
6174 							if(lastUseOfAttachment[inputAttachmentIndex])
6175 							{
6176 								deBool foundDuplicate = false;
6177 
6178 								const deUint32			srcPass			= *lastUseOfAttachment[inputAttachmentIndex];
6179 								const deUint32			dstPass			= subpassIndex;
6180 								const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
6181 
6182 								const SubpassDependency newDependency(srcPass, dstPass,
6183 																	  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6184 																	  | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6185 																	  | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6186 																	  | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6187 
6188 																	  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6189 																	  | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6190 																	  | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6191 																	  | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6192 
6193 																	  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6194 																	  VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6195 
6196 																	  dependencyFlags);
6197 								for (SubpassDependency& dependency : deps)
6198 								{
6199 									if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6200 									{
6201 										const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6202 										const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6203 										dependency.setDstAccessMask(newSrcFlags);
6204 										dependency.setDstAccessMask(newDstFlags);
6205 										foundDuplicate = true;
6206 										break;
6207 									}
6208 								}
6209 
6210 								if (!foundDuplicate)
6211 								{
6212 									deps.push_back(newDependency);
6213 								}
6214 
6215 								lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
6216 
6217 								VkImageAspectFlags aspect = 0u;
6218 								if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
6219 								{
6220 									bool col = colorAttachments.find(inputAttachmentIndex) != colorAttachments.end();
6221 									aspect = col ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
6222 								}
6223 								inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL, aspect));
6224 							}
6225 						}
6226 
6227 						if (depthStencilAttachment)
6228 						{
6229 							if (lastUseOfAttachment[*depthStencilAttachment])
6230 							{
6231 								deBool foundDuplicate = false;
6232 
6233 								const deUint32			srcPass			= *lastUseOfAttachment[*depthStencilAttachment];
6234 								const deUint32			dstPass			= subpassIndex;
6235 								const VkDependencyFlags dependencyFlags = ((srcPass == subpassIndex) || rng.getBool()) ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;
6236 
6237 								const SubpassDependency newDependency(srcPass, dstPass,
6238 																	  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6239 																	  | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6240 																	  | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6241 																	  | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6242 
6243 																	  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6244 																	  | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6245 																	  | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6246 																	  | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6247 
6248 																	  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6249 																	  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
6250 																	  | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6251 
6252 																	  dependencyFlags);
6253 								for (SubpassDependency& dependency : deps)
6254 								{
6255 									if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
6256 									{
6257 										const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
6258 										const VkAccessFlags newDstFlags = dependency.getDstAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
6259 										dependency.setDstAccessMask(newSrcFlags);
6260 										dependency.setDstAccessMask(newDstFlags);
6261 										foundDuplicate = true;
6262 										break;
6263 									}
6264 								}
6265 
6266 								if (!foundDuplicate)
6267 								{
6268 									deps.push_back(newDependency);
6269 								}
6270 							}
6271 
6272 							lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
6273 
6274 							depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
6275 						}
6276 						else
6277 							depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
6278 
6279 						vector<deUint32>	preserveAttachments;
6280 						for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
6281 						{
6282 							if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
6283 								preserveAttachments.push_back(attachmentIndex);
6284 						}
6285 
6286 						// Use random image layout when possible
6287 						for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6288 						{
6289 							bool usedAsInput = false;
6290 							for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6291 								if (colorAttachmentReferences[colorRefIdx].getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
6292 									usedAsInput = true;
6293 
6294 							if (!usedAsInput)
6295 								colorAttachmentReferences[colorRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)));
6296 						}
6297 						for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6298 						{
6299 							bool usedAsDepthStencil	= inputAttachmentReferences[inputRefIdx].getAttachment() == depthStencilAttachmentReference.getAttachment();
6300 							bool usedAsColor		= false;
6301 							for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
6302 								if (inputAttachmentReferences[inputRefIdx].getAttachment() == colorAttachmentReferences[colorRefIdx].getAttachment())
6303 									usedAsColor = true;
6304 
6305 							if (!usedAsColor && !usedAsDepthStencil)
6306 								inputAttachmentReferences[inputRefIdx].setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsInput), DE_ARRAY_END(subpassLayoutsInput)));
6307 						}
6308 						{
6309 							bool usedAsInput = false;
6310 							for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
6311 								if (depthStencilAttachmentReference.getAttachment() == inputAttachmentReferences[inputRefIdx].getAttachment())
6312 									usedAsInput = true;
6313 
6314 							if (!usedAsInput)
6315 								depthStencilAttachmentReference.setImageLayout(rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsDepthStencil), DE_ARRAY_END(subpassLayoutsDepthStencil)));
6316 						}
6317 
6318 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6319 												inputAttachmentReferences,
6320 												colorAttachmentReferences,
6321 												vector<AttachmentReference>(),
6322 												depthStencilAttachmentReference,
6323 												preserveAttachments));
6324 					}
6325 				}
6326 				{
6327 					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6328 					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6329 					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6330 
6331 					const string							testCaseName	= de::toString(testCaseNdx);
6332 					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6333 					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6334 					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6335 
6336 					const RenderPass						renderPass		(attachments, subpasses, deps);
6337 					const TestConfig						testConfig		(renderPass,
6338 																			 render,
6339 																			 commandBuffer,
6340 																			 imageMemory,
6341 																			 targetSize,
6342 																			 renderPos,
6343 																			 renderSize,
6344 																			 DE_FALSE,
6345 																			 80329,
6346 																			 0,
6347 																			 testConfigExternal.allocationKind,
6348 																			 testConfigExternal.groupParams);
6349 
6350 					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
6351 				}
6352 			}
6353 			else
6354 			{
6355 				const deUint32		attachmentCount	= rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
6356 				vector<Attachment>	attachments;
6357 				vector<Subpass>		subpasses;
6358 
6359 				for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
6360 				{
6361 					const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
6362 					const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
6363 					const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6364 					const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6365 
6366 					const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6367 					const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
6368 
6369 					const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
6370 					const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
6371 
6372 					attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
6373 				}
6374 
6375 				if (allocationType == ALLOCATIONTYPE_GROW)
6376 				{
6377 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6378 					{
6379 						vector<AttachmentReference>	colorAttachmentReferences;
6380 
6381 						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
6382 						{
6383 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6384 
6385 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6386 						}
6387 
6388 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6389 												vector<AttachmentReference>(),
6390 												colorAttachmentReferences,
6391 												vector<AttachmentReference>(),
6392 												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6393 												vector<deUint32>()));
6394 					}
6395 				}
6396 				else if (allocationType == ALLOCATIONTYPE_SHRINK)
6397 				{
6398 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6399 					{
6400 						vector<AttachmentReference>	colorAttachmentReferences;
6401 
6402 						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
6403 						{
6404 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6405 
6406 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6407 						}
6408 
6409 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6410 													vector<AttachmentReference>(),
6411 													colorAttachmentReferences,
6412 													vector<AttachmentReference>(),
6413 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6414 													vector<deUint32>()));
6415 					}
6416 				}
6417 				else if (allocationType == ALLOCATIONTYPE_ROLL)
6418 				{
6419 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
6420 					{
6421 						vector<AttachmentReference>	colorAttachmentReferences;
6422 
6423 						for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
6424 						{
6425 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6426 
6427 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
6428 						}
6429 
6430 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6431 													vector<AttachmentReference>(),
6432 													colorAttachmentReferences,
6433 													vector<AttachmentReference>(),
6434 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6435 													vector<deUint32>()));
6436 					}
6437 				}
6438 				else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
6439 				{
6440 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6441 					{
6442 						vector<AttachmentReference>	colorAttachmentReferences;
6443 
6444 						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
6445 						{
6446 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6447 
6448 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6449 						}
6450 
6451 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6452 													vector<AttachmentReference>(),
6453 													colorAttachmentReferences,
6454 													vector<AttachmentReference>(),
6455 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6456 													vector<deUint32>()));
6457 					}
6458 					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
6459 					{
6460 						vector<AttachmentReference>	colorAttachmentReferences;
6461 
6462 						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
6463 						{
6464 							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));
6465 
6466 							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
6467 						}
6468 
6469 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6470 													vector<AttachmentReference>(),
6471 													colorAttachmentReferences,
6472 													vector<AttachmentReference>(),
6473 													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6474 													vector<deUint32>()));
6475 					}
6476 				}
6477 				else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
6478 				{
6479 					subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6480 											vector<AttachmentReference>(),
6481 											vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
6482 											vector<AttachmentReference>(),
6483 											AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6484 											vector<deUint32>()));
6485 
6486 					for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
6487 					{
6488 						const VkImageAspectFlags inputAttachmentAspectMask = (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ? VK_IMAGE_ASPECT_COLOR_BIT : static_cast<VkImageAspectFlagBits>(0);
6489 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
6490 												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
6491 												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)))),
6492 												vector<AttachmentReference>(),
6493 												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6494 												vector<deUint32>()));
6495 					}
6496 				}
6497 				else
6498 					DE_FATAL("Unknown allocation type");
6499 
6500 				{
6501 					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
6502 					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
6503 					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
6504 
6505 					const string							testCaseName	= de::toString(testCaseNdx);
6506 					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
6507 					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
6508 					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
6509 
6510 					vector<SubpassDependency>				deps;
6511 
6512 					for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
6513 					{
6514 						const bool byRegion				= rng.getBool();
6515 						deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
6516 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6517 															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6518 															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6519 															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6520 
6521 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
6522 															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
6523 															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
6524 															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6525 
6526 														 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6527 														 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT),
6528 
6529 														 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
6530 					}
6531 
6532 					const RenderPass					renderPass		(attachments, subpasses, deps);
6533 					const TestConfig					testConfig		(renderPass,
6534 																		 render,
6535 																		 commandBuffer,
6536 																		 imageMemory,
6537 																		 targetSize,
6538 																		 renderPos,
6539 																		 renderSize,
6540 																		 DE_FALSE,
6541 																		 80329,
6542 																		 0,
6543 																		 testConfigExternal.allocationKind,
6544 																		 testConfigExternal.groupParams);
6545 
6546 					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, testConfig);
6547 				}
6548 			}
6549 		}
6550 		group->addChild(allocationTypeGroup.release());
6551 	}
6552 }
6553 
addSimpleTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)6554 void addSimpleTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
6555 {
6556 	const UVec2	targetSize	(64, 64);
6557 	const UVec2	renderPos	(0, 0);
6558 	const UVec2	renderSize	(64, 64);
6559 
6560 	// color
6561 	{
6562 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6563 																		  VK_SAMPLE_COUNT_1_BIT,
6564 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
6565 																		  VK_ATTACHMENT_STORE_OP_STORE,
6566 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6567 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6568 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6569 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6570 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6571 																	0u,
6572 																	vector<AttachmentReference>(),
6573 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6574 																	vector<AttachmentReference>(),
6575 																	AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6576 																	vector<deUint32>())),
6577 										 vector<SubpassDependency>());
6578 		const TestConfig	testConfig	(renderPass,
6579 										 TestConfig::RENDERTYPES_DRAW,
6580 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6581 										 TestConfig::IMAGEMEMORY_STRICT,
6582 										 targetSize,
6583 										 renderPos,
6584 										 renderSize,
6585 										 DE_FALSE,
6586 										 90239,
6587 										 0,
6588 										 testConfigExternal.allocationKind,
6589 										 testConfigExternal.groupParams);
6590 
6591 		addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, testConfig);
6592 	}
6593 
6594 	// depth
6595 	{
6596 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
6597 																		  VK_SAMPLE_COUNT_1_BIT,
6598 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
6599 																		  VK_ATTACHMENT_STORE_OP_STORE,
6600 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6601 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6602 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6603 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6604 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6605 																	0u,
6606 																	vector<AttachmentReference>(),
6607 																	vector<AttachmentReference>(),
6608 																	vector<AttachmentReference>(),
6609 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6610 																	vector<deUint32>())),
6611 										 vector<SubpassDependency>());
6612 		const TestConfig	testConfig	(renderPass,
6613 										 TestConfig::RENDERTYPES_DRAW,
6614 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6615 										 TestConfig::IMAGEMEMORY_STRICT,
6616 										 targetSize,
6617 										 renderPos,
6618 										 renderSize,
6619 										 DE_FALSE,
6620 										 90239,
6621 										 0,
6622 										 testConfigExternal.allocationKind,
6623 										 testConfigExternal.groupParams);
6624 
6625 		addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, testConfig);
6626 	}
6627 
6628 	// stencil
6629 	{
6630 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
6631 																		  VK_SAMPLE_COUNT_1_BIT,
6632 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6633 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6634 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
6635 																		  VK_ATTACHMENT_STORE_OP_STORE,
6636 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6637 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6638 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6639 																	0u,
6640 																	vector<AttachmentReference>(),
6641 																	vector<AttachmentReference>(),
6642 																	vector<AttachmentReference>(),
6643 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6644 																	vector<deUint32>())),
6645 										 vector<SubpassDependency>());
6646 		const TestConfig	testConfig	(renderPass,
6647 										 TestConfig::RENDERTYPES_DRAW,
6648 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6649 										 TestConfig::IMAGEMEMORY_STRICT,
6650 										 targetSize,
6651 										 renderPos,
6652 										 renderSize,
6653 										 DE_FALSE,
6654 										 90239,
6655 										 0,
6656 										 testConfigExternal.allocationKind,
6657 										 testConfigExternal.groupParams);
6658 
6659 		addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6660 	}
6661 
6662 	// depth_stencil
6663 	{
6664 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
6665 																		  VK_SAMPLE_COUNT_1_BIT,
6666 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
6667 																		  VK_ATTACHMENT_STORE_OP_STORE,
6668 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
6669 																		  VK_ATTACHMENT_STORE_OP_STORE,
6670 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6671 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
6672 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6673 																	0u,
6674 																	vector<AttachmentReference>(),
6675 																	vector<AttachmentReference>(),
6676 																	vector<AttachmentReference>(),
6677 																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6678 																	vector<deUint32>())),
6679 										 vector<SubpassDependency>());
6680 		const TestConfig	testConfig	(renderPass,
6681 										 TestConfig::RENDERTYPES_DRAW,
6682 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6683 										 TestConfig::IMAGEMEMORY_STRICT,
6684 										 targetSize,
6685 										 renderPos,
6686 										 renderSize,
6687 										 DE_FALSE,
6688 										 90239,
6689 										 0,
6690 										 testConfigExternal.allocationKind,
6691 										 testConfigExternal.groupParams);
6692 
6693 		addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6694 	}
6695 
6696 	// color_depth
6697 	{
6698 		const Attachment	attachments[] =
6699 		{
6700 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6701 					   VK_SAMPLE_COUNT_1_BIT,
6702 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
6703 					   VK_ATTACHMENT_STORE_OP_STORE,
6704 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6705 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6706 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6707 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6708 			Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
6709 					   VK_SAMPLE_COUNT_1_BIT,
6710 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
6711 					   VK_ATTACHMENT_STORE_OP_STORE,
6712 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6713 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6714 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6715 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6716 		};
6717 
6718 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6719 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6720 																	0u,
6721 																	vector<AttachmentReference>(),
6722 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6723 																	vector<AttachmentReference>(),
6724 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6725 																	vector<deUint32>())),
6726 										 vector<SubpassDependency>());
6727 		const TestConfig	testConfig	(renderPass,
6728 										 TestConfig::RENDERTYPES_DRAW,
6729 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6730 										 TestConfig::IMAGEMEMORY_STRICT,
6731 										 targetSize,
6732 										 renderPos,
6733 										 renderSize,
6734 										 DE_FALSE,
6735 										 90239,
6736 										 0,
6737 										 testConfigExternal.allocationKind,
6738 										 testConfigExternal.groupParams);
6739 
6740 		addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, testConfig);
6741 	}
6742 
6743 	// color_stencil
6744 	{
6745 		const Attachment	attachments[] =
6746 		{
6747 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6748 					   VK_SAMPLE_COUNT_1_BIT,
6749 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
6750 					   VK_ATTACHMENT_STORE_OP_STORE,
6751 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6752 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6753 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6754 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6755 			Attachment(VK_FORMAT_S8_UINT,
6756 					   VK_SAMPLE_COUNT_1_BIT,
6757 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6758 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6759 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
6760 					   VK_ATTACHMENT_STORE_OP_STORE,
6761 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6762 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6763 		};
6764 
6765 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6766 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6767 																	0u,
6768 																	vector<AttachmentReference>(),
6769 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6770 																	vector<AttachmentReference>(),
6771 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6772 																	vector<deUint32>())),
6773 										 vector<SubpassDependency>());
6774 		const TestConfig	testConfig	(renderPass,
6775 										 TestConfig::RENDERTYPES_DRAW,
6776 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6777 										 TestConfig::IMAGEMEMORY_STRICT,
6778 										 targetSize,
6779 										 renderPos,
6780 										 renderSize,
6781 										 DE_FALSE,
6782 										 90239,
6783 										 0,
6784 										 testConfigExternal.allocationKind,
6785 										 testConfigExternal.groupParams);
6786 
6787 		addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6788 	}
6789 
6790 	// color_depth_stencil
6791 	{
6792 		const Attachment	attachments[] =
6793 		{
6794 			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6795 					   VK_SAMPLE_COUNT_1_BIT,
6796 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
6797 					   VK_ATTACHMENT_STORE_OP_STORE,
6798 					   VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6799 					   VK_ATTACHMENT_STORE_OP_DONT_CARE,
6800 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6801 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
6802 			Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
6803 					   VK_SAMPLE_COUNT_1_BIT,
6804 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
6805 					   VK_ATTACHMENT_STORE_OP_STORE,
6806 					   VK_ATTACHMENT_LOAD_OP_CLEAR,
6807 					   VK_ATTACHMENT_STORE_OP_STORE,
6808 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6809 					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6810 		};
6811 
6812 		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
6813 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6814 																	0u,
6815 																	vector<AttachmentReference>(),
6816 																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6817 																	vector<AttachmentReference>(),
6818 																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6819 																	vector<deUint32>())),
6820 										 vector<SubpassDependency>());
6821 		const TestConfig	testConfig	(renderPass,
6822 										 TestConfig::RENDERTYPES_DRAW,
6823 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6824 										 TestConfig::IMAGEMEMORY_STRICT,
6825 										 targetSize,
6826 										 renderPos,
6827 										 renderSize,
6828 										 DE_FALSE,
6829 										 90239,
6830 										 0,
6831 										 testConfigExternal.allocationKind,
6832 										 testConfigExternal.groupParams);
6833 
6834 		addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, testConfig);
6835 	}
6836 
6837 	// no attachments
6838 	{
6839 		const RenderPass	renderPass	(vector<Attachment>(),
6840 										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6841 																	0u,
6842 																	vector<AttachmentReference>(),
6843 																	vector<AttachmentReference>(),
6844 																	vector<AttachmentReference>(),
6845 																	AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6846 																	vector<deUint32>())),
6847 										vector<SubpassDependency>());
6848 		const TestConfig	testConfig	(renderPass,
6849 										 TestConfig::RENDERTYPES_DRAW,
6850 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6851 										 TestConfig::IMAGEMEMORY_STRICT,
6852 										 targetSize,
6853 										 renderPos,
6854 										 renderSize,
6855 										 DE_FALSE,
6856 										 90239,
6857 										 0,
6858 										 testConfigExternal.allocationKind,
6859 										 testConfigExternal.groupParams);
6860 
6861 		addFunctionCaseWithPrograms<TestConfig>(group, "no_attachments", "No attachments case.", createTestShaders, renderPassTest, testConfig);
6862 	}
6863 
6864 	// color_unused_omit_blend_state
6865 	if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
6866 	{
6867 		vector<Subpass>		subpasses;
6868 
6869 		// First subpass: use color attachment, create pipeline with color blend state
6870 		subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6871 									0u,
6872 									vector<AttachmentReference>(),
6873 									vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6874 									vector<AttachmentReference>(),
6875 									AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6876 									vector<deUint32>(),
6877 									false));
6878 
6879 		// Second subpass: don't use color attachment, create pipeline without color blend state
6880 		subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6881 									0u,
6882 									vector<AttachmentReference>(),
6883 									vector<AttachmentReference>(1, AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6884 									vector<AttachmentReference>(),
6885 									AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6886 									vector<deUint32>(),
6887 									true));
6888 
6889 		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
6890 																		  VK_SAMPLE_COUNT_1_BIT,
6891 																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
6892 																		  VK_ATTACHMENT_STORE_OP_STORE,
6893 																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6894 																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6895 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6896 																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6897 										 subpasses,
6898 										 vector<SubpassDependency>());
6899 
6900 		const TestConfig	testConfig	(renderPass,
6901 										 TestConfig::RENDERTYPES_DRAW,
6902 										 TestConfig::COMMANDBUFFERTYPES_INLINE,
6903 										 TestConfig::IMAGEMEMORY_STRICT,
6904 										 targetSize,
6905 										 renderPos,
6906 										 renderSize,
6907 										 DE_FALSE,
6908 										 90239,
6909 										 0,
6910 										 testConfigExternal.allocationKind,
6911 										 testConfigExternal.groupParams);
6912 		addFunctionCaseWithPrograms<TestConfig>(group, "color_unused_omit_blend_state", "Two unused color attachment case without blend state", createTestShaders, renderPassTest, testConfig);
6913 	}
6914 }
6915 
formatToName(VkFormat format)6916 std::string formatToName (VkFormat format)
6917 {
6918 	const std::string	formatStr	= de::toString(format);
6919 	const std::string	prefix		= "VK_FORMAT_";
6920 
6921 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
6922 
6923 	return de::toLower(formatStr.substr(prefix.length()));
6924 }
6925 
addFormatTests(tcu::TestCaseGroup * group,const TestConfigExternal testConfigExternal)6926 void addFormatTests (tcu::TestCaseGroup* group, const TestConfigExternal testConfigExternal)
6927 {
6928 	tcu::TestContext&	testCtx		= group->getTestContext();
6929 
6930 	const UVec2			targetSize	(64, 64);
6931 	const UVec2			renderPos	(0, 0);
6932 	const UVec2			renderSize	(64, 64);
6933 
6934 	const struct
6935 	{
6936 		const char* const			str;
6937 		const VkAttachmentStoreOp	op;
6938 	} storeOps[] =
6939 	{
6940 		{ "store",		VK_ATTACHMENT_STORE_OP_STORE		},
6941 		{ "dont_care",	VK_ATTACHMENT_STORE_OP_DONT_CARE	}
6942 	};
6943 
6944 	const struct
6945 	{
6946 		const char* const			str;
6947 		const VkAttachmentLoadOp	op;
6948 	} loadOps[] =
6949 	{
6950 		{ "clear",		VK_ATTACHMENT_LOAD_OP_CLEAR		},
6951 		{ "load",		VK_ATTACHMENT_LOAD_OP_LOAD		},
6952 		{ "dont_care",	VK_ATTACHMENT_LOAD_OP_DONT_CARE	}
6953 	};
6954 
6955 	const struct
6956 	{
6957 		 const char* const				str;
6958 		 const TestConfig::RenderTypes	types;
6959 	} renderTypes[] =
6960 	{
6961 		{ "clear",		TestConfig::RENDERTYPES_CLEAR								},
6962 		{ "draw",		TestConfig::RENDERTYPES_DRAW								},
6963 		{ "clear_draw",	TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW	}
6964 	};
6965 
6966 	// Color formats
6967 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
6968 	{
6969 		const VkFormat					format		= s_coreColorFormats[formatNdx];
6970 		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
6971 
6972 		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
6973 		{
6974 			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
6975 			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
6976 
6977 			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
6978 			{
6979 				const RenderPass	renderPass	(vector<Attachment>(1, Attachment(format,
6980 																				  VK_SAMPLE_COUNT_1_BIT,
6981 																				  loadOp,
6982 																				  VK_ATTACHMENT_STORE_OP_STORE,
6983 																				  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6984 																				  VK_ATTACHMENT_STORE_OP_DONT_CARE,
6985 																				  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6986 																				  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6987 												 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6988 																			0u,
6989 																			vector<AttachmentReference>(),
6990 																			vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6991 																			vector<AttachmentReference>(),
6992 																			AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6993 																			vector<deUint32>())),
6994 												 vector<SubpassDependency>());
6995 				const TestConfig	testConfig	(renderPass,
6996 												 renderTypes[renderTypeNdx].types,
6997 												 TestConfig::COMMANDBUFFERTYPES_INLINE,
6998 												 TestConfig::IMAGEMEMORY_STRICT,
6999 												 targetSize,
7000 												 renderPos,
7001 												 renderSize,
7002 												 DE_FALSE,
7003 												 90239,
7004 												 0,
7005 												 testConfigExternal.allocationKind,
7006 												 testConfigExternal.groupParams);
7007 
7008 				addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7009 			}
7010 
7011 			formatGroup->addChild(loadOpGroup.release());
7012 		}
7013 
7014 		if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7015 		{
7016 			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
7017 
7018 			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7019 			{
7020 				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
7021 				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7022 
7023 				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
7024 				{
7025 					const VkImageAspectFlags		inputAttachmentAspectMask	= (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
7026 																				? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
7027 																				: static_cast<VkImageAspectFlags>(0);
7028 					const VkAttachmentStoreOp		storeOp						= storeOps[storeOpNdx].op;
7029 					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup				(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
7030 
7031 					for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
7032 					{
7033 						const bool useInputAspect = useInputAspectNdx != 0;
7034 
7035 						if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2 && useInputAspect)
7036 							continue;
7037 
7038 						for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7039 						{
7040 							{
7041 								vector<Attachment>							attachments;
7042 								vector<Subpass>								subpasses;
7043 								vector<SubpassDependency>					deps;
7044 								vector<VkInputAttachmentAspectReference>	inputAspects;
7045 
7046 								attachments.push_back(Attachment(format,
7047 																 VK_SAMPLE_COUNT_1_BIT,
7048 																 loadOp,
7049 																 storeOp,
7050 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7051 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7052 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7053 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7054 
7055 								attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7056 																 VK_SAMPLE_COUNT_1_BIT,
7057 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7058 																 VK_ATTACHMENT_STORE_OP_STORE,
7059 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7060 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7061 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7062 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7063 
7064 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7065 															0u,
7066 															vector<AttachmentReference>(),
7067 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7068 															vector<AttachmentReference>(),
7069 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7070 															vector<deUint32>()));
7071 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7072 															0u,
7073 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7074 															vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7075 															vector<AttachmentReference>(),
7076 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7077 															vector<deUint32>()));
7078 
7079 								deps.push_back(SubpassDependency(0, 1,
7080 
7081 																vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7082 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7083 
7084 																vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7085 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7086 																vk::VK_DEPENDENCY_BY_REGION_BIT));
7087 
7088 								if (useInputAspect)
7089 								{
7090 									const VkInputAttachmentAspectReference inputAspect =
7091 									{
7092 										1u,
7093 										0u,
7094 										VK_IMAGE_ASPECT_COLOR_BIT
7095 									};
7096 
7097 									inputAspects.push_back(inputAspect);
7098 								}
7099 
7100 								{
7101 									const RenderPass	renderPass	(attachments, subpasses, deps, inputAspects);
7102 									const TestConfig	testConfig	(renderPass,
7103 																	 renderTypes[renderTypeNdx].types,
7104 																	 TestConfig::COMMANDBUFFERTYPES_INLINE,
7105 																	 TestConfig::IMAGEMEMORY_STRICT,
7106 																	 targetSize,
7107 																	 renderPos,
7108 																	 renderSize,
7109 																	 DE_FALSE,
7110 																	 89246,
7111 																	 0,
7112 																	 testConfigExternal.allocationKind,
7113 																	 testConfigExternal.groupParams);
7114 									const string		testName	(renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
7115 
7116 									addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7117 								}
7118 							}
7119 							{
7120 								vector<Attachment>							attachments;
7121 								vector<Subpass>								subpasses;
7122 								vector<SubpassDependency>					deps;
7123 								vector<VkInputAttachmentAspectReference>	inputAspects;
7124 
7125 								attachments.push_back(Attachment(format,
7126 																 VK_SAMPLE_COUNT_1_BIT,
7127 																 loadOp,
7128 																 storeOp,
7129 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7130 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7131 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7132 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7133 
7134 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7135 															0u,
7136 															vector<AttachmentReference>(),
7137 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7138 															vector<AttachmentReference>(),
7139 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7140 															vector<deUint32>()));
7141 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7142 															0u,
7143 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
7144 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
7145 															vector<AttachmentReference>(),
7146 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7147 															vector<deUint32>()));
7148 
7149 								deps.push_back(SubpassDependency(0, 1,
7150 																vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7151 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7152 
7153 																vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7154 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7155 																vk::VK_DEPENDENCY_BY_REGION_BIT));
7156 
7157 								deps.push_back(SubpassDependency(1, 1,
7158 																vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7159 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7160 
7161 																vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7162 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7163 																vk::VK_DEPENDENCY_BY_REGION_BIT));
7164 
7165 								if (useInputAspect)
7166 								{
7167 									const VkInputAttachmentAspectReference inputAspect =
7168 									{
7169 										1u,
7170 										0u,
7171 										VK_IMAGE_ASPECT_COLOR_BIT
7172 									};
7173 
7174 									inputAspects.push_back(inputAspect);
7175 								}
7176 
7177 								{
7178 									const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
7179 									const TestConfig testConfig (renderPass,
7180 																 renderTypes[renderTypeNdx].types,
7181 																 TestConfig::COMMANDBUFFERTYPES_INLINE,
7182 																 TestConfig::IMAGEMEMORY_STRICT,
7183 																 targetSize,
7184 																 renderPos,
7185 																 renderSize,
7186 																 DE_FALSE,
7187 																 89246,
7188 																 0,
7189 																 testConfigExternal.allocationKind,
7190 																 testConfigExternal.groupParams);
7191 									const string	testName	(string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
7192 
7193 									addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7194 								}
7195 							}
7196 						}
7197 					}
7198 
7199 					loadOpGroup->addChild(storeOpGroup.release());
7200 				}
7201 
7202 				inputGroup->addChild(loadOpGroup.release());
7203 			}
7204 
7205 			formatGroup->addChild(inputGroup.release());
7206 		}
7207 
7208 		group->addChild(formatGroup.release());
7209 	}
7210 
7211 	// Depth stencil formats
7212 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
7213 	{
7214 		const VkFormat					vkFormat			= s_coreDepthStencilFormats[formatNdx];
7215 		const tcu::TextureFormat		format				= mapVkFormat(vkFormat);
7216 		const bool						isStencilAttachment	= hasStencilComponent(format.order);
7217 		const bool						isDepthAttachment	= hasDepthComponent(format.order);
7218 		const VkImageAspectFlags		formatAspectFlags	= (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7219 															| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u);
7220 		de::MovePtr<tcu::TestCaseGroup>	formatGroup			(new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
7221 
7222 		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7223 		{
7224 			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
7225 			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7226 
7227 			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7228 			{
7229 				{
7230 					const RenderPass	renderPass	(vector<Attachment>(1, Attachment(vkFormat,
7231 																					  VK_SAMPLE_COUNT_1_BIT,
7232 																					  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7233 																					  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7234 																					  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7235 																					  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7236 																					  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7237 																					  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7238 													 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7239 																				0u,
7240 																				vector<AttachmentReference>(),
7241 																				vector<AttachmentReference>(),
7242 																				vector<AttachmentReference>(),
7243 																				AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7244 																				vector<deUint32>())),
7245 													 vector<SubpassDependency>());
7246 					const TestConfig	testConfig	(renderPass,
7247 													 renderTypes[renderTypeNdx].types,
7248 													 TestConfig::COMMANDBUFFERTYPES_INLINE,
7249 													 TestConfig::IMAGEMEMORY_STRICT,
7250 													 targetSize,
7251 													 renderPos,
7252 													 renderSize,
7253 													 DE_FALSE,
7254 													 90239,
7255 													 0,
7256 													 testConfigExternal.allocationKind,
7257 													 testConfigExternal.groupParams);
7258 
7259 					addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7260 				}
7261 
7262 				if (isStencilAttachment && isDepthAttachment && loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
7263 				{
7264 					{
7265 						const RenderPass	renderPass	(vector<Attachment>(1, Attachment(vkFormat,
7266 																				  VK_SAMPLE_COUNT_1_BIT,
7267 																				  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7268 																				  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7269 																				  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7270 																				  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7271 																				  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7272 																				  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7273 														 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7274 																					0u,
7275 																					vector<AttachmentReference>(),
7276 																					vector<AttachmentReference>(),
7277 																					vector<AttachmentReference>(),
7278 																					AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
7279 																					vector<deUint32>())),
7280 														 vector<SubpassDependency>());
7281 						const TestConfig	testConfig	(renderPass,
7282 														 renderTypes[renderTypeNdx].types,
7283 														 TestConfig::COMMANDBUFFERTYPES_INLINE,
7284 														 TestConfig::IMAGEMEMORY_STRICT,
7285 														 targetSize,
7286 														 renderPos,
7287 														 renderSize,
7288 														 DE_FALSE,
7289 														 90239,
7290 														 0,
7291 														 testConfigExternal.allocationKind,
7292 														 testConfigExternal.groupParams);
7293 						const string		testName	(string(renderTypes[renderTypeNdx].str) + "_depth_read_only");
7294 
7295 						addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7296 					}
7297 
7298 					{
7299 						const RenderPass	renderPass	(vector<Attachment>(1, Attachment(vkFormat,
7300 																		  VK_SAMPLE_COUNT_1_BIT,
7301 																		  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7302 																		  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7303 																		  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7304 																		  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
7305 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7306 																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
7307 														 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7308 																					0u,
7309 																					vector<AttachmentReference>(),
7310 																					vector<AttachmentReference>(),
7311 																					vector<AttachmentReference>(),
7312 																					AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7313 																					vector<deUint32>())),
7314 														 vector<SubpassDependency>());
7315 						const TestConfig	testConfig	(renderPass,
7316 														 renderTypes[renderTypeNdx].types,
7317 														 TestConfig::COMMANDBUFFERTYPES_INLINE,
7318 														 TestConfig::IMAGEMEMORY_STRICT,
7319 														 targetSize,
7320 														 renderPos,
7321 														 renderSize,
7322 														 DE_FALSE,
7323 														 90239,
7324 														 0,
7325 														 testConfigExternal.allocationKind,
7326 														 testConfigExternal.groupParams);
7327 						const string		testName	(string(renderTypes[renderTypeNdx].str) + "_stencil_read_only");
7328 
7329 						addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7330 					}
7331 				}
7332 			}
7333 
7334 			formatGroup->addChild(loadOpGroup.release());
7335 		}
7336 
7337 		if (testConfigExternal.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7338 		{
7339 			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
7340 
7341 			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
7342 			{
7343 				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
7344 				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
7345 
7346 				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
7347 				{
7348 					const VkImageAspectFlags		inputAttachmentAspectMask	= (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
7349 																				? formatAspectFlags
7350 																				: static_cast<VkImageAspectFlags>(0);
7351 					const VkAttachmentStoreOp		storeOp						= storeOps[storeOpNdx].op;
7352 					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup				(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
7353 
7354 					for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
7355 					{
7356 						const bool useInputAspect = useInputAspectNdx != 0;
7357 
7358 						if (testConfigExternal.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2 && useInputAspect)
7359 							continue;
7360 
7361 						for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
7362 						{
7363 							{
7364 								vector<Attachment>							attachments;
7365 								vector<Subpass>								subpasses;
7366 								vector<SubpassDependency>					deps;
7367 								vector<VkInputAttachmentAspectReference>	inputAspects;
7368 
7369 								attachments.push_back(Attachment(vkFormat,
7370 																 VK_SAMPLE_COUNT_1_BIT,
7371 																 loadOp,
7372 																 storeOp,
7373 																 loadOp,
7374 																 storeOp,
7375 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7376 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7377 
7378 								attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7379 																 VK_SAMPLE_COUNT_1_BIT,
7380 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7381 																 VK_ATTACHMENT_STORE_OP_STORE,
7382 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7383 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7384 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7385 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7386 
7387 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7388 															0u,
7389 															vector<AttachmentReference>(),
7390 															vector<AttachmentReference>(),
7391 															vector<AttachmentReference>(),
7392 															AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7393 															vector<deUint32>()));
7394 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7395 															0u,
7396 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7397 															vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7398 															vector<AttachmentReference>(),
7399 															AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7400 															vector<deUint32>()));
7401 
7402 								deps.push_back(SubpassDependency(0, 1,
7403 																vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7404 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7405 
7406 																vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7407 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7408 																0u));
7409 
7410 								if (useInputAspect)
7411 								{
7412 									const VkInputAttachmentAspectReference inputAspect =
7413 									{
7414 										1u,
7415 										0u,
7416 										(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7417 											| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7418 									};
7419 
7420 									inputAspects.push_back(inputAspect);
7421 								}
7422 
7423 								{
7424 									const RenderPass	renderPass	(attachments, subpasses, deps, inputAspects);
7425 									const TestConfig	testConfig	(renderPass,
7426 																	 renderTypes[renderTypeNdx].types,
7427 																	 TestConfig::COMMANDBUFFERTYPES_INLINE,
7428 																	 TestConfig::IMAGEMEMORY_STRICT,
7429 																	 targetSize,
7430 																	 renderPos,
7431 																	 renderSize,
7432 																	 DE_FALSE,
7433 																	 89246,
7434 																	 0,
7435 																	 testConfigExternal.allocationKind,
7436 																	 testConfigExternal.groupParams);
7437 									const string		testName	(renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""));
7438 
7439 									addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7440 								}
7441 							}
7442 							{
7443 								vector<Attachment>							attachments;
7444 								vector<Subpass>								subpasses;
7445 								vector<SubpassDependency>					deps;
7446 								vector<VkInputAttachmentAspectReference>	inputAspects;
7447 
7448 								attachments.push_back(Attachment(vkFormat,
7449 																 VK_SAMPLE_COUNT_1_BIT,
7450 																 loadOp,
7451 																 storeOp,
7452 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7453 																 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7454 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7455 																 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7456 
7457 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7458 															0u,
7459 															vector<AttachmentReference>(),
7460 															vector<AttachmentReference>(),
7461 															vector<AttachmentReference>(),
7462 															AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7463 															vector<deUint32>()));
7464 								subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7465 															0u,
7466 															vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
7467 															vector<AttachmentReference>(),
7468 															vector<AttachmentReference>(),
7469 															AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
7470 															vector<deUint32>()));
7471 
7472 								deps.push_back(SubpassDependency(0, 1,
7473 																vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7474 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7475 
7476 																vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7477 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7478 																vk::VK_DEPENDENCY_BY_REGION_BIT));
7479 
7480 								deps.push_back(SubpassDependency(1, 1,
7481 																vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7482 																vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7483 																vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7484 																vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7485 																vk::VK_DEPENDENCY_BY_REGION_BIT));
7486 
7487 
7488 								if (useInputAspect)
7489 								{
7490 									const VkInputAttachmentAspectReference inputAspect =
7491 									{
7492 										1u,
7493 										0u,
7494 
7495 										(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7496 											| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7497 									};
7498 
7499 									inputAspects.push_back(inputAspect);
7500 								}
7501 
7502 								{
7503 									const RenderPass	renderPass	(attachments, subpasses, deps, inputAspects);
7504 									const TestConfig	testConfig	(renderPass,
7505 																	 renderTypes[renderTypeNdx].types,
7506 																	 TestConfig::COMMANDBUFFERTYPES_INLINE,
7507 																	 TestConfig::IMAGEMEMORY_STRICT,
7508 																	 targetSize,
7509 																	 renderPos,
7510 																	 renderSize,
7511 																	 DE_FALSE,
7512 																	 89246,
7513 																	 0,
7514 																	 testConfigExternal.allocationKind,
7515 																	 testConfigExternal.groupParams);
7516 									const string		testName	(string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""));
7517 
7518 									addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7519 								}
7520 							}
7521 
7522 							if (isStencilAttachment && isDepthAttachment)
7523 							{
7524 								// Depth read only
7525 								{
7526 									vector<Attachment>							attachments;
7527 									vector<Subpass>								subpasses;
7528 									vector<SubpassDependency>					deps;
7529 									vector<VkInputAttachmentAspectReference>	inputAspects;
7530 
7531 									attachments.push_back(Attachment(vkFormat,
7532 																	 VK_SAMPLE_COUNT_1_BIT,
7533 																	 loadOp,
7534 																	 storeOp,
7535 																	 loadOp,
7536 																	 storeOp,
7537 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7538 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7539 
7540 									attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7541 																	 VK_SAMPLE_COUNT_1_BIT,
7542 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7543 																	 VK_ATTACHMENT_STORE_OP_STORE,
7544 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7545 																	 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7546 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7547 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7548 
7549 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7550 																0u,
7551 																vector<AttachmentReference>(),
7552 																vector<AttachmentReference>(),
7553 																vector<AttachmentReference>(),
7554 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7555 																vector<deUint32>()));
7556 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7557 																0u,
7558 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
7559 																vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7560 																vector<AttachmentReference>(),
7561 																AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7562 																vector<deUint32>()));
7563 
7564 									deps.push_back(SubpassDependency(0, 1,
7565 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7566 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7567 
7568 																	vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7569 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7570 																	0u));
7571 
7572 									if (useInputAspect)
7573 									{
7574 										const VkInputAttachmentAspectReference inputAspect =
7575 										{
7576 											1u,
7577 											0u,
7578 
7579 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7580 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7581 										};
7582 
7583 										inputAspects.push_back(inputAspect);
7584 									}
7585 
7586 									{
7587 										const RenderPass	renderPass	 (attachments, subpasses, deps, inputAspects);
7588 										const TestConfig	testConfig	 (renderPass,
7589 																		 renderTypes[renderTypeNdx].types,
7590 																		 TestConfig::COMMANDBUFFERTYPES_INLINE,
7591 																		 TestConfig::IMAGEMEMORY_STRICT,
7592 																		 targetSize,
7593 																		 renderPos,
7594 																		 renderSize,
7595 																		 DE_FALSE,
7596 																		 89246,
7597 																		 0,
7598 																		 testConfigExternal.allocationKind,
7599 																		 testConfigExternal.groupParams);
7600 										const string		testName	(renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
7601 
7602 										addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7603 									}
7604 								}
7605 								{
7606 									vector<Attachment>							attachments;
7607 									vector<Subpass>								subpasses;
7608 									vector<SubpassDependency>					deps;
7609 									vector<VkInputAttachmentAspectReference>	inputAspects;
7610 
7611 									attachments.push_back(Attachment(vkFormat,
7612 																	 VK_SAMPLE_COUNT_1_BIT,
7613 																	 loadOp,
7614 																	 storeOp,
7615 																	 loadOp,
7616 																	 storeOp,
7617 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7618 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7619 
7620 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7621 																0u,
7622 																vector<AttachmentReference>(),
7623 																vector<AttachmentReference>(),
7624 																vector<AttachmentReference>(),
7625 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7626 																vector<deUint32>()));
7627 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7628 																0u,
7629 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, inputAttachmentAspectMask)),
7630 																vector<AttachmentReference>(),
7631 																vector<AttachmentReference>(),
7632 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
7633 																vector<deUint32>()));
7634 
7635 									deps.push_back(SubpassDependency(0, 1,
7636 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7637 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7638 
7639 																	vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7640 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7641 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
7642 
7643 									deps.push_back(SubpassDependency(1, 1,
7644 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7645 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7646 
7647 																	vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7648 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7649 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
7650 
7651 									if (useInputAspect)
7652 									{
7653 										const VkInputAttachmentAspectReference inputAspect =
7654 										{
7655 											1u,
7656 											0u,
7657 
7658 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7659 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7660 										};
7661 
7662 										inputAspects.push_back(inputAspect);
7663 									}
7664 
7665 									{
7666 										const RenderPass	renderPass	(attachments, subpasses, deps, inputAspects);
7667 										const TestConfig	testConfig	(renderPass,
7668 																		 renderTypes[renderTypeNdx].types,
7669 																		 TestConfig::COMMANDBUFFERTYPES_INLINE,
7670 																		 TestConfig::IMAGEMEMORY_STRICT,
7671 																		 targetSize,
7672 																		 renderPos,
7673 																		 renderSize,
7674 																		 DE_FALSE,
7675 																		 89246,
7676 																		 0,
7677 																		 testConfigExternal.allocationKind,
7678 																		 testConfigExternal.groupParams);
7679 										const string		testName	(string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only");
7680 
7681 										addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7682 									}
7683 								}
7684 								// Stencil read only
7685 								{
7686 									vector<Attachment>							attachments;
7687 									vector<Subpass>								subpasses;
7688 									vector<SubpassDependency>					deps;
7689 									vector<VkInputAttachmentAspectReference>	inputAspects;
7690 
7691 									attachments.push_back(Attachment(vkFormat,
7692 																	 VK_SAMPLE_COUNT_1_BIT,
7693 																	 loadOp,
7694 																	 storeOp,
7695 																	 loadOp,
7696 																	 storeOp,
7697 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7698 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7699 
7700 									attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
7701 																	 VK_SAMPLE_COUNT_1_BIT,
7702 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7703 																	 VK_ATTACHMENT_STORE_OP_STORE,
7704 																	 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7705 																	 VK_ATTACHMENT_STORE_OP_DONT_CARE,
7706 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7707 																	 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
7708 
7709 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7710 																0u,
7711 																vector<AttachmentReference>(),
7712 																vector<AttachmentReference>(),
7713 																vector<AttachmentReference>(),
7714 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7715 																vector<deUint32>()));
7716 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7717 																0u,
7718 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7719 																vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
7720 																vector<AttachmentReference>(),
7721 																AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
7722 																vector<deUint32>()));
7723 
7724 									deps.push_back(SubpassDependency(0, 1,
7725 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7726 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7727 
7728 																	vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7729 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7730 																	0u));
7731 
7732 									if (useInputAspect)
7733 									{
7734 										const VkInputAttachmentAspectReference inputAspect =
7735 										{
7736 											1u,
7737 											0u,
7738 
7739 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7740 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7741 										};
7742 
7743 										inputAspects.push_back(inputAspect);
7744 									}
7745 
7746 									{
7747 										const RenderPass	renderPass	(attachments, subpasses, deps, inputAspects);
7748 										const TestConfig	testConfig	(renderPass,
7749 																		 renderTypes[renderTypeNdx].types,
7750 																		 TestConfig::COMMANDBUFFERTYPES_INLINE,
7751 																		 TestConfig::IMAGEMEMORY_STRICT,
7752 																		 targetSize,
7753 																		 renderPos,
7754 																		 renderSize,
7755 																		 DE_FALSE,
7756 																		 89246,
7757 																		 0,
7758 																		 testConfigExternal.allocationKind,
7759 																		 testConfigExternal.groupParams);
7760 										const string		testName	(renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7761 
7762 										addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7763 									}
7764 								}
7765 								{
7766 									vector<Attachment>							attachments;
7767 									vector<Subpass>								subpasses;
7768 									vector<SubpassDependency>					deps;
7769 									vector<VkInputAttachmentAspectReference>	inputAspects;
7770 
7771 									attachments.push_back(Attachment(vkFormat,
7772 																	 VK_SAMPLE_COUNT_1_BIT,
7773 																	 loadOp,
7774 																	 storeOp,
7775 																	 loadOp,
7776 																	 storeOp,
7777 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
7778 																	 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
7779 
7780 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7781 																0u,
7782 																vector<AttachmentReference>(),
7783 																vector<AttachmentReference>(),
7784 																vector<AttachmentReference>(),
7785 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
7786 																vector<deUint32>()));
7787 									subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
7788 																0u,
7789 																vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask)),
7790 																vector<AttachmentReference>(),
7791 																vector<AttachmentReference>(),
7792 																AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
7793 																vector<deUint32>()));
7794 
7795 									deps.push_back(SubpassDependency(0, 1,
7796 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7797 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7798 
7799 																	vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7800 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7801 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
7802 
7803 									deps.push_back(SubpassDependency(1, 1,
7804 																	vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
7805 																	vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7806 
7807 																	vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
7808 																	vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
7809 																	vk::VK_DEPENDENCY_BY_REGION_BIT));
7810 
7811 
7812 									if (useInputAspect)
7813 									{
7814 										const VkInputAttachmentAspectReference inputAspect =
7815 										{
7816 											1u,
7817 											0u,
7818 
7819 											(isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
7820 												| (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
7821 										};
7822 
7823 										inputAspects.push_back(inputAspect);
7824 									}
7825 
7826 									{
7827 										const RenderPass	renderPass	(attachments, subpasses, deps, inputAspects);
7828 										const TestConfig	testConfig	(renderPass,
7829 																		 renderTypes[renderTypeNdx].types,
7830 																		 TestConfig::COMMANDBUFFERTYPES_INLINE,
7831 																		 TestConfig::IMAGEMEMORY_STRICT,
7832 																		 targetSize,
7833 																		 renderPos,
7834 																		 renderSize,
7835 																		 DE_FALSE,
7836 																		 89246,
7837 																		 0,
7838 																		 testConfigExternal.allocationKind,
7839 																		 testConfigExternal.groupParams);
7840 										const string		testName	(string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only");
7841 
7842 										addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), testName, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, testConfig);
7843 									}
7844 								}
7845 							}
7846 						}
7847 					}
7848 
7849 					loadOpGroup->addChild(storeOpGroup.release());
7850 				}
7851 
7852 				inputGroup->addChild(loadOpGroup.release());
7853 			}
7854 
7855 			formatGroup->addChild(inputGroup.release());
7856 		}
7857 
7858 		group->addChild(formatGroup.release());
7859 	}
7860 }
7861 
addRenderPassTests(tcu::TestCaseGroup * group,const AllocationKind allocationKind,const SharedGroupParams groupParams)7862 void addRenderPassTests (tcu::TestCaseGroup* group, const AllocationKind allocationKind, const SharedGroupParams groupParams)
7863 {
7864 	// tests added by this function have both primary and secondary cases and there is no need to repeat them for useSecondaryCmdBuffer flag;
7865 	// but cases defined in other files that are later added to those groups in createRenderPassTestsInternal had to be adjusted and run
7866 	// for useSecondaryCmdBuffer flag
7867 	if (groupParams->useSecondaryCmdBuffer && !groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7868 		return;
7869 
7870 	const TestConfigExternal	testConfigExternal	(allocationKind, groupParams);
7871 
7872 	// don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
7873 	if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7874 	{
7875 		addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, testConfigExternal);
7876 		addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, testConfigExternal);
7877 	}
7878 
7879 	addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, testConfigExternal);
7880 
7881 	// don't repeat cases that don't use CommandBufferTypes::COMMANDBUFFERTYPES_SECONDARY
7882 	if (!groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
7883 		addTestGroup(group, "attachment_write_mask", "Attachment write mask tests", addAttachmentWriteMaskTests, testConfigExternal);
7884 
7885 	if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7886 		addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, testConfigExternal);
7887 }
7888 
createSuballocationTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)7889 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx, const SharedGroupParams groupParams)
7890 {
7891 	de::MovePtr<tcu::TestCaseGroup>	suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
7892 
7893 	addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED, groupParams);
7894 
7895 	return suballocationTestsGroup;
7896 }
7897 
createDedicatedAllocationTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)7898 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx, const SharedGroupParams groupParams)
7899 {
7900 	de::MovePtr<tcu::TestCaseGroup>	dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
7901 
7902 	addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED, groupParams);
7903 
7904 	return dedicatedAllocationTestsGroup;
7905 }
7906 
createRenderPassTestsInternal(tcu::TestContext & testCtx,const char * groupName,const SharedGroupParams groupParams)7907 tcu::TestCaseGroup* createRenderPassTestsInternal (tcu::TestContext& testCtx, const char* groupName, const SharedGroupParams groupParams)
7908 {
7909 	de::MovePtr<tcu::TestCaseGroup>	renderingTests					(new tcu::TestCaseGroup(testCtx, groupName, ""));
7910 	de::MovePtr<tcu::TestCaseGroup>	suballocationTestGroup			= createSuballocationTests(testCtx, groupParams);
7911 	de::MovePtr<tcu::TestCaseGroup>	dedicatedAllocationTestGroup	= createDedicatedAllocationTests(testCtx, groupParams);
7912 	de::MovePtr<tcu::TestCaseGroup> noDrawGroup {new tcu::TestCaseGroup{testCtx, "no_draws", ""}};
7913 
7914 	const RenderingType renderingType = groupParams->renderingType;
7915 
7916 	switch (renderingType)
7917 	{
7918 	case RENDERING_TYPE_RENDERPASS_LEGACY:
7919 		suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
7920 		suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx, groupParams));
7921 		suballocationTestGroup->addChild(createRenderPassSubpassDependencyTests(testCtx));
7922 		suballocationTestGroup->addChild(createRenderPassSampleReadTests(testCtx));
7923 		noDrawGroup->addChild(new RenderPassNoDrawLoadStoreTestCase(testCtx, "render_pass_no_draw_clear_load_store", "Test clears in a renderpass with no drawing commands", false));
7924 
7925 #ifndef CTS_USES_VULKANSC
7926 		suballocationTestGroup->addChild(createRenderPassSparseRenderTargetTests(testCtx, groupParams));
7927 		renderingTests->addChild(createDepthStencilWriteConditionsTests(testCtx));
7928 #endif // CTS_USES_VULKANSC
7929 
7930 		renderingTests->addChild(createRenderPassMultipleSubpassesMultipleCommandBuffersTests(testCtx));
7931 
7932 		break;
7933 
7934 	case RENDERING_TYPE_RENDERPASS2:
7935 		suballocationTestGroup->addChild(createRenderPass2MultisampleTests(testCtx));
7936 		suballocationTestGroup->addChild(createRenderPass2MultisampleResolveTests(testCtx, groupParams));
7937 		suballocationTestGroup->addChild(createRenderPass2SubpassDependencyTests(testCtx));
7938 		suballocationTestGroup->addChild(createRenderPass2SampleReadTests(testCtx));
7939 		noDrawGroup->addChild(new RenderPassNoDrawLoadStoreTestCase(testCtx, "render_pass2_no_draw_clear_load_store", "Test clears in a renderpass with no drawing commands", true));
7940 
7941 #ifndef CTS_USES_VULKANSC
7942 		suballocationTestGroup->addChild(createRenderPass2SparseRenderTargetTests(testCtx, groupParams));
7943 #endif // CTS_USES_VULKANSC
7944 
7945 		renderingTests->addChild(createRenderPass2DepthStencilResolveTests(testCtx));
7946 		break;
7947 
7948 #ifndef CTS_USES_VULKANSC
7949 	case RENDERING_TYPE_DYNAMIC_RENDERING:
7950 		suballocationTestGroup->addChild(createDynamicRenderingMultisampleResolveTests(testCtx, groupParams));
7951 		suballocationTestGroup->addChild(createDynamicRenderingSparseRenderTargetTests(testCtx, groupParams));
7952 
7953 		if (groupParams->useSecondaryCmdBuffer == false)
7954 		{
7955 			renderingTests->addChild(createDynamicRenderingRandomTests(testCtx));
7956 			renderingTests->addChild(createDynamicRenderingBasicTests(testCtx));
7957 		}
7958 		break;
7959 #endif // CTS_USES_VULKANSC
7960 
7961 	default:
7962 		break;
7963 	}
7964 
7965 	if (renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
7966 	{
7967 		suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, renderingType));
7968 		suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, renderingType));
7969 	}
7970 
7971 	suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, groupParams));
7972 
7973 #ifndef CTS_USES_VULKANSC
7974 	suballocationTestGroup->addChild(createRenderPassLoadStoreOpNoneTests(testCtx, groupParams));
7975 
7976 	if (renderingType == RENDERING_TYPE_RENDERPASS2)
7977 	{
7978 		suballocationTestGroup->addChild(createRenderPassSubpassMergeFeedbackTests(testCtx, renderingType));
7979 	}
7980 
7981 	renderingTests->addChild(createFragmentDensityMapTests(testCtx, groupParams));
7982 	renderingTests->addChild(createRenderPassDitheringTests(testCtx, renderingType));
7983 #endif // CTS_USES_VULKANSC
7984 
7985 	renderingTests->addChild(suballocationTestGroup.release());
7986 	renderingTests->addChild(dedicatedAllocationTestGroup.release());
7987 	renderingTests->addChild(noDrawGroup.release());
7988 
7989 	return renderingTests.release();
7990 }
7991 
7992 } // anonymous
7993 
createRenderPassTests(tcu::TestContext & testCtx)7994 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
7995 {
7996 	SharedGroupParams groupParams(
7997 		new GroupParams
7998 		{
7999 			RENDERING_TYPE_RENDERPASS_LEGACY,	// RenderingType renderingType;
8000 			false,								// bool useSecondaryCmdBuffer;
8001 			false,								// bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8002 		});
8003 	return createRenderPassTestsInternal(testCtx, "renderpass", groupParams);
8004 }
8005 
createRenderPass2Tests(tcu::TestContext & testCtx)8006 tcu::TestCaseGroup* createRenderPass2Tests (tcu::TestContext& testCtx)
8007 {
8008 	SharedGroupParams groupParams(
8009 		new GroupParams
8010 		{
8011 			RENDERING_TYPE_RENDERPASS2,			// RenderingType renderingType;
8012 			false,								// bool useSecondaryCmdBuffer;
8013 			false,								// bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8014 		});
8015 	return createRenderPassTestsInternal(testCtx, "renderpass2", groupParams);
8016 }
8017 
createDynamicRenderingTests(tcu::TestContext & testCtx)8018 tcu::TestCaseGroup* createDynamicRenderingTests(tcu::TestContext& testCtx)
8019 {
8020 	de::MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup(new tcu::TestCaseGroup(testCtx, "dynamic_rendering", "Draw using VK_KHR_dynamic_rendering"));
8021 
8022 	dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "primary_cmd_buff", SharedGroupParams(
8023 		new GroupParams
8024 		{
8025 			RENDERING_TYPE_DYNAMIC_RENDERING,	// RenderingType renderingType;
8026 			false,								// bool useSecondaryCmdBuffer;
8027 			false,								// bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8028 		})));
8029 	dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "partial_secondary_cmd_buff", SharedGroupParams(
8030 		new GroupParams
8031 		{
8032 			RENDERING_TYPE_DYNAMIC_RENDERING,	// RenderingType renderingType;
8033 			true,								// bool useSecondaryCmdBuffer;
8034 			false,								// bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8035 		})));
8036 	dynamicRenderingGroup->addChild(createRenderPassTestsInternal(testCtx, "complete_secondary_cmd_buff", SharedGroupParams(
8037 		new GroupParams
8038 		{
8039 			RENDERING_TYPE_DYNAMIC_RENDERING,	// RenderingType renderingType;
8040 			true,								// bool useSecondaryCmdBuffer;
8041 			true,								// bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
8042 		})));
8043 
8044 	return dynamicRenderingGroup.release();
8045 }
8046 
8047 } // vkt
8048