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