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