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