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