• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Valve Corporation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Tests vkCmdClearAttachments with unused attachments.
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkObjUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include <sstream>
35 #include <functional>
36 #include <vector>
37 #include <string>
38 #include <memory>
39 
40 namespace vkt
41 {
42 namespace renderpass
43 {
44 
45 namespace
46 {
47 
48 struct Vertex
49 {
50 	tcu::Vec4	position;
51 	tcu::Vec4	color;
52 };
53 
54 template<typename T>
sizeInBytes(const std::vector<T> & vec)55 inline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
56 {
57 	return vec.size() * sizeof(vec[0]);
58 }
59 
genVertices(void)60 std::vector<Vertex> genVertices (void)
61 {
62 	std::vector<Vertex>		vectorData;
63 	const tcu::Vec4			red			= {1.0f, 0.0f, 0.0f, 1.0f};
64 	const tcu::Vec4			green		= {0.0f, 1.0f, 0.0f, 1.0f};
65 	const tcu::Vec4			blue		= {0.0f, 0.0f, 1.0f, 1.0f};
66 	const tcu::Vec4			yellow		= {1.0f, 1.0f, 0.0f, 1.0f};
67 
68 	vectorData.push_back({tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f) , red});
69 	vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , red});
70 	vectorData.push_back({tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f) , red});
71 	vectorData.push_back({tcu::Vec4( 0.0f,  1.0f, 0.0f, 1.0f) , red});
72 
73 	vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , green});
74 	vectorData.push_back({tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f) , green});
75 	vectorData.push_back({tcu::Vec4( 0.0f,  1.0f, 0.0f, 1.0f) , green});
76 	vectorData.push_back({tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f) , green});
77 
78 	vectorData.push_back({tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f) , blue});
79 	vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , blue});
80 	vectorData.push_back({tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f) , blue});
81 	vectorData.push_back({tcu::Vec4( 0.0f,  1.0f, 0.0f, 1.0f) , blue});
82 
83 	vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , yellow});
84 	vectorData.push_back({tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f) , yellow});
85 	vectorData.push_back({tcu::Vec4( 0.0f,  1.0f, 0.0f, 1.0f) , yellow});
86 	vectorData.push_back({tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f) , yellow});
87 
88 	return vectorData;
89 }
90 
91 class MultipleSubpassesMultipleCommandBuffersTestInstance : public TestInstance
92 {
93 public:
94 											MultipleSubpassesMultipleCommandBuffersTestInstance	(Context&			context);
~MultipleSubpassesMultipleCommandBuffersTestInstance(void)95 	virtual									~MultipleSubpassesMultipleCommandBuffersTestInstance	(void) {}
96 	virtual tcu::TestStatus					iterate								(void);
97 	void									createCommandBuffer					(const DeviceInterface&	vk,
98 																				 VkDevice				vkDevice);
99 private:
100 	static constexpr deUint32				kImageWidth			= 32;
101 	static constexpr deUint32				kImageHeight		= 32;
102 	const tcu::UVec2						m_renderSize		= { kImageWidth, kImageHeight };
103 
104 	VkClearValue							m_initialColor;
105 	VkClearValue							m_clearColor;
106 
107 	Move<VkImage>							m_colorImageA;
108 	de::MovePtr<Allocation>					m_colorImageAllocA;
109 	Move<VkImageView>						m_colorAttachmentViewA;
110 
111 	Move<VkImage>							m_colorImageB;
112 	de::MovePtr<Allocation>					m_colorImageAllocB;
113 	Move<VkImageView>						m_colorAttachmentViewB;
114 
115 	Move<VkRenderPass>						m_renderPass;
116 	Move<VkFramebuffer>						m_framebufferA;
117 	Move<VkFramebuffer>						m_framebufferB;
118 	Move<VkShaderModule>					m_vertexShaderModule;
119 	Move<VkShaderModule>					m_fragmentShaderModule;
120 	Move<VkDescriptorSetLayout>				m_descriptorSetLayout;
121 	Move<VkPipelineLayout>					m_pipelineLayout;
122 	Move<VkPipeline>						m_graphicsPipeline0;
123 	Move<VkPipeline>						m_graphicsPipeline1;
124 	Move<VkPipeline>						m_graphicsPipeline2;
125 	Move<VkCommandPool>						m_cmdPool;
126 	Move<VkCommandBuffer>					m_cmdBufferA;
127 	Move<VkCommandBuffer>					m_cmdBufferB;
128 
129 	Move<VkBuffer>							m_vertexBuffer;
130 	de::MovePtr<Allocation>					m_vertexBufferAlloc;
131 };
132 
133 class MultipleSubpassesMultipleCommandBuffersTest : public vkt::TestCase
134 {
135 public:
MultipleSubpassesMultipleCommandBuffersTest(tcu::TestContext & testContext,const std::string & name,const std::string & description)136 										MultipleSubpassesMultipleCommandBuffersTest	(tcu::TestContext&	testContext,
137 																	 const std::string&	name,
138 																	 const std::string&	description)
139 											: vkt::TestCase(testContext, name, description)
140 											{}
~MultipleSubpassesMultipleCommandBuffersTest(void)141 	virtual								~MultipleSubpassesMultipleCommandBuffersTest	(void) {}
142 	virtual void						initPrograms				(SourceCollections&	sourceCollections) const;
143 	virtual TestInstance*				createInstance				(Context&			context) const;
144 };
145 
createInstance(Context & context) const146 TestInstance* MultipleSubpassesMultipleCommandBuffersTest::createInstance (Context& context) const
147 {
148 	return new MultipleSubpassesMultipleCommandBuffersTestInstance(context);
149 }
150 
initPrograms(SourceCollections & sourceCollections) const151 void MultipleSubpassesMultipleCommandBuffersTest::initPrograms (SourceCollections& sourceCollections) const
152 {
153 	// Vertex shader.
154 	sourceCollections.glslSources.add("vert_shader") << glu::VertexSource(
155 		"#version 450\n"
156 		"layout(location = 0) in vec4 position;\n"
157 		"layout(location = 1) in vec4 color;\n"
158 		"layout(location = 0) out vec4 vtxColor;\n"
159 		"void main (void)\n"
160 		"{\n"
161 		"\tgl_Position = position;\n"
162 		"\tvtxColor = color;\n"
163 		"}\n");
164 
165 	// Fragment shader.
166 	std::ostringstream fragmentSource;
167 
168 	fragmentSource	<< "#version 450\n"
169 					<< "layout(location = 0) in vec4 vtxColor;\n"
170 					<< "layout(location = 0) out vec4 fragColor;\n"
171 					<< "void main (void)\n"
172 					<< "{\n"
173 					<< "\tfragColor = vtxColor;\n"
174 					<< "}\n";
175 
176 	sourceCollections.glslSources.add("frag_shader") << glu::FragmentSource(fragmentSource.str());
177 }
178 
179 // Create a render pass for this use case.
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice)180 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vk, VkDevice vkDevice)
181 {
182 	// Create attachment descriptions.
183 	const VkAttachmentDescription		attachmentDescription	=
184 	{
185 		(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags		flags
186 		VK_FORMAT_R32G32B32A32_SFLOAT,				// VkFormat							format
187 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits			samples
188 		VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp				loadOp
189 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp
190 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp
191 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp
192 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout
193 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
194 	};
195 
196 	// Mark attachments as used or not depending on the test parameters.
197 	const VkAttachmentReference			attachmentReference
198 	{
199 		0u,																	// deUint32				attachment
200 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,							// VkImageLayout		layout
201 	};
202 
203 	// Create subpass description with the previous color attachment references.
204 	std::vector<vk::VkSubpassDescription> subpassDescriptions;
205 	{
206 		const vk::VkSubpassDescription			subpassDescription =
207 		{
208 			(VkSubpassDescriptionFlags)0,											// VkSubpassDescriptionFlags		flags
209 			VK_PIPELINE_BIND_POINT_GRAPHICS,										// VkPipelineBindPoint				pipelineBindPoint
210 			0u,																		// deUint32							inputAttachmentCount
211 			DE_NULL,																// const VkAttachmentReference*		pInputAttachments
212 			1u,																		// deUint32							colorAttachmentCount
213 			&attachmentReference,													// const VkAttachmentReference*		pColorAttachments
214 			DE_NULL,																// const VkAttachmentReference*		pResolveAttachments
215 			DE_NULL,																// const VkAttachmentReference*		pDepthStencilAttachment
216 			0u,																		// deUint32							preserveAttachmentCount
217 			DE_NULL																	// const deUint32*					pPreserveAttachments
218 		};
219 		subpassDescriptions.emplace_back(subpassDescription);
220 		subpassDescriptions.emplace_back(subpassDescription);
221 		subpassDescriptions.emplace_back(subpassDescription);
222 	}
223 
224 	std::vector<vk::VkSubpassDependency> subpassDependencies;
225 	{
226 		vk::VkSubpassDependency			subpassDependency =
227 		{
228 			0u,												// deUint32				srcSubpass
229 			1u,												// deUint32					dstSubpass
230 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// VkPipelineStageFlags		srcStageMask
231 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// VkPipelineStageFlags		dstStageMask
232 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
233 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask
234 			0u												// VkDependencyFlags		dependencyFlags
235 		};
236 		subpassDependencies.emplace_back(subpassDependency);
237 		subpassDependency.srcSubpass = 1u;
238 		subpassDependency.dstSubpass = 2u;
239 		subpassDependencies.emplace_back(subpassDependency);
240 	}
241 
242 
243 	const vk::VkRenderPassCreateInfo	renderPassInfo =
244 	{
245 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,								// VkStructureType					sType
246 		DE_NULL,																// const void*						pNext
247 		(VkRenderPassCreateFlags)0,												// VkRenderPassCreateFlags			flags
248 		1u,																		// deUint32							attachmentCount
249 		&attachmentDescription,													// const VkAttachmentDescription*	pAttachments
250 		static_cast<deUint32>(subpassDescriptions.size()),						// deUint32							subpassCount
251 		subpassDescriptions.data(),												// const VkSubpassDescription*		pSubpasses
252 		static_cast<deUint32>(subpassDependencies.size()),						// deUint32							dependencyCount
253 		subpassDependencies.data(),												// const VkSubpassDependency*		pDependencies
254 	};
255 
256 	return createRenderPass(vk, vkDevice, &renderPassInfo);
257 }
258 
MultipleSubpassesMultipleCommandBuffersTestInstance(Context & context)259 MultipleSubpassesMultipleCommandBuffersTestInstance::MultipleSubpassesMultipleCommandBuffersTestInstance(Context&	context)
260 	: vkt::TestInstance(context)
261 {
262 	// Initial color for all images.
263 	m_initialColor.color.float32[0] = 0.0f;
264 	m_initialColor.color.float32[1] = 0.0f;
265 	m_initialColor.color.float32[2] = 0.0f;
266 	m_initialColor.color.float32[3] = 1.0f;
267 
268 	// Clear color for used attachments.
269 	m_clearColor.color.float32[0] = 1.0f;
270 	m_clearColor.color.float32[1] = 1.0f;
271 	m_clearColor.color.float32[2] = 1.0f;
272 	m_clearColor.color.float32[3] = 1.0f;
273 
274 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
275 	const VkDevice				vkDevice				= m_context.getDevice();
276 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
277 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
278 	const VkComponentMapping	componentMapping		= { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
279 
280 	// Create color images.
281 	{
282 		const VkImageCreateInfo	colorImageParams =
283 		{
284 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
285 			DE_NULL,																// const void*				pNext;
286 			0u,																		// VkImageCreateFlags		flags;
287 			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
288 			VK_FORMAT_R32G32B32A32_SFLOAT,											// VkFormat					format;
289 			{ kImageWidth, kImageHeight, 1u },										// VkExtent3D				extent;
290 			1u,																		// deUint32					mipLevels;
291 			1u,																		// deUint32					arrayLayers;
292 			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
293 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
294 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
295 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT,									// VkImageUsageFlags		usage;
296 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
297 			1u,																		// deUint32					queueFamilyIndexCount;
298 			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
299 			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
300 		};
301 		// Create, allocate and bind image memory.
302 		m_colorImageA = createImage(vk, vkDevice, &colorImageParams);
303 		m_colorImageAllocA = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImageA), MemoryRequirement::Any);
304 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImageA, m_colorImageAllocA->getMemory(), m_colorImageAllocA->getOffset()));
305 
306 		m_colorImageB = createImage(vk, vkDevice, &colorImageParams);
307 		m_colorImageAllocB = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImageB), MemoryRequirement::Any);
308 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImageB, m_colorImageAllocB->getMemory(), m_colorImageAllocB->getOffset()));
309 
310 		// Create image view.
311 		{
312 			const VkImageViewCreateInfo colorAttachmentViewParamsA =
313 			{
314 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
315 				DE_NULL,											// const void*				pNext;
316 				0u,													// VkImageViewCreateFlags	flags;
317 				*m_colorImageA,										// VkImage					image;
318 				VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
319 				VK_FORMAT_R32G32B32A32_SFLOAT,						// VkFormat					format;
320 				componentMapping,									// VkChannelMapping			channels;
321 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
322 			};
323 			m_colorAttachmentViewA = createImageView(vk, vkDevice, &colorAttachmentViewParamsA);
324 
325 			const VkImageViewCreateInfo colorAttachmentViewParamsB =
326 			{
327 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
328 				DE_NULL,											// const void*				pNext;
329 				0u,													// VkImageViewCreateFlags	flags;
330 				*m_colorImageB,										// VkImage					image;
331 				VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
332 				VK_FORMAT_R32G32B32A32_SFLOAT,						// VkFormat					format;
333 				componentMapping,									// VkChannelMapping			channels;
334 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
335 			};
336 			m_colorAttachmentViewB = createImageView(vk, vkDevice, &colorAttachmentViewParamsB);
337 		}
338 
339 		// Clear image and leave it prepared to be used as a color attachment.
340 		{
341 			const VkImageAspectFlags		aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
342 			Move<VkCommandPool>				cmdPool;
343 			Move<VkCommandBuffer>			cmdBuffer;
344 			std::vector<VkImageMemoryBarrier> preImageBarriers;
345 			std::vector<VkImageMemoryBarrier> postImageBarriers;
346 
347 			// Create command pool and buffer
348 			cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
349 			cmdBuffer	= allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
350 
351 			// From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
352 			const VkImageMemoryBarrier preImageBarrierA =
353 			{
354 				 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
355 				 DE_NULL,									// const void*				pNext;
356 				 0u,										// VkAccessFlags			srcAccessMask;
357 				 VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
358 				 VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
359 				 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
360 				 VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
361 				 VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
362 				 *m_colorImageA,							// VkImage					image;
363 				 {											// VkImageSubresourceRange	subresourceRange;
364 					aspectMask,								// VkImageAspect			aspect;
365 					0u,										// deUint32					baseMipLevel;
366 					1u,										// deUint32					mipLevels;
367 					0u,										// deUint32					baseArraySlice;
368 					1u										// deUint32					arraySize;
369 				 }
370 			};
371 
372 			preImageBarriers.emplace_back(preImageBarrierA);
373 
374 			// From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
375 			const VkImageMemoryBarrier postImageBarrierA =
376 			{
377 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
378 				DE_NULL,									// const void*				pNext;
379 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
380 				VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
381 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
382 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
383 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
384 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
385 				*m_colorImageA,								// VkImage					image;
386 				{											// VkImageSubresourceRange	subresourceRange;
387 					aspectMask,								// VkImageAspect			aspect;
388 					0u,										// deUint32					baseMipLevel;
389 					1u,										// deUint32					mipLevels;
390 					0u,										// deUint32					baseArraySlice;
391 					1u										// deUint32					arraySize;
392 				}
393 			};
394 
395 			postImageBarriers.emplace_back(postImageBarrierA);
396 
397 			// From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
398 			const VkImageMemoryBarrier preImageBarrierB =
399 			{
400 				 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
401 				 DE_NULL,									// const void*				pNext;
402 				 0u,										// VkAccessFlags			srcAccessMask;
403 				 VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
404 				 VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
405 				 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
406 				 VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
407 				 VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
408 				 *m_colorImageB,							// VkImage					image;
409 				 {											// VkImageSubresourceRange	subresourceRange;
410 					aspectMask,								// VkImageAspect			aspect;
411 					0u,										// deUint32					baseMipLevel;
412 					1u,										// deUint32					mipLevels;
413 					0u,										// deUint32					baseArraySlice;
414 					1u										// deUint32					arraySize;
415 				 }
416 			};
417 
418 			preImageBarriers.emplace_back(preImageBarrierB);
419 
420 			// From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
421 			const VkImageMemoryBarrier postImageBarrierB =
422 			{
423 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
424 				DE_NULL,									// const void*				pNext;
425 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
426 				VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
427 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
428 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
429 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
430 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
431 				*m_colorImageB,								// VkImage					image;
432 				{											// VkImageSubresourceRange	subresourceRange;
433 					aspectMask,								// VkImageAspect			aspect;
434 					0u,										// deUint32					baseMipLevel;
435 					1u,										// deUint32					mipLevels;
436 					0u,										// deUint32					baseArraySlice;
437 					1u										// deUint32					arraySize;
438 				}
439 			};
440 
441 			postImageBarriers.emplace_back(postImageBarrierB);
442 
443 			const VkImageSubresourceRange clearRange	=
444 			{
445 				aspectMask,	// VkImageAspectFlags	aspectMask;
446 				0u,			// deUint32				baseMipLevel;
447 				1u,			// deUint32				levelCount;
448 				0u,			// deUint32				baseArrayLayer;
449 				1u			// deUint32				layerCount;
450 			};
451 
452 			// Clear image and transfer layout.
453 			beginCommandBuffer(vk, *cmdBuffer);
454 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, static_cast<deUint32>(preImageBarriers.size()), preImageBarriers.data());
455 			vk.cmdClearColorImage(*cmdBuffer, *m_colorImageA, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
456 			vk.cmdClearColorImage(*cmdBuffer, *m_colorImageB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
457 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, static_cast<deUint32>(postImageBarriers.size()), postImageBarriers.data());
458 			endCommandBuffer(vk, *cmdBuffer);
459 
460 			submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
461 		}
462 	}
463 
464 	// Create render pass.
465 	m_renderPass = createRenderPass(vk, vkDevice);
466 
467 	// Create framebuffer
468 	{
469 		const VkImageView				attachmentBindInfosA[1]			=
470 		{
471 			*m_colorAttachmentViewA,
472 		};
473 		const VkFramebufferCreateInfo	framebufferParamsA	=
474 		{
475 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
476 			DE_NULL,											// const void*				pNext;
477 			0u,													// VkFramebufferCreateFlags	flags;
478 			*m_renderPass,										// VkRenderPass				renderPass;
479 			1u,													// deUint32					attachmentCount;
480 			attachmentBindInfosA,								// const VkImageView*		pAttachments;
481 			kImageWidth,										// deUint32					width;
482 			kImageHeight,										// deUint32					height;
483 			1u													// deUint32					layers;
484 		};
485 
486 		m_framebufferA = createFramebuffer(vk, vkDevice, &framebufferParamsA);
487 
488 		const VkImageView				attachmentBindInfosB[1]			=
489 		{
490 			*m_colorAttachmentViewB,
491 		};
492 		const VkFramebufferCreateInfo	framebufferParamsB	=
493 		{
494 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
495 			DE_NULL,											// const void*				pNext;
496 			0u,													// VkFramebufferCreateFlags	flags;
497 			*m_renderPass,										// VkRenderPass				renderPass;
498 			1u,													// deUint32					attachmentCount;
499 			attachmentBindInfosB,								// const VkImageView*		pAttachments;
500 			kImageWidth,										// deUint32					width;
501 			kImageHeight,										// deUint32					height;
502 			1u													// deUint32					layers;
503 		};
504 
505 		m_framebufferB = createFramebuffer(vk, vkDevice, &framebufferParamsB);
506 	}
507 
508 	// Create pipeline layout.
509 	{
510 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams	=
511 		{
512 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
513 			DE_NULL,												// const void*							pNext
514 			0u,														// VkDescriptorSetLayoutCreateFlags		flags
515 			0u,														// deUint32								bindingCount
516 			DE_NULL													// const VkDescriptorSetLayoutBinding*	pBindings
517 		};
518 		m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
519 
520 		const VkPipelineLayoutCreateInfo		pipelineLayoutParams		=
521 		{
522 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
523 			DE_NULL,											// const void*						pNext;
524 			0u,													// VkPipelineLayoutCreateFlags		flags;
525 			1u,													// deUint32							setLayoutCount;
526 			&m_descriptorSetLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts;
527 			0u,													// deUint32							pushConstantRangeCount;
528 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
529 		};
530 
531 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
532 	}
533 
534 	// Create Vertex buffer
535 	{
536 		const std::vector<Vertex>		vertexValues		= genVertices();
537 		const VkDeviceSize				vertexBufferSize	= sizeInBytes(vertexValues);
538 
539 		const vk::VkBufferCreateInfo	bufferCreateInfo	=
540 		{
541 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,				// VkStructureType		sType
542 			DE_NULL,											// const void*			pNext
543 			0u,													// VkBufferCreateFlags	flags
544 			vertexBufferSize,									// VkDeviceSize			size
545 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
546 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,					// VkBufferUsageFlags	usage
547 			VK_SHARING_MODE_EXCLUSIVE,							// VkSharingMode		sharingMode
548 			1u,													// deUint32				queueFamilyIndexCount
549 			&queueFamilyIndex									// const deUint32*		pQueueFamilyIndices
550 		};
551 
552 		m_vertexBuffer		= createBuffer(vk, vkDevice, &bufferCreateInfo);
553 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
554 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
555 		// Load vertices into vertex buffer
556 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertexValues.data(), static_cast<size_t>(vertexBufferSize));
557 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
558 	}
559 
560 	// Vertex buffer description
561 	const vk::VkVertexInputBindingDescription bindingDescription =
562 	{
563 		0u,													// deUint32				binding
564 		sizeof(Vertex),										// deUint32				stride
565 		VK_VERTEX_INPUT_RATE_VERTEX							// VkVertexInputRate	inputRate
566 	};
567 
568 	std::vector<vk::VkVertexInputAttributeDescription> attributeDescriptions;
569 	{
570 		vk::VkVertexInputAttributeDescription attributeDescriptionVertex =
571 		{
572 			0u,									// deUint32		location
573 			0u,									// deUint32		binding
574 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat		format
575 			offsetof(Vertex, position)			// deUint32		offset
576 		};
577 
578 		vk::VkVertexInputAttributeDescription attributeDescriptionColor =
579 		{
580 			1u,									// deUint32		location
581 			0u,									// deUint32		binding
582 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat		format
583 			offsetof(Vertex, color)				// deUint32		offset
584 		};
585 		attributeDescriptions.emplace_back(attributeDescriptionVertex);
586 		attributeDescriptions.emplace_back(attributeDescriptionColor);
587 	}
588 
589 	const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
590 	{
591 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType
592 		DE_NULL,														// const void*								pNext
593 		0u,																// VkPipelineVertexInputStateCreateFlags	flags
594 		1u,																// deUint32									vertexBindingDescriptionCount
595 		&bindingDescription,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
596 		static_cast<deUint32>(attributeDescriptions.size()),			// deUint32									vertexAttributeDescriptionCount
597 		attributeDescriptions.data(),									// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
598 	};
599 
600 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert_shader"), 0);
601 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag_shader"), 0);
602 
603 	// Create pipeline.
604 	{
605 		const std::vector<VkViewport>						viewports						(1, makeViewport(m_renderSize));
606 		const std::vector<VkRect2D>							scissors						(1, makeRect2D(m_renderSize));
607 
608 		const VkPipelineColorBlendAttachmentState			colorBlendAttachmentState		=
609 		{
610 			VK_FALSE,					// VkBool32					blendEnable
611 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcColorBlendFactor
612 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstColorBlendFactor
613 			VK_BLEND_OP_ADD,			// VkBlendOp				colorBlendOp
614 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcAlphaBlendFactor
615 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstAlphaBlendFactor
616 			VK_BLEND_OP_ADD,			// VkBlendOp				alphaBlendOp
617 			VK_COLOR_COMPONENT_R_BIT	// VkColorComponentFlags	colorWriteMask
618 			| VK_COLOR_COMPONENT_G_BIT
619 			| VK_COLOR_COMPONENT_B_BIT
620 			| VK_COLOR_COMPONENT_A_BIT
621 		};
622 
623 		const VkPipelineColorBlendStateCreateInfo			colorBlendStateCreateInfo		=
624 		{
625 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,							// VkStructureType								sType
626 			DE_NULL,																			// const void*									pNext
627 			0u,																					// VkPipelineColorBlendStateCreateFlags			flags
628 			VK_FALSE,																			// VkBool32										logicOpEnable
629 			VK_LOGIC_OP_CLEAR,																	// VkLogicOp									logicOp
630 		    1u,																					// deUint32										attachmentCount
631 		    &colorBlendAttachmentState,															// const VkPipelineColorBlendAttachmentState*	pAttachments
632 			{ 0.0f, 0.0f, 0.0f, 0.0f }															// float										blendConstants[4]
633 		};
634 
635 		m_graphicsPipeline0 = makeGraphicsPipeline(vk,									// const DeviceInterface&							vk
636 												   vkDevice,								// const VkDevice									device
637 												   *m_pipelineLayout,					// const VkPipelineLayout							pipelineLayout
638 												   *m_vertexShaderModule,				// const VkShaderModule								vertexShaderModule
639 												   DE_NULL,								// const VkShaderModule								tessellationControlModule
640 												   DE_NULL,								// const VkShaderModule								tessellationEvalModule
641 												   DE_NULL,								// const VkShaderModule								geometryShaderModule
642 												   *m_fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
643 												   *m_renderPass,						// const VkRenderPass								renderPass
644 												   viewports,							// const std::vector<VkViewport>&					viewports
645 												   scissors,								// const std::vector<VkRect2D>&						scissors
646 												   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology						topology
647 												   0u,									// const deUint32									subpass
648 												   0u,									// const deUint32									patchControlPoints
649 												   &vertexInputState,					// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
650 												   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
651 												   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
652 												   DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
653 												   &colorBlendStateCreateInfo);			// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
654 
655 		m_graphicsPipeline1 = makeGraphicsPipeline(vk,									// const DeviceInterface&							vk
656 												   vkDevice,								// const VkDevice									device
657 												   *m_pipelineLayout,					// const VkPipelineLayout							pipelineLayout
658 												   *m_vertexShaderModule,				// const VkShaderModule								vertexShaderModule
659 												   DE_NULL,								// const VkShaderModule								tessellationControlModule
660 												   DE_NULL,								// const VkShaderModule								tessellationEvalModule
661 												   DE_NULL,								// const VkShaderModule								geometryShaderModule
662 												   *m_fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
663 												   *m_renderPass,						// const VkRenderPass								renderPass
664 												   viewports,							// const std::vector<VkViewport>&					viewports
665 												   scissors,								// const std::vector<VkRect2D>&						scissors
666 												   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology						topology
667 												   1u,									// const deUint32									subpass
668 												   0u,									// const deUint32									patchControlPoints
669 												   &vertexInputState,					// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
670 												   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
671 												   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
672 												   DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
673 												   &colorBlendStateCreateInfo);			// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
674 
675 		m_graphicsPipeline2 = makeGraphicsPipeline(vk,									// const DeviceInterface&							vk
676 												   vkDevice,								// const VkDevice									device
677 												   *m_pipelineLayout,					// const VkPipelineLayout							pipelineLayout
678 												   *m_vertexShaderModule,				// const VkShaderModule								vertexShaderModule
679 												   DE_NULL,								// const VkShaderModule								tessellationControlModule
680 												   DE_NULL,								// const VkShaderModule								tessellationEvalModule
681 												   DE_NULL,								// const VkShaderModule								geometryShaderModule
682 												   *m_fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
683 												   *m_renderPass,						// const VkRenderPass								renderPass
684 												   viewports,							// const std::vector<VkViewport>&					viewports
685 												   scissors,								// const std::vector<VkRect2D>&						scissors
686 												   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology						topology
687 												   2u,									// const deUint32									subpass
688 												   0u,									// const deUint32									patchControlPoints
689 												   &vertexInputState,					// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
690 												   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
691 												   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
692 												   DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
693 												   &colorBlendStateCreateInfo);			// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
694 
695 	}
696 
697 	// Create command pool
698 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
699 
700 	// Create command buffer
701 	createCommandBuffer(vk, vkDevice);
702 }
703 
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice)704 void MultipleSubpassesMultipleCommandBuffersTestInstance::createCommandBuffer (const DeviceInterface&	vk,
705 																		  VkDevice					vkDevice)
706 {
707 	const VkRenderPassBeginInfo							renderPassBeginInfoA	=
708 	{
709 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
710 		DE_NULL,									// const void*			pNext;
711 		*m_renderPass,								// VkRenderPass			renderPass;
712 		*m_framebufferA,							// VkFramebuffer		framebuffer;
713 		makeRect2D(m_renderSize),					// VkRect2D				renderArea;
714 		0u,											// uint32_t				clearValueCount;
715 		DE_NULL										// const VkClearValue*	pClearValues;
716 	};
717 	const VkRenderPassBeginInfo							renderPassBeginInfoB	=
718 	{
719 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
720 		DE_NULL,									// const void*			pNext;
721 		*m_renderPass,								// VkRenderPass			renderPass;
722 		*m_framebufferB,							// VkFramebuffer		framebuffer;
723 		makeRect2D(m_renderSize),					// VkRect2D				renderArea;
724 		0u,											// uint32_t				clearValueCount;
725 		DE_NULL										// const VkClearValue*	pClearValues;
726 	};
727 
728 	m_cmdBufferA = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
729 	m_cmdBufferB = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
730 
731 	const VkClearRect									clearRect			=
732 	{
733 		{												// VkRect2D		rect;
734 			{ 0, 0, },									//	VkOffset2D	offset;
735 			{ kImageWidth, kImageHeight }				//	VkExtent2D	extent;
736 		},
737 		0u,												// uint32_t		baseArrayLayer;
738 		1u												// uint32_t		layerCount;
739 	};
740 
741 	const VkClearAttachment clearAttachment =
742 	{
743 		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
744 		0u,							// uint32_t				colorAttachment;
745 		m_clearColor				// VkClearValue			clearValue;
746 	};
747 
748 	VkDeviceSize	vertexBufferOffset	= 0u;
749 
750 	// Command Buffer A will set his own event but wait for the B's event before continuing to the next subpass.
751 	beginCommandBuffer(vk, *m_cmdBufferA, 0u);
752 	beginCommandBuffer(vk, *m_cmdBufferB, 0u);
753 		vk.cmdBeginRenderPass(*m_cmdBufferA, &renderPassBeginInfoA, VK_SUBPASS_CONTENTS_INLINE);
754 		vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline0);
755 		vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
756 		vk.cmdClearAttachments(*m_cmdBufferA, 1u, &clearAttachment, 1u, &clearRect);
757 
758 		vk.cmdBeginRenderPass(*m_cmdBufferB, &renderPassBeginInfoB, VK_SUBPASS_CONTENTS_INLINE);
759 		vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline0);
760 		vk.cmdClearAttachments(*m_cmdBufferB, 1u, &clearAttachment, 1u, &clearRect);
761 		vk.cmdNextSubpass(*m_cmdBufferB, VK_SUBPASS_CONTENTS_INLINE);
762 
763 		vk.cmdNextSubpass(*m_cmdBufferA, VK_SUBPASS_CONTENTS_INLINE);
764 		vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline1);
765 		vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
766 		vk.cmdDraw(*m_cmdBufferA, 4u, 1u, 0u, 0u);
767 
768 		vertexBufferOffset = 8 * sizeof(Vertex);
769 		vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline1);
770 		vk.cmdBindVertexBuffers(*m_cmdBufferB, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
771 		vk.cmdDraw(*m_cmdBufferB, 4u, 1u, 0u, 0u);
772 		vk.cmdNextSubpass(*m_cmdBufferB, VK_SUBPASS_CONTENTS_INLINE);
773 
774 		vertexBufferOffset = 0u;
775 		vk.cmdNextSubpass(*m_cmdBufferA, VK_SUBPASS_CONTENTS_INLINE);
776 		vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline2);
777 		vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
778 		vk.cmdDraw(*m_cmdBufferA, 4u, 1u, 4u, 0u);
779 
780 		vertexBufferOffset = 8 * sizeof(Vertex);
781 		vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline2);
782 		vk.cmdDraw(*m_cmdBufferB, 4u, 1u, 4u, 0u);
783 		vk.cmdEndRenderPass(*m_cmdBufferB);
784 		vk.cmdEndRenderPass(*m_cmdBufferA);
785 	endCommandBuffer(vk, *m_cmdBufferA);
786 	endCommandBuffer(vk, *m_cmdBufferB);
787 }
788 
iterate(void)789 tcu::TestStatus	MultipleSubpassesMultipleCommandBuffersTestInstance::iterate (void)
790 {
791 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
792 	const VkDevice			vkDevice			= m_context.getDevice();
793 	const VkQueue			queue				= m_context.getUniversalQueue();
794 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
795 	SimpleAllocator			allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
796 
797 	{
798 		const Unique<VkFence>				fence				(createFence(vk, vkDevice));
799 		std::vector<VkCommandBuffer>	commandBuffers;
800 		commandBuffers.emplace_back(m_cmdBufferA.get());
801 		commandBuffers.emplace_back(m_cmdBufferB.get());
802 
803 		const VkSubmitInfo		submitInfo				=
804 		{
805 			VK_STRUCTURE_TYPE_SUBMIT_INFO,						// VkStructureType				sType;
806 			DE_NULL,											// const void*					pNext;
807 			0u,													// deUint32						waitSemaphoreCount;
808 			DE_NULL,											// const VkSemaphore*			pWaitSemaphores;
809 			(const VkPipelineStageFlags*)DE_NULL,				// const VkPipelineStageFlags*	pWaitDstStageMask;
810 			static_cast<deUint32>(commandBuffers.size()),		// deUint32						commandBufferCount;
811 			commandBuffers.data(),								// const VkCommandBuffer*		pCommandBuffers;
812 			0u,													// deUint32						signalSemaphoreCount;
813 			DE_NULL,											// const VkSemaphore*			pSignalSemaphores;
814 		};
815 
816 		VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
817 		VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), DE_TRUE, ~0ull));
818 	}
819 
820 	{
821 		// Colors to compare to.
822 		const tcu::Vec4			red			= {1.0f, 0.0f, 0.0f, 1.0f};
823 		const tcu::Vec4			green		= {0.0f, 1.0f, 0.0f, 1.0f};
824 		const tcu::Vec4			blue		= {0.0f, 0.0f, 1.0f, 1.0f};
825 		const tcu::Vec4			yellow		= {1.0f, 1.0f, 0.0f, 1.0f};
826 
827 		// Read result images.
828 		de::MovePtr<tcu::TextureLevel> imagePixelsA = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImageA, VK_FORMAT_R32G32B32A32_SFLOAT, m_renderSize);
829 		de::MovePtr<tcu::TextureLevel> imagePixelsB = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImageB, VK_FORMAT_R32G32B32A32_SFLOAT, m_renderSize);
830 
831 		// Verify pixel colors match.
832 		const tcu::ConstPixelBufferAccess&	imageAccessA		= imagePixelsA->getAccess();
833 		const tcu::ConstPixelBufferAccess&	imageAccessB		= imagePixelsB->getAccess();
834 
835 
836 		tcu::TextureLevel	referenceImageA(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_renderSize.x(), m_renderSize.y());
837 		tcu::TextureLevel	referenceImageB(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_renderSize.x(), m_renderSize.y());
838 
839 		tcu::clear(tcu::getSubregion(referenceImageA.getAccess(), 0u, 0u,
840 									 imageAccessA.getWidth() / 2, imageAccessA.getHeight()),
841 					   red);
842 		tcu::clear(tcu::getSubregion(referenceImageA.getAccess(), imageAccessA.getWidth() / 2, 0u,
843 									 imageAccessA.getWidth() / 2, imageAccessA.getHeight()),
844 				   green);
845 
846 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImageA.getAccess(), imageAccessA, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
847 			TCU_FAIL("[A] Rendered image is not correct");
848 
849 		tcu::clear(tcu::getSubregion(referenceImageB.getAccess(), 0u, 0u,
850 									 imageAccessB.getWidth() / 2, imageAccessB.getHeight()),
851 					   blue);
852 		tcu::clear(tcu::getSubregion(referenceImageB.getAccess(), imageAccessB.getWidth() / 2, 0u,
853 									 imageAccessA.getWidth() / 2, imageAccessB.getHeight()),
854 				   yellow);
855 
856 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImageB.getAccess(), imageAccessB, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
857 			TCU_FAIL("[B] Rendered image is not correct");
858 
859 	}
860 
861 	return tcu::TestStatus::pass("Pass");
862 }
863 } // anonymous
864 
createRenderPassMultipleSubpassesMultipleCommandBuffersTests(tcu::TestContext & testCtx)865 tcu::TestCaseGroup* createRenderPassMultipleSubpassesMultipleCommandBuffersTests (tcu::TestContext& testCtx)
866 {
867 	de::MovePtr<tcu::TestCaseGroup>	testGroup (new tcu::TestCaseGroup(testCtx, "multiple_subpasses_multiple_command_buffers", "Multiple subpasses multiple command buffers"));
868 
869 	testGroup->addChild(new MultipleSubpassesMultipleCommandBuffersTest(testCtx, "test", ""));
870 
871 	return testGroup.release();
872 }
873 
874 } // renderpass
875 } // vkt
876