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