• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 Google Inc.
6  * Copyright (c) 2018 The Khronos Group Inc.
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 for subpass dependency
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktRenderPassSubpassDependencyTests.hpp"
26 #include "vktRenderPassTestsUtil.hpp"
27 
28 #include "vktTestCaseUtil.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 
37 #include "tcuImageCompare.hpp"
38 #include "tcuResultCollector.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuTextureUtil.hpp"
41 
42 #include "rrRenderer.hpp"
43 #include "deRandom.hpp"
44 #include "deMath.h"
45 
46 using namespace vk;
47 
48 using tcu::UVec4;
49 using tcu::Vec2;
50 using tcu::UVec2;
51 using tcu::Vec4;
52 
53 using tcu::ConstPixelBufferAccess;
54 using tcu::PixelBufferAccess;
55 
56 using tcu::TestLog;
57 
58 using std::string;
59 using std::vector;
60 using de::SharedPtr;
61 
62 typedef de::SharedPtr<Unique<VkImage> >					SharedPtrVkImage;
63 typedef de::SharedPtr<Unique<VkImageView> >				SharedPtrVkImageView;
64 typedef de::SharedPtr<Unique<VkPipeline> >				SharedPtrVkPipeline;
65 typedef de::SharedPtr<Unique<VkSampler> >				SharedPtrVkSampler;
66 typedef de::SharedPtr<Unique<VkRenderPass> >			SharedPtrVkRenderPass;
67 typedef de::SharedPtr<Unique<VkFramebuffer> >			SharedPtrVkFramebuffer;
68 typedef de::SharedPtr<Unique<VkDescriptorPool> >		SharedPtrVkDescriptorPool;
69 typedef de::SharedPtr<Unique<VkDescriptorSetLayout> >	SharedPtrVkDescriptorLayout;
70 typedef de::SharedPtr<Unique<VkDescriptorSet> >			SharedPtrVkDescriptorSet;
71 typedef de::SharedPtr<Unique<VkPipelineLayout> >		SharedPtrVkPipelineLayout;
72 typedef de::SharedPtr<Unique<VkPipeline> >				SharedPtrVkPipeline;
73 
74 namespace vkt
75 {
76 namespace
77 {
78 using namespace renderpass;
79 
80 template<typename T>
makeSharedPtr(Move<T> move)81 inline SharedPtr<Unique<T> > makeSharedPtr(Move<T> move)
82 {
83 	return SharedPtr<Unique<T> >(new Unique<T>(move));
84 }
85 
getRepresentableDepthChannel(const ConstPixelBufferAccess & access)86 tcu::TextureLevel getRepresentableDepthChannel (const ConstPixelBufferAccess& access)
87 {
88 	tcu::TextureLevel depthChannel (mapVkFormat(VK_FORMAT_R8G8B8_UNORM), access.getWidth(), access.getHeight());
89 
90 	for (int y = 0; y < access.getHeight(); y++)
91 	for (int x = 0; x < access.getWidth(); x++)
92 		depthChannel.getAccess().setPixel(tcu::Vec4(access.getPixDepth(x, y)), x, y);
93 
94 	return depthChannel;
95 }
96 
verifyDepth(Context & context,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const float threshold)97 bool verifyDepth (Context&						context,
98 				  const ConstPixelBufferAccess&	reference,
99 				  const ConstPixelBufferAccess&	result,
100 				  const float					threshold)
101 {
102 	tcu::TestLog& log (context.getTestContext().getLog());
103 
104 	return tcu::floatThresholdCompare(log,										// log
105 									  "Depth channel",							// imageSetName
106 									  "Depth compare",							// imageSetDesc
107 									  getRepresentableDepthChannel(reference),	// reference
108 									  getRepresentableDepthChannel(result),		// result
109 									  Vec4(threshold),							// threshold
110 									  tcu::COMPARE_LOG_RESULT);					// logMode
111 }
112 
verifyStencil(Context & context,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result)113 bool verifyStencil (Context&						context,
114 					const ConstPixelBufferAccess&	reference,
115 					const ConstPixelBufferAccess&	result)
116 {
117 	tcu::TextureLevel	stencilErrorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
118 	tcu::TestLog&		log					(context.getTestContext().getLog());
119 	bool				stencilOk			(DE_TRUE);
120 
121 	for (int y = 0; y < result.getHeight(); y++)
122 	for (int x = 0; x < result.getWidth(); x++)
123 	{
124 		if (result.getPixStencil(x, y) != reference.getPixStencil(x, y))
125 		{
126 			stencilErrorImage.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
127 			stencilOk = DE_FALSE;
128 		}
129 		else
130 			stencilErrorImage.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
131 	}
132 
133 	log << tcu::TestLog::ImageSet("Stencil compare", "Stencil compare")
134 		<< tcu::TestLog::Image("Result stencil channel", "Result stencil channel", result)
135 		<< tcu::TestLog::Image("Reference stencil channel", "Reference stencil channel", reference);
136 
137 	if (!stencilOk)
138 		log << tcu::TestLog::Image("Stencil error mask", "Stencil error mask", stencilErrorImage);
139 
140 	log << tcu::TestLog::EndImageSet;
141 
142 	return stencilOk;
143 }
144 
145 // Reference renderer shaders
146 class DepthVertShader : public rr::VertexShader
147 {
148 public:
DepthVertShader(void)149 	DepthVertShader (void)
150 	: rr::VertexShader (1, 1)
151 	{
152 		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
153 		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
154 	}
155 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const156 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
157 	{
158 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
159 		{
160 			packets[packetNdx]->position	= rr::readVertexAttribFloat(inputs[0],
161 																		packets[packetNdx]->instanceNdx,
162 																		packets[packetNdx]->vertexNdx);
163 
164 			packets[packetNdx]->outputs[0]	= rr::readVertexAttribFloat(inputs[0],
165 																		packets[packetNdx]->instanceNdx,
166 																		packets[packetNdx]->vertexNdx);
167 		}
168 	}
169 };
170 
171 class DepthFragShader : public rr::FragmentShader
172 {
173 public:
DepthFragShader(void)174 	DepthFragShader (void)
175 	: rr::FragmentShader(1, 1)
176 	{
177 		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
178 		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
179 	}
180 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const181 	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
182 	{
183 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
184 		{
185 			rr::FragmentPacket& packet = packets[packetNdx];
186 			for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
187 			{
188 				const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
189 
190 				rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
191 			}
192 		}
193 	}
194 };
195 
196 class SelfDependencyBackwardsVertShader : public rr::VertexShader
197 {
198 public:
SelfDependencyBackwardsVertShader(void)199 	SelfDependencyBackwardsVertShader (void)
200 	: rr::VertexShader (1, 0)
201 	{
202 		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
203 	}
204 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const205 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
206 	{
207 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
208 		{
209 			packets[packetNdx]->position	= rr::readVertexAttribFloat(inputs[0],
210 																		packets[packetNdx]->instanceNdx,
211 																		packets[packetNdx]->vertexNdx);
212 		}
213 	}
214 };
215 
216 class SelfDependencyBackwardsFragShader : public rr::FragmentShader
217 {
218 public:
SelfDependencyBackwardsFragShader(void)219 	SelfDependencyBackwardsFragShader (void)
220 	: rr::FragmentShader(0, 1)
221 	{
222 		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
223 	}
224 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const225 	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
226 	{
227 		DE_UNREF(packets);
228 
229 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
230 			for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
231 				rr::writeFragmentOutput<tcu::Vec4>(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
232 	}
233 };
234 
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)235 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface&	vk,
236 											VkDevice				device,
237 											Allocator&				allocator,
238 											VkBuffer				buffer)
239 {
240 	de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
241 
242 	VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
243 
244 	return allocation;
245 }
246 
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)247 Move<VkImageView> createImageView (const DeviceInterface&	vk,
248 								   VkDevice					device,
249 								   VkImageViewCreateFlags	flags,
250 								   VkImage					image,
251 								   VkImageViewType			viewType,
252 								   VkFormat					format,
253 								   VkComponentMapping		components,
254 								   VkImageSubresourceRange	subresourceRange)
255 {
256 	const VkImageViewCreateInfo pCreateInfo =
257 	{
258 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
259 		DE_NULL,									// const void*				pNext
260 		flags,										// VkImageViewCreateFlags	flags
261 		image,										// VkImage					image
262 		viewType,									// VkImageViewType			viewType
263 		format,										// VkFormat					format
264 		components,									// VkComponentMapping		components
265 		subresourceRange,							// VkImageSubresourceRange	subresourceRange
266 	};
267 
268 	return createImageView(vk, device, &pCreateInfo);
269 }
270 
createImageViews(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkImage> images,VkFormat format,VkImageAspectFlags aspect)271 vector<SharedPtrVkImageView> createImageViews (const DeviceInterface&	vkd,
272 											   VkDevice					device,
273 											   vector<SharedPtrVkImage>	images,
274 											   VkFormat					format,
275 											   VkImageAspectFlags		aspect)
276 {
277 	vector<SharedPtrVkImageView> imageViews;
278 
279 	for (size_t imageViewNdx = 0; imageViewNdx < images.size(); imageViewNdx++)
280 	{
281 		const VkImageSubresourceRange range =
282 		{
283 			aspect,	// VkImageAspectFlags	aspectMask
284 			0u,		// uint32_t				baseMipLevel
285 			1u,		// uint32_t				levelCount
286 			0u,		// uint32_t				baseArrayLayer
287 			1u		// uint32_t				layerCount
288 		};
289 
290 		imageViews.push_back(makeSharedPtr(createImageView(vkd, device, 0u, **images[imageViewNdx], VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range)));
291 	}
292 
293 	return imageViews;
294 }
295 
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)296 Move<VkBuffer> createBuffer (const DeviceInterface&	vkd,
297 							 VkDevice				device,
298 							 VkFormat				format,
299 							 deUint32				width,
300 							 deUint32				height)
301 {
302 	const VkBufferUsageFlags	bufferUsage	(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
303 	const VkDeviceSize			pixelSize	= mapVkFormat(format).getPixelSize();
304 	const VkBufferCreateInfo	createInfo	=
305 	{
306 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
307 		DE_NULL,								// const void*			pNext
308 		0u,										// VkBufferCreateFlags	flags
309 		width * height * pixelSize,				// VkDeviceSize			size
310 		bufferUsage,							// VkBufferUsageFlags	usage
311 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
312 		0u,										// uint32_t				queueFamilyIndexCount
313 		DE_NULL									// const uint32_t*		pQueueFamilyIndices
314 	};
315 
316 	return createBuffer(vkd, device, &createInfo);
317 }
318 
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkSampler> & samplers)319 vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts (const DeviceInterface&		vkd,
320 																VkDevice					device,
321 																vector<SharedPtrVkSampler>&	samplers)
322 {
323 	vector<SharedPtrVkDescriptorLayout> layouts;
324 
325 	for (size_t layoutNdx = 0; layoutNdx < samplers.size(); layoutNdx++)
326 	{
327 		const VkDescriptorSetLayoutBinding		bindings	=
328 		{
329 				0u,											// uint32_t				binding
330 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType
331 				1u,											// uint32_t				descriptorCount
332 				VK_SHADER_STAGE_FRAGMENT_BIT,				// VkShaderStageFlags	stageFlags
333 				&**samplers[layoutNdx]						// const VkSampler*		pImmutableSamplers
334 		};
335 
336 		const VkDescriptorSetLayoutCreateInfo	createInfo	=
337 		{
338 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
339 			DE_NULL,												// const void*							pNext
340 			0u,														// VkDescriptorSetLayoutCreateFlags		flags
341 			1u,														// uint32_t								bindingCount
342 			&bindings												// const VkDescriptorSetLayoutBinding*	pBindings
343 		};
344 
345 		layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
346 	}
347 
348 	return layouts;
349 }
350 
createDescriptorPools(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorLayout> & layouts,VkDescriptorType type)351 vector<SharedPtrVkDescriptorPool> createDescriptorPools (const DeviceInterface&					vkd,
352 														 VkDevice								device,
353 														 vector<SharedPtrVkDescriptorLayout>&	layouts,
354 														 VkDescriptorType						type)
355 {
356 	vector<SharedPtrVkDescriptorPool> descriptorPools;
357 
358 	for (size_t poolNdx = 0; poolNdx < layouts.size(); poolNdx++)
359 	{
360 		const VkDescriptorPoolSize			size		=
361 		{
362 			type,	// VkDescriptorType		type
363 			1u		// uint32_t				descriptorCount
364 		};
365 
366 		const VkDescriptorPoolCreateInfo	createInfo	=
367 		{
368 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,		// VkStructureType				sType
369 			DE_NULL,											// const void*					pNext
370 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,	// VkDescriptorPoolCreateFlags	flags
371 			1u,													// uint32_t						maxSets
372 			1u,													// uint32_t						poolSizeCount
373 			&size												// const VkDescriptorPoolSize*	pPoolSizes
374 		};
375 
376 		descriptorPools.push_back(makeSharedPtr(createDescriptorPool(vkd, device, &createInfo)));
377 	}
378 
379 	return descriptorPools;
380 }
381 
382 struct ExternalTestConfig
383 {
ExternalTestConfigvkt::__anon675baf4b0111::ExternalTestConfig384 	ExternalTestConfig	(VkFormat				format_,
385 						 UVec2					imageSize_,
386 						 vector<RenderPass>		renderPasses_,
387 						 RenderPassType			renderPassType_,
388 						 SynchronizationType	synchronizationType_,
389 						 deUint32				blurKernel_ = 4)
390 		: format				(format_)
391 		, imageSize				(imageSize_)
392 		, renderPasses			(renderPasses_)
393 		, renderPassType		(renderPassType_)
394 		, synchronizationType	(synchronizationType_)
395 		, blurKernel			(blurKernel_)
396 	{
397 	}
398 
399 	VkFormat			format;
400 	UVec2				imageSize;
401 	vector<RenderPass>	renderPasses;
402 	RenderPassType		renderPassType;
403 	SynchronizationType	synchronizationType;
404 	deUint32			blurKernel;
405 };
406 
407 class ExternalDependencyTestInstance : public TestInstance
408 {
409 public:
410 											ExternalDependencyTestInstance	(Context& context, ExternalTestConfig testConfig);
411 											~ExternalDependencyTestInstance	(void);
412 
413 	vector<SharedPtrVkImage>				createAndAllocateImages			(const DeviceInterface&					vk,
414 																			 VkDevice								device,
415 																			 Allocator&								allocator,
416 																			 vector<de::SharedPtr<Allocation> >&	imageMemories,
417 																			 deUint32								universalQueueFamilyIndex,
418 																			 VkFormat								format,
419 																			 deUint32								width,
420 																			 deUint32								height,
421 																			 vector<RenderPass>						renderPasses);
422 
423 	vector<SharedPtrVkSampler>				createSamplers					(const DeviceInterface&					vkd,
424 																			 const VkDevice							device,
425 																			 vector<RenderPass>&					renderPasses);
426 
427 	vector<SharedPtrVkRenderPass>			createRenderPasses				(const DeviceInterface&					vkd,
428 																			 VkDevice								device,
429 																			 vector<RenderPass>						renderPassInfos,
430 																			 const RenderPassType					renderPassType,
431 																			 const SynchronizationType				synchronizationType);
432 
433 	vector<SharedPtrVkFramebuffer>			createFramebuffers				(const DeviceInterface&					vkd,
434 																			 VkDevice								device,
435 																			 vector<SharedPtrVkRenderPass>&			renderPasses,
436 																			 vector<SharedPtrVkImageView>&			dstImageViews,
437 																			 deUint32								width,
438 																			 deUint32								height);
439 
440 	vector<SharedPtrVkPipelineLayout>		createRenderPipelineLayouts		(const DeviceInterface&					vkd,
441 																			 VkDevice								device,
442 																			 vector<SharedPtrVkRenderPass>&			renderPasses,
443 																			 vector<SharedPtrVkDescriptorLayout>&	descriptorSetLayouts);
444 
445 	vector<SharedPtrVkPipeline>				createRenderPipelines			(const DeviceInterface&					vkd,
446 																			 VkDevice								device,
447 																			 vector<SharedPtrVkRenderPass>&			renderPasses,
448 																			 vector<SharedPtrVkPipelineLayout>&		pipelineLayouts,
449 																			 const BinaryCollection&				binaryCollection,
450 																			 deUint32								width,
451 																			 deUint32								height);
452 
453 	vector<SharedPtrVkDescriptorSet>		createDescriptorSets			(const DeviceInterface&					vkd,
454 																			 VkDevice								device,
455 																			 vector<SharedPtrVkDescriptorPool>&		pools,
456 																			 vector<SharedPtrVkDescriptorLayout>&	layouts,
457 																			 vector<SharedPtrVkImageView>&			imageViews,
458 																			 vector<SharedPtrVkSampler>&			samplers);
459 
460 	tcu::TestStatus							iterate							(void);
461 
462 	template<typename RenderpassSubpass>
463 	tcu::TestStatus							iterateInternal					(void);
464 
465 private:
466 	const bool								m_renderPass2Supported;
467 	const bool								m_synchronization2Supported;
468 	const RenderPassType					m_renderPassType;
469 
470 	const deUint32							m_width;
471 	const deUint32							m_height;
472 	const deUint32							m_blurKernel;
473 	const VkFormat							m_format;
474 
475 	vector<de::SharedPtr<Allocation> >		m_imageMemories;
476 	vector<SharedPtrVkImage>				m_images;
477 	vector<SharedPtrVkImageView>			m_imageViews;
478 	vector<SharedPtrVkSampler>				m_samplers;
479 
480 	const Unique<VkBuffer>					m_dstBuffer;
481 	const de::UniquePtr<Allocation>			m_dstBufferMemory;
482 
483 	vector<SharedPtrVkRenderPass>			m_renderPasses;
484 	vector<SharedPtrVkFramebuffer>			m_framebuffers;
485 
486 	vector<SharedPtrVkDescriptorLayout>		m_subpassDescriptorSetLayouts;
487 	vector<SharedPtrVkDescriptorPool>		m_subpassDescriptorPools;
488 	vector<SharedPtrVkDescriptorSet>		m_subpassDescriptorSets;
489 
490 	vector<SharedPtrVkPipelineLayout>		m_renderPipelineLayouts;
491 	vector<SharedPtrVkPipeline>				m_renderPipelines;
492 
493 	const Unique<VkCommandPool>				m_commandPool;
494 	tcu::ResultCollector					m_resultCollector;
495 };
496 
ExternalDependencyTestInstance(Context & context,ExternalTestConfig testConfig)497 ExternalDependencyTestInstance::ExternalDependencyTestInstance (Context& context, ExternalTestConfig testConfig)
498 	: TestInstance					(context)
499 	, m_renderPass2Supported		((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
500 	, m_synchronization2Supported	((testConfig.synchronizationType == SYNCHRONIZATION_TYPE_SYNCHRONIZATION2) && context.requireDeviceFunctionality("VK_KHR_synchronization2"))
501 	, m_renderPassType				(testConfig.renderPassType)
502 	, m_width						(testConfig.imageSize.x())
503 	, m_height						(testConfig.imageSize.y())
504 	, m_blurKernel					(testConfig.blurKernel)
505 	, m_format						(testConfig.format)
506 	, m_images						(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_format, m_width, m_height, testConfig.renderPasses))
507 	, m_imageViews					(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
508 	, m_samplers					(createSamplers(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses))
509 	, m_dstBuffer					(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
510 	, m_dstBufferMemory				(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
511 	, m_renderPasses				(createRenderPasses(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses, testConfig.renderPassType, testConfig.synchronizationType))
512 	, m_framebuffers				(createFramebuffers(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_imageViews, m_width, m_height))
513 	, m_subpassDescriptorSetLayouts	(createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_samplers))
514 	, m_subpassDescriptorPools		(createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
515 	, m_subpassDescriptorSets		(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews, m_samplers))
516 	, m_renderPipelineLayouts		(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_subpassDescriptorSetLayouts))
517 	, m_renderPipelines				(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_renderPipelineLayouts, context.getBinaryCollection(), m_width, m_height))
518 	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
519 {
520 }
521 
~ExternalDependencyTestInstance(void)522 ExternalDependencyTestInstance::~ExternalDependencyTestInstance (void)
523 {
524 }
525 
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,deUint32 universalQueueFamilyIndex,VkFormat format,deUint32 width,deUint32 height,vector<RenderPass> renderPasses)526 vector<SharedPtrVkImage> ExternalDependencyTestInstance::createAndAllocateImages (const DeviceInterface&				vk,
527 																				  VkDevice								device,
528 																				  Allocator&							allocator,
529 																				  vector<de::SharedPtr<Allocation> >&	imageMemories,
530 																				  deUint32								universalQueueFamilyIndex,
531 																				  VkFormat								format,
532 																				  deUint32								width,
533 																				  deUint32								height,
534 																				  vector<RenderPass>					renderPasses)
535 {
536 	vector<SharedPtrVkImage> images;
537 
538 	for (size_t imageNdx = 0; imageNdx < renderPasses.size(); imageNdx++)
539 	{
540 		const VkExtent3D		imageExtent		=
541 		{
542 			width,		// uint32_t		width
543 			height,		// uint32_t		height
544 			1u			// uint32_t		depth
545 		};
546 
547 		const VkImageCreateInfo	imageCreateInfo	=
548 		{
549 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
550 			DE_NULL,								// const void*				pNext
551 			0u,										// VkImageCreateFlags		flags
552 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
553 			format,									// VkFormat					format
554 			imageExtent,							// VkExtent3D				extent
555 			1u,										// uint32_t					mipLevels
556 			1u,										// uint32_t					arrayLayers
557 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
558 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
559 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
560 				| VK_IMAGE_USAGE_SAMPLED_BIT
561 				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
562 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
563 			1u,										// uint32_t					queueFamilyIndexCount
564 			&universalQueueFamilyIndex,				// const uint32_t*			pQueueFamilyIndices
565 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
566 		};
567 
568 		images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
569 		imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
570 		VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
571 	}
572 
573 	return images;
574 }
575 
createSamplers(const DeviceInterface & vkd,const VkDevice device,vector<RenderPass> & renderPasses)576 vector<SharedPtrVkSampler> ExternalDependencyTestInstance::createSamplers (const DeviceInterface&	vkd,
577 																		   const VkDevice			device,
578 																		   vector<RenderPass>&		renderPasses)
579 {
580 	vector<SharedPtrVkSampler> samplers;
581 
582 	for (size_t samplerNdx = 0; samplerNdx < renderPasses.size() - 1; samplerNdx++)
583 	{
584 		const VkSamplerCreateInfo samplerInfo =
585 		{
586 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType
587 			DE_NULL,									// const void*				pNext
588 			0u,											// VkSamplerCreateFlags		flags
589 			VK_FILTER_NEAREST,							// VkFilter					magFilter
590 			VK_FILTER_NEAREST,							// VkFilter					minFilter
591 			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode
592 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU
593 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV
594 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW
595 			0.0f,										// float					mipLodBias
596 			VK_FALSE,									// VkBool32					anisotropyEnable
597 			1.0f,										// float					maxAnisotropy
598 			VK_FALSE,									// VkBool32					compareEnable
599 			VK_COMPARE_OP_ALWAYS,						// VkCompareOp				compareOp
600 			0.0f,										// float					minLod
601 			0.0f,										// float					maxLod
602 			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor
603 			VK_FALSE,									// VkBool32					unnormalizedCoordinates
604 		};
605 
606 		samplers.push_back(makeSharedPtr(createSampler(vkd, device, &samplerInfo)));
607 	}
608 
609 	return samplers;
610 }
611 
createRenderPasses(const DeviceInterface & vkd,VkDevice device,vector<RenderPass> renderPassInfos,const RenderPassType renderPassType,const SynchronizationType synchronizationType)612 vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses (const DeviceInterface&	vkd,
613 																				  VkDevice					device,
614 																				  vector<RenderPass>		renderPassInfos,
615 																				  const RenderPassType		renderPassType,
616 																				  const SynchronizationType	synchronizationType)
617 {
618 	vector<SharedPtrVkRenderPass> renderPasses;
619 	renderPasses.reserve(renderPassInfos.size());
620 
621 	for (const auto& renderPassInfo : renderPassInfos)
622 		renderPasses.push_back(makeSharedPtr(createRenderPass(vkd, device, renderPassInfo, renderPassType, synchronizationType)));
623 
624 	return renderPasses;
625 }
626 
createFramebuffers(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkImageView> & dstImageViews,deUint32 width,deUint32 height)627 vector<SharedPtrVkFramebuffer> ExternalDependencyTestInstance::createFramebuffers (const DeviceInterface&			vkd,
628 																				   VkDevice							device,
629 																				   vector<SharedPtrVkRenderPass>&	renderPasses,
630 																				   vector<SharedPtrVkImageView>&	dstImageViews,
631 																				   deUint32							width,
632 																				   deUint32							height)
633 {
634 	vector<SharedPtrVkFramebuffer> framebuffers;
635 
636 	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
637 	{
638 		VkRenderPass renderPass (**renderPasses[renderPassNdx]);
639 
640 		const VkFramebufferCreateInfo createInfo =
641 		{
642 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
643 			DE_NULL,									// const void*				pNext
644 			0u,											// VkFramebufferCreateFlags	flags
645 			renderPass,									// VkRenderPass				renderPass
646 			1u,											// uint32_t					attachmentCount
647 			&**dstImageViews[renderPassNdx],			// const VkImageView*		pAttachments
648 			width,										// uint32_t					width
649 			height,										// uint32_t					height
650 			1u											// uint32_t					layers
651 		};
652 
653 		framebuffers.push_back(makeSharedPtr(createFramebuffer(vkd, device, &createInfo)));
654 	}
655 
656 	return framebuffers;
657 }
658 
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews,vector<SharedPtrVkSampler> & samplers)659 vector<SharedPtrVkDescriptorSet> ExternalDependencyTestInstance::createDescriptorSets (const DeviceInterface&				vkd,
660 																					   VkDevice								device,
661 																					   vector<SharedPtrVkDescriptorPool>&	pools,
662 																					   vector<SharedPtrVkDescriptorLayout>&	layouts,
663 																					   vector<SharedPtrVkImageView>&		imageViews,
664 																					   vector<SharedPtrVkSampler>&			samplers)
665 {
666 	vector<SharedPtrVkDescriptorSet> descriptorSets;
667 
668 	for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
669 	{
670 		const VkDescriptorSetAllocateInfo allocateInfo =
671 		{
672 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType					sType
673 			DE_NULL,										// const void*						pNext
674 			**pools[setNdx],								// VkDescriptorPool					descriptorPool
675 			1u,												// uint32_t							descriptorSetCount
676 			&**layouts[setNdx]								// const VkDescriptorSetLayout*		pSetLayouts
677 		};
678 
679 		descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
680 
681 		{
682 			const VkDescriptorImageInfo	imageInfo	=
683 			{
684 				**samplers[setNdx],							// VkSampler		sampler
685 				**imageViews[setNdx],						// VkImageView		imageView
686 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	imageLayout
687 			};
688 
689 			const VkWriteDescriptorSet	write		=
690 			{
691 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// VkStructureType					sType
692 				DE_NULL,									// const void*						pNext
693 				**descriptorSets[setNdx],					// VkDescriptorSet					dstSet
694 				0u,											// uint32_t							dstBinding
695 				0u,											// uint32_t							dstArrayElement
696 				1u,											// uint32_t							descriptorCount
697 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType					descriptorType
698 				&imageInfo,									// const VkDescriptorImageInfo*		pImageInfo
699 				DE_NULL,									// const VkDescriptorBufferInfo*	pBufferInfo
700 				DE_NULL										// const VkBufferView*				pTexelBufferView
701 			};
702 
703 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
704 		}
705 	}
706 
707 	return descriptorSets;
708 }
709 
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkDescriptorLayout> & descriptorSetLayouts)710 vector<SharedPtrVkPipelineLayout> ExternalDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface&				vkd,
711 																							   VkDevice								device,
712 																							   vector<SharedPtrVkRenderPass>&		renderPasses,
713 																							   vector<SharedPtrVkDescriptorLayout>&	descriptorSetLayouts)
714 {
715 	vector<SharedPtrVkPipelineLayout> pipelineLayouts;
716 
717 	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
718 	{
719 		const VkPipelineLayoutCreateInfo createInfo =
720 		{
721 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,								// VkStructureType				sType
722 			DE_NULL,																	// const void*					pNext
723 			(vk::VkPipelineLayoutCreateFlags)0,											// VkPipelineLayoutCreateFlags	flags
724 			renderPassNdx > 0 ? 1u : 0u,												// deUint32						setLayoutCount
725 			renderPassNdx > 0 ? &**descriptorSetLayouts[renderPassNdx - 1] : DE_NULL,	// const VkDescriptorSetLayout*	pSetLayouts
726 			0u,																			// deUint32						pushConstantRangeCount
727 			DE_NULL																		// const VkPushConstantRange*	pPushConstantRanges
728 		};
729 
730 		pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
731 	}
732 
733 	return pipelineLayouts;
734 }
735 
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,deUint32 width,deUint32 height)736 vector<SharedPtrVkPipeline> ExternalDependencyTestInstance::createRenderPipelines (const DeviceInterface&				vkd,
737 																				   VkDevice								device,
738 																				   vector<SharedPtrVkRenderPass>&		renderPasses,
739 																				   vector<SharedPtrVkPipelineLayout>&	pipelineLayouts,
740 																				   const BinaryCollection&				binaryCollection,
741 																				   deUint32								width,
742 																				   deUint32								height)
743 {
744 	vector<SharedPtrVkPipeline> pipelines;
745 
746 	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
747 	{
748 		const Unique<VkShaderModule>					vertexShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-vert-" + de::toString(renderPassNdx)), 0u));
749 		const Unique<VkShaderModule>					fragmentShaderModule	(createShaderModule(vkd, device, binaryCollection.get("quad-frag-" + de::toString(renderPassNdx)), 0u));
750 
751 		const VkPipelineVertexInputStateCreateInfo		vertexInputState		=
752 		{
753 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
754 			DE_NULL,													// const void*								pNext
755 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
756 			0u,															// uint32_t									vertexBindingDescriptionCount
757 			DE_NULL,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
758 			0u,															// uint32_t									vertexAttributeDescriptionCount
759 			DE_NULL														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
760 		};
761 
762 		const std::vector<VkViewport>					viewports				(1, makeViewport(tcu::UVec2(width, height)));
763 		const std::vector<VkRect2D>						scissors				(1, makeRect2D(tcu::UVec2(width, height)));
764 		const VkRenderPass								renderPass				(**renderPasses[renderPassNdx]);
765 		const VkPipelineLayout							layout					(**pipelineLayouts[renderPassNdx]);
766 
767 		pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd,									// const DeviceInterface&						vk
768 															   device,								// const VkDevice								device
769 															   layout,								// const VkPipelineLayout						pipelineLayout
770 															   *vertexShaderModule,					// const VkShaderModule							vertexShaderModule
771 															   DE_NULL,								// const VkShaderModule							tessellationControlShaderModule
772 															   DE_NULL,								// const VkShaderModule							tessellationEvalShaderModule
773 															   DE_NULL,								// const VkShaderModule							geometryShaderModule
774 															   *fragmentShaderModule,				// const VkShaderModule							fragmentShaderModule
775 															   renderPass,							// const VkRenderPass							renderPass
776 															   viewports,							// const std::vector<VkViewport>&				viewports
777 															   scissors,							// const std::vector<VkRect2D>&					scissors
778 															   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology					topology
779 															   0u,									// const deUint32								subpass
780 															   0u,									// const deUint32								patchControlPoints
781 															   &vertexInputState)));				// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
782 	}
783 
784 	return pipelines;
785 }
786 
iterate(void)787 tcu::TestStatus ExternalDependencyTestInstance::iterate (void)
788 {
789 	switch (m_renderPassType)
790 	{
791 		case RENDERPASS_TYPE_LEGACY:
792 			return iterateInternal<RenderpassSubpass1>();
793 		case RENDERPASS_TYPE_RENDERPASS2:
794 			return iterateInternal<RenderpassSubpass2>();
795 		default:
796 			TCU_THROW(InternalError, "Impossible");
797 	}
798 }
799 
800 template<typename RenderpassSubpass>
iterateInternal(void)801 tcu::TestStatus ExternalDependencyTestInstance::iterateInternal (void)
802 {
803 	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
804 	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
805 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
806 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
807 
808 	beginCommandBuffer(vkd, *commandBuffer);
809 
810 	for (size_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
811 	{
812 		// Begin render pass
813 		{
814 			VkRect2D renderArea =
815 			{
816 				{ 0u, 0u },				// VkOffset2D	offset
817 				{ m_width, m_height }	// VkExtent2D	extent
818 			};
819 
820 			const VkRenderPassBeginInfo beginInfo =
821 			{
822 				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
823 				DE_NULL,									// const void*			pNext
824 				**m_renderPasses[renderPassNdx],			// VkRenderPass			renderPass
825 				**m_framebuffers[renderPassNdx],			// VkFramebuffer		framebuffer
826 				renderArea,									// VkRect2D				renderArea
827 				0u,											// uint32_t				clearValueCount
828 				DE_NULL										// const VkClearValue*	pClearValues
829 			};
830 
831 			RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
832 		}
833 
834 		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[renderPassNdx]);
835 
836 		// Use results from the previous pass as input texture
837 		if (renderPassNdx > 0)
838 			vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[renderPassNdx], 0, 1, &**m_subpassDescriptorSets[renderPassNdx - 1], 0, DE_NULL);
839 
840 		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
841 
842 		RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
843 	}
844 
845 	// Memory barrier between rendering and copy
846 	{
847 		VkImageSubresourceRange		imageSubresourceRange	=
848 		{
849 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
850 			0u,							// uint32_t				baseMipLevel
851 			1u,							// uint32_t				levelCount
852 			0u,							// uint32_t				baseArrayLayer
853 			1u							// uint32_t				layerCount
854 		};
855 
856 		const VkImageMemoryBarrier	barrier					=
857 		{
858 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType
859 			DE_NULL,									// const void*				pNext
860 			0,											// VkAccessFlags			srcAccessMask
861 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask
862 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout			oldLayout
863 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout
864 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t					srcQueueFamilyIndex
865 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t					dstQueueFamilyIndex
866 			**m_images[m_renderPasses.size() - 1],		// VkImage					image
867 			imageSubresourceRange						// VkImageSubresourceRange	subresourceRange
868 		};
869 		// Since the implicit 'end' subpass dependency has VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT in its dstStageMask,
870 		// we can't form an execution dependency chain with a specific pipeline stage. The cases that provide an explict
871 		// 'end' subpass dependency could use a specific pipline stage, but there isn't a way to distinguish between the
872 		// implicit and explicit cases here.
873 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
874 	}
875 
876 	// Copy image memory to buffer
877 	{
878 		const VkImageSubresourceLayers imageSubresourceLayers =
879 		{
880 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
881 			0u,							// deUint32				mipLevel
882 			0u,							// deUint32				baseArrayLayer
883 			1u							// deUint32				layerCount
884 		};
885 
886 		const VkBufferImageCopy region =
887 		{
888 			0u,							// VkDeviceSize				bufferOffset
889 			0u,							// uint32_t					bufferRowLength
890 			0u,							// uint32_t					bufferImageHeight
891 			imageSubresourceLayers,		// VkImageSubresourceLayers	imageSubresource
892 			{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
893 			{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
894 		};
895 
896 		vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[m_renderPasses.size() - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_dstBuffer, 1u, &region);
897 	}
898 
899 	// Memory barrier between copy and host access
900 	{
901 		const VkBufferMemoryBarrier barrier =
902 		{
903 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
904 			DE_NULL,									// const void*		pNext
905 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
906 			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
907 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
908 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
909 			*m_dstBuffer,								// VkBuffer			buffer
910 			0u,											// VkDeviceSize		offset
911 			VK_WHOLE_SIZE								// VkDeviceSize		size
912 		};
913 
914 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
915 	}
916 
917 	endCommandBuffer(vkd, *commandBuffer);
918 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
919 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_dstBufferMemory->getMemory(), m_dstBufferMemory->getOffset(), VK_WHOLE_SIZE);
920 
921 	{
922 		const tcu::TextureFormat			format		(mapVkFormat(m_format));
923 		const void* const					ptr			(m_dstBufferMemory->getHostPtr());
924 		const tcu::ConstPixelBufferAccess	access		(format, m_width, m_height, 1, ptr);
925 		tcu::TextureLevel					reference	(format, m_width, m_height);
926 		tcu::TextureLevel					textureA	(format, m_width, m_height);
927 		tcu::TextureLevel					textureB	(format, m_width, m_height);
928 
929 		for (deUint32 renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
930 		{
931 			// First pass renders four quads of different color, which will be blurred in the following passes
932 			if (renderPassNdx == 0)
933 			{
934 				for (deUint32 y = 0; y < m_height; y++)
935 				for (deUint32 x = 0; x < m_width; x++)
936 				{
937 					if (x <= (m_width - 1) / 2 && y <= (m_height - 1) / 2)
938 						textureA.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
939 					else if (x > (m_width - 1) / 2 && y <= (m_height - 1) / 2)
940 						textureA.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
941 					else if (x <= (m_width - 1) / 2 && y > (m_height - 1) / 2)
942 						textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
943 					else
944 						textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y);
945 				}
946 			}
947 			// Blur previous pass
948 			else
949 			{
950 				for (deUint32 y = 0; y < m_height; y++)
951 				for (deUint32 x = 0; x < m_width; x++)
952 				{
953 					Vec4 blurColor (Vec4(0.0));
954 
955 					for (deUint32 sampleNdx = 0; sampleNdx < (m_blurKernel + 1); sampleNdx++)
956 					{
957 						if (renderPassNdx % 2 == 0)
958 						{
959 							// Do a horizontal blur
960 							blurColor += 0.12f * textureB.getAccess().getPixel(deClamp32((deInt32)x - (m_blurKernel / 2) + sampleNdx, 0u, m_width - 1u), y);
961 						}
962 						else
963 						{
964 							// Do a vertical blur
965 							blurColor += 0.12f * textureA.getAccess().getPixel(x, deClamp32((deInt32)y - (m_blurKernel / 2) + sampleNdx, 0u, m_height - 1u));
966 						}
967 					}
968 
969 					renderPassNdx % 2 == 0 ? textureA.getAccess().setPixel(blurColor, x, y) : textureB.getAccess().setPixel(blurColor, x, y);
970 				}
971 			}
972 		}
973 
974 		reference = m_renderPasses.size() % 2 == 0 ? textureB : textureA;
975 
976 		{
977 			// Allow error of 4 times the minimum presentable difference
978 			const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
979 
980 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
981 				m_resultCollector.fail("Compare failed.");
982 		}
983 	}
984 
985 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
986 }
987 
988 struct SubpassTestConfig
989 {
SubpassTestConfigvkt::__anon675baf4b0111::SubpassTestConfig990 		SubpassTestConfig	(VkFormat		format_,
991 							 UVec2			imageSize_,
992 							 RenderPass		renderPass_,
993 							 RenderPassType	renderPassType_)
994 		: format			(format_)
995 		, imageSize			(imageSize_)
996 		, renderPass		(renderPass_)
997 		, renderPassType	(renderPassType_)
998 	{
999 	}
1000 
1001 	VkFormat			format;
1002 	UVec2				imageSize;
1003 	RenderPass			renderPass;
1004 	RenderPassType		renderPassType;
1005 };
1006 
1007 class SubpassDependencyTestInstance : public TestInstance
1008 {
1009 public:
1010 										SubpassDependencyTestInstance	(Context&								context,
1011 																		 SubpassTestConfig						testConfig);
1012 
1013 										~SubpassDependencyTestInstance	(void);
1014 
1015 	vector<SharedPtrVkImage>			createAndAllocateImages			(const DeviceInterface&					vk,
1016 																		 VkDevice								device,
1017 																		 Allocator&								allocator,
1018 																		 vector<de::SharedPtr<Allocation> >&	imageMemories,
1019 																		 deUint32								universalQueueFamilyIndex,
1020 																		 RenderPass								renderPassInfo,
1021 																		 VkFormat								format,
1022 																		 deUint32								width,
1023 																		 deUint32								height);
1024 
1025 	vector<SharedPtrVkPipelineLayout>	createRenderPipelineLayouts		(const DeviceInterface&					vkd,
1026 																		 VkDevice								device,
1027 																		 RenderPass								renderPassInfo,
1028 																		 vector<SharedPtrVkDescriptorLayout>	descriptorSetLayouts);
1029 
1030 	vector<SharedPtrVkPipeline>			createRenderPipelines			(const DeviceInterface&					vkd,
1031 																		 VkDevice								device,
1032 																		 RenderPass								renderPassInfo,
1033 																		 VkRenderPass							renderPass,
1034 																		 vector<SharedPtrVkPipelineLayout>&		pipelineLayouts,
1035 																		 const BinaryCollection&				binaryCollection,
1036 																		 VkFormat								format,
1037 																		 deUint32								width,
1038 																		 deUint32								height);
1039 
1040 	Move<VkFramebuffer>					createFramebuffer				(const DeviceInterface&					vkd,
1041 																		 VkDevice								device,
1042 																		 RenderPass								renderPassInfo,
1043 																		 VkRenderPass							renderPass,
1044 																		 vector<SharedPtrVkImageView>&			dstImageViews,
1045 																		 deUint32								width,
1046 																		 deUint32								height);
1047 
1048 	vector<SharedPtrVkDescriptorLayout>	createDescriptorSetLayouts		(const DeviceInterface&					vkd,
1049 																		 VkDevice								device,
1050 																		 RenderPass								renderPassInfo);
1051 
1052 	vector<SharedPtrVkDescriptorSet>	createDescriptorSets			(const DeviceInterface&					vkd,
1053 																		 VkDevice								device,
1054 																		 VkFormat								format,
1055 																		 vector<SharedPtrVkDescriptorPool>&		pools,
1056 																		 vector<SharedPtrVkDescriptorLayout>&	layouts,
1057 																		 vector<SharedPtrVkImageView>&			imageViews);
1058 
1059 	tcu::TestStatus						iterate							(void);
1060 
1061 	template<typename RenderpassSubpass>
1062 	tcu::TestStatus						iterateInternal					(void);
1063 
1064 private:
1065 	const bool							m_extensionSupported;
1066 	const RenderPass					m_renderPassInfo;
1067 	const RenderPassType				m_renderPassType;
1068 
1069 	const deUint32						m_width;
1070 	const deUint32						m_height;
1071 	const VkFormat						m_format;
1072 
1073 	vector<de::SharedPtr<Allocation> >	m_imageMemories;
1074 	vector<SharedPtrVkImage>			m_images;
1075 	vector<SharedPtrVkImageView>		m_imageViews;
1076 
1077 	const Unique<VkBuffer>				m_primaryBuffer;
1078 	const Unique<VkBuffer>				m_secondaryBuffer;
1079 	const de::UniquePtr<Allocation>		m_primaryBufferMemory;
1080 	const de::UniquePtr<Allocation>		m_secondaryBufferMemory;
1081 
1082 	const Unique<VkRenderPass>			m_renderPass;
1083 	const Unique<VkFramebuffer>			m_framebuffer;
1084 
1085 	vector<SharedPtrVkDescriptorLayout>	m_subpassDescriptorSetLayouts;
1086 	vector<SharedPtrVkDescriptorPool>	m_subpassDescriptorPools;
1087 	vector<SharedPtrVkDescriptorSet>	m_subpassDescriptorSets;
1088 
1089 	vector<SharedPtrVkPipelineLayout>	m_renderPipelineLayouts;
1090 	vector<SharedPtrVkPipeline>			m_renderPipelines;
1091 
1092 	const Unique<VkCommandPool>			m_commandPool;
1093 	tcu::ResultCollector				m_resultCollector;
1094 };
1095 
SubpassDependencyTestInstance(Context & context,SubpassTestConfig testConfig)1096 SubpassDependencyTestInstance::SubpassDependencyTestInstance (Context& context, SubpassTestConfig testConfig)
1097 	: TestInstance					(context)
1098 	, m_extensionSupported			((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1099 	, m_renderPassInfo				(testConfig.renderPass)
1100 	, m_renderPassType				(testConfig.renderPassType)
1101 	, m_width						(testConfig.imageSize.x())
1102 	, m_height						(testConfig.imageSize.y())
1103 	, m_format						(testConfig.format)
1104 	, m_images						(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_renderPassInfo, m_format, m_width, m_height))
1105 	, m_imageViews					(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, isDepthStencilFormat(m_format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT))
1106 	, m_primaryBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1107 	, m_secondaryBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1108 	, m_primaryBufferMemory			(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_primaryBuffer))
1109 	, m_secondaryBufferMemory		(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_secondaryBuffer))
1110 	, m_renderPass					(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, testConfig.renderPassType))
1111 	, m_framebuffer					(createFramebuffer(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_imageViews, m_width, m_height))
1112 	, m_subpassDescriptorSetLayouts	(createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo))
1113 	, m_subpassDescriptorPools		(createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT))
1114 	, m_subpassDescriptorSets		(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_format, m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews))
1115 	, m_renderPipelineLayouts		(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, m_subpassDescriptorSetLayouts))
1116 	, m_renderPipelines				(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_renderPipelineLayouts, context.getBinaryCollection(), m_format, m_width, m_height))
1117 	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1118 {
1119 }
1120 
~SubpassDependencyTestInstance(void)1121 SubpassDependencyTestInstance::~SubpassDependencyTestInstance (void)
1122 {
1123 }
1124 
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,deUint32 universalQueueFamilyIndex,RenderPass renderPassInfo,VkFormat format,deUint32 width,deUint32 height)1125 vector<SharedPtrVkImage> SubpassDependencyTestInstance::createAndAllocateImages (const DeviceInterface&					vk,
1126 																				 VkDevice								device,
1127 																				 Allocator&								allocator,
1128 																				 vector<de::SharedPtr<Allocation> >&	imageMemories,
1129 																				 deUint32								universalQueueFamilyIndex,
1130 																				 RenderPass								renderPassInfo,
1131 																				 VkFormat								format,
1132 																				 deUint32								width,
1133 																				 deUint32								height)
1134 {
1135 	// Verify format support
1136 	{
1137 		const VkFormatFeatureFlags	flags		= isDepthStencilFormat(m_format) ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1138 		const VkFormatProperties	properties	= vk::getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format);
1139 
1140 		if ((properties.optimalTilingFeatures & flags) != flags)
1141 			TCU_THROW(NotSupportedError, "Format not supported");
1142 	}
1143 
1144 	vector<SharedPtrVkImage> images;
1145 
1146 	for (size_t imageNdx = 0; imageNdx < renderPassInfo.getAttachments().size(); imageNdx++)
1147 	{
1148 		const VkExtent3D		imageExtent		=
1149 		{
1150 			width,		// uint32_t	width
1151 			height,		// uint32_t	height
1152 			1u			// uint32_t	depth
1153 		};
1154 
1155 		VkImageUsageFlags		usage			= ((isDepthStencilFormat(format)
1156 													? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
1157 													: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
1158 													| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1159 													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
1160 
1161 		const VkImageCreateInfo	imageCreateInfo	=
1162 		{
1163 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
1164 			DE_NULL,								// const void*				pNext
1165 			0u,										// VkImageCreateFlags		flags
1166 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
1167 			format,									// VkFormat					format
1168 			imageExtent,							// VkExtent3D				extent
1169 			1u,										// uint32_t					mipLevels
1170 			1u,										// uint32_t					arrayLayers
1171 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
1172 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
1173 			usage,									// VkImageUsageFlags		usage
1174 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
1175 			1u,										// uint32_t					queueFamilyIndexCount
1176 			&universalQueueFamilyIndex,				// const uint32_t*			pQueueFamilyIndices
1177 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
1178 		};
1179 
1180 		images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
1181 		imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
1182 		VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
1183 	}
1184 
1185 	return images;
1186 }
1187 
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)1188 vector<SharedPtrVkPipelineLayout> SubpassDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface&				vkd,
1189 																							  VkDevice								device,
1190 																							  RenderPass							renderPassInfo,
1191 																							  vector<SharedPtrVkDescriptorLayout>	descriptorSetLayouts)
1192 {
1193 	vector<SharedPtrVkPipelineLayout>	pipelineLayouts;
1194 	vector<VkDescriptorSetLayout>		descriptorSetLayoutHandles;
1195 	const size_t						descriptorSetLayoutCount	= descriptorSetLayouts.size();
1196 
1197 	for (size_t descriptorSetLayoutNdx = 0; descriptorSetLayoutNdx < descriptorSetLayoutCount; descriptorSetLayoutNdx++)
1198 		descriptorSetLayoutHandles.push_back(**descriptorSetLayouts.at(descriptorSetLayoutNdx));
1199 
1200 	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1201 	{
1202 		const VkPipelineLayoutCreateInfo createInfo =
1203 		{
1204 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
1205 			DE_NULL,										// const void*					pNext
1206 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
1207 			(deUint32)descriptorSetLayoutCount,				// deUint32						setLayoutCount
1208 			descriptorSetLayoutHandles.data(),				// const VkDescriptorSetLayout*	pSetLayouts
1209 			0u,												// deUint32						pushConstantRangeCount
1210 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
1211 		};
1212 
1213 		pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
1214 	}
1215 
1216 	return pipelineLayouts;
1217 }
1218 
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,VkFormat format,deUint32 width,deUint32 height)1219 vector<SharedPtrVkPipeline> SubpassDependencyTestInstance::createRenderPipelines (const DeviceInterface&				vkd,
1220 																				  VkDevice								device,
1221 																				  RenderPass							renderPassInfo,
1222 																				  VkRenderPass							renderPass,
1223 																				  vector<SharedPtrVkPipelineLayout>&	pipelineLayouts,
1224 																				  const BinaryCollection&				binaryCollection,
1225 																				  VkFormat								format,
1226 																				  deUint32								width,
1227 																				  deUint32								height)
1228 {
1229 	vector<SharedPtrVkPipeline> pipelines;
1230 
1231 	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1232 	{
1233 		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, binaryCollection.get("subpass-vert-" + de::toString(subpassNdx)), 0u));
1234 		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, binaryCollection.get("subpass-frag-" + de::toString(subpassNdx)), 0u));
1235 
1236 		const VkVertexInputBindingDescription		vertexBinding0				=
1237 		{
1238 			0u,							// deUint32					binding;
1239 			sizeof(Vec4),				// deUint32					strideInBytes;
1240 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
1241 		};
1242 
1243 		VkVertexInputAttributeDescription			attr0						=
1244 		{
1245 			0u,								// deUint32	location;
1246 			0u,								// deUint32	binding;
1247 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
1248 			0u								// deUint32	offsetInBytes;
1249 		};
1250 
1251 		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
1252 		{
1253 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
1254 			DE_NULL,													// const void*								pNext
1255 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
1256 			1u,															// uint32_t									vertexBindingDescriptionCount
1257 			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
1258 			1u,															// uint32_t									vertexAttributeDescriptionCount
1259 			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
1260 		};
1261 
1262 		const VkStencilOpState						stencilOpState				=
1263 		{
1264 			VK_STENCIL_OP_KEEP,		// stencilFailOp
1265 			VK_STENCIL_OP_KEEP,		// stencilPassOp
1266 			VK_STENCIL_OP_KEEP,		// stencilDepthFailOp
1267 			VK_COMPARE_OP_ALWAYS,	// stencilCompareOp
1268 			0x0u,					// stencilCompareMask
1269 			0x0u,					// stencilWriteMask
1270 			0u						// stencilReference
1271 		};
1272 
1273 		const VkPipelineDepthStencilStateCreateInfo	depthStencilStateCreateInfo	=
1274 		{
1275 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType
1276 			DE_NULL,													// const void*								pNext
1277 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags
1278 			VK_TRUE,													// VkBool32									depthTestEnable
1279 			VK_TRUE,													// VkBool32									depthWriteEnable
1280 			VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp
1281 			VK_FALSE,													// VkBool32									depthBoundsTestEnable
1282 			VK_TRUE,													// VkBool32									stencilTestEnable
1283 			stencilOpState,												// VkStencilOpState							front
1284 			stencilOpState,												// VkStencilOpState							back
1285 			0.0f,														// float									minDepthBounds
1286 			1.0f,														// float									maxDepthBounds
1287 		};
1288 
1289 		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(width, height)));
1290 		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(width, height)));
1291 		const VkPipelineLayout						layout						(**pipelineLayouts[subpassNdx]);
1292 		const VkPipelineDepthStencilStateCreateInfo	depthStencilCreateInfo		(isDepthStencilFormat(format)
1293 																					? depthStencilStateCreateInfo
1294 																					: VkPipelineDepthStencilStateCreateInfo());
1295 
1296 		pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd,									// const DeviceInterface&							vk
1297 															   device,								// const VkDevice									device
1298 															   layout,								// const VkPipelineLayout							pipelineLayout
1299 															   *vertexShaderModule,					// const VkShaderModule								vertexShaderModule
1300 															   DE_NULL,								// const VkShaderModule								tessellationControlShaderModule
1301 															   DE_NULL,								// const VkShaderModule								tessellationEvalShaderModule
1302 															   DE_NULL,								// const VkShaderModule								geometryShaderModule
1303 															   *fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
1304 															   renderPass,							// const VkRenderPass								renderPass
1305 															   viewports,							// const std::vector<VkViewport>&					viewports
1306 															   scissors,							// const std::vector<VkRect2D>&						scissors
1307 															   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
1308 															   (deUint32)subpassNdx,				// const deUint32									subpass
1309 															   0u,									// const deUint32									patchControlPoints
1310 															   &vertexInputState,					// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
1311 															   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
1312 															   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
1313 															   &depthStencilCreateInfo,				// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
1314 															   DE_NULL)));							// const VkPipelineDynamicStateCreateInfo*			pDynamicState
1315 	}
1316 
1317 	return pipelines;
1318 }
1319 
createFramebuffer(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkImageView> & dstImageViews,deUint32 width,deUint32 height)1320 Move<VkFramebuffer> SubpassDependencyTestInstance::createFramebuffer (const DeviceInterface&		vkd,
1321 																	  VkDevice						device,
1322 																	  RenderPass					renderPassInfo,
1323 																	  VkRenderPass					renderPass,
1324 																	  vector<SharedPtrVkImageView>&	dstImageViews,
1325 																	  deUint32						width,
1326 																	  deUint32						height)
1327 {
1328 	const size_t		attachmentCount		(renderPassInfo.getAttachments().size());
1329 	vector<VkImageView>	attachmentHandles;
1330 
1331 	for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1332 		attachmentHandles.push_back(**dstImageViews.at(attachmentNdx));
1333 
1334 	const VkFramebufferCreateInfo createInfo =
1335 	{
1336 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
1337 		DE_NULL,									// const void*				pNext
1338 		0u,											// VkFramebufferCreateFlags	flags
1339 		renderPass,									// VkRenderPass				renderPass
1340 		(deUint32)attachmentCount,					// uint32_t					attachmentCount
1341 		attachmentHandles.data(),					// const VkImageView*		pAttachments
1342 		width,										// uint32_t					width
1343 		height,										// uint32_t					height
1344 		1u											// uint32_t					layers
1345 	};
1346 
1347 	return vk::createFramebuffer(vkd, device, &createInfo);
1348 }
1349 
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo)1350 vector<SharedPtrVkDescriptorLayout> SubpassDependencyTestInstance::createDescriptorSetLayouts (const DeviceInterface&	vkd,
1351 																							   VkDevice					device,
1352 																							   RenderPass				renderPassInfo)
1353 {
1354 	vector<SharedPtrVkDescriptorLayout> layouts;
1355 
1356 	size_t attachmentCount = renderPassInfo.getAttachments().size();
1357 
1358 	for (size_t layoutNdx = 0; layoutNdx < attachmentCount - 1; layoutNdx++)
1359 	{
1360 		const VkDescriptorSetLayoutBinding		bindings	=
1361 		{
1362 				0u,										// uint32_t				binding
1363 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType		descriptorType
1364 				1u,										// uint32_t				descriptorCount
1365 				VK_SHADER_STAGE_FRAGMENT_BIT,			// VkShaderStageFlags	stageFlags
1366 				DE_NULL									// const VkSampler*		pImmutableSamplers
1367 		};
1368 
1369 		const VkDescriptorSetLayoutCreateInfo	createInfo	=
1370 		{
1371 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
1372 			DE_NULL,												// const void*							pNext
1373 			0u,														// VkDescriptorSetLayoutCreateFlags		flags
1374 			1u,														// uint32_t								bindingCount
1375 			&bindings												// const VkDescriptorSetLayoutBinding*	pBindings
1376 		};
1377 
1378 		layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
1379 	}
1380 
1381 	return layouts;
1382 }
1383 
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,VkFormat format,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews)1384 vector<SharedPtrVkDescriptorSet> SubpassDependencyTestInstance::createDescriptorSets (const DeviceInterface&				vkd,
1385 																					  VkDevice								device,
1386 																					  VkFormat								format,
1387 																					  vector<SharedPtrVkDescriptorPool>&	pools,
1388 																					  vector<SharedPtrVkDescriptorLayout>&	layouts,
1389 																					  vector<SharedPtrVkImageView>&			imageViews)
1390 {
1391 	vector<SharedPtrVkDescriptorSet> descriptorSets;
1392 
1393 	for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
1394 	{
1395 		const VkDescriptorSetAllocateInfo allocateInfo =
1396 		{
1397 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType				sType
1398 			DE_NULL,										// const void*					pNext
1399 			**pools[setNdx],								// VkDescriptorPool				descriptorPool
1400 			1u,												// uint32_t						descriptorSetCount
1401 			&**layouts[setNdx]								// const VkDescriptorSetLayout*	pSetLayouts
1402 		};
1403 
1404 		descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
1405 
1406 		{
1407 			VkImageLayout imageLayout				= isDepthStencilFormat(format)
1408 														? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
1409 														: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1410 
1411 			const VkDescriptorImageInfo	imageInfo	=
1412 			{
1413 				DE_NULL,				// VkSampler		sampler
1414 				**imageViews[setNdx],	// VkImageView		imageView
1415 				imageLayout				// VkImageLayout	imageLayout
1416 			};
1417 
1418 			const VkWriteDescriptorSet	write		=
1419 			{
1420 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType
1421 				DE_NULL,								// const void*						pNext
1422 				**descriptorSets[setNdx],				// VkDescriptorSet					dstSet
1423 				0u,										// uint32_t							dstBinding
1424 				0u,										// uint32_t							dstArrayElement
1425 				1u,										// uint32_t							descriptorCount
1426 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType					descriptorType
1427 				&imageInfo,								// const VkDescriptorImageInfo*		pImageInfo
1428 				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo
1429 				DE_NULL									// const VkBufferView*				pTexelBufferView
1430 			};
1431 
1432 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
1433 		}
1434 	}
1435 
1436 	return descriptorSets;
1437 }
1438 
iterate(void)1439 tcu::TestStatus SubpassDependencyTestInstance::iterate (void)
1440 {
1441 	switch (m_renderPassType)
1442 	{
1443 		case RENDERPASS_TYPE_LEGACY:
1444 			return iterateInternal<RenderpassSubpass1>();
1445 		case RENDERPASS_TYPE_RENDERPASS2:
1446 			return iterateInternal<RenderpassSubpass2>();
1447 		default:
1448 			TCU_THROW(InternalError, "Impossible");
1449 	}
1450 }
1451 
1452 template<typename RenderpassSubpass>
iterateInternal(void)1453 tcu::TestStatus SubpassDependencyTestInstance::iterateInternal (void)
1454 {
1455 	de::Random											rand					(5);
1456 	const DeviceInterface&								vkd						(m_context.getDeviceInterface());
1457 	const Unique<VkCommandBuffer>						commandBuffer			(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1458 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo		(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1459 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
1460 	const size_t										attachmentCount			(m_renderPassInfo.getAttachments().size());
1461 	const size_t										subpassCount			(m_renderPassInfo.getSubpasses().size());
1462 	vector<VkClearValue>								clearValues;
1463 	vector<Vec4>										vertexData;
1464 
1465 	beginCommandBuffer(vkd, *commandBuffer);
1466 
1467 	// Transition stencil aspects to the final layout directly.
1468 	if (isDepthStencilFormat(m_format))
1469 	{
1470 		const VkImageSubresourceRange imageSubresourceRange =
1471 		{
1472 			VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask
1473 			0u,								// uint32_t				baseMipLevel
1474 			1u,								// uint32_t				levelCount
1475 			0u,								// uint32_t				baseArrayLayer
1476 			1u								// uint32_t				layerCount
1477 		};
1478 
1479 		VkImageMemoryBarrier barrier =
1480 		{
1481 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType
1482 			DE_NULL,											// const void*				pNext
1483 			0u,													// VkAccessFlags			srcAccessMask
1484 			VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			dstAccessMask
1485 			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout
1486 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,	// VkImageLayout			newLayout
1487 			VK_QUEUE_FAMILY_IGNORED,							// uint32_t					srcQueueFamilyIndex
1488 			VK_QUEUE_FAMILY_IGNORED,							// uint32_t					dstQueueFamilyIndex
1489 			DE_NULL,											// VkImage					image
1490 			imageSubresourceRange								// VkImageSubresourceRange	subresourceRange
1491 		};
1492 
1493 		for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; ++attachmentNdx)
1494 		{
1495 			barrier.image = **m_images[attachmentNdx];
1496 			vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1497 		}
1498 	}
1499 
1500 	// Begin render pass
1501 	{
1502 		VkRect2D					renderArea			=
1503 		{
1504 			{ 0u, 0u },				// VkOffset2D	offset
1505 			{ m_width, m_height }	// VkExtent2D	extent
1506 		};
1507 
1508 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1509 			clearValues.push_back(isDepthStencilFormat(m_format) ? makeClearValueDepthStencil(1.0f, 255u) : makeClearValueColor(Vec4(1.0f, 0.0f, 0.0f, 1.0f)));
1510 
1511 		const VkRenderPassBeginInfo	beginInfo			=
1512 		{
1513 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
1514 			DE_NULL,									// const void*			pNext
1515 			*m_renderPass,								// VkRenderPass			renderPass
1516 			*m_framebuffer,								// VkFramebuffer		framebuffer
1517 			renderArea,									// VkRect2D				renderArea
1518 			(deUint32)attachmentCount,					// uint32_t				clearValueCount
1519 			clearValues.data()							// const VkClearValue*	pClearValues
1520 		};
1521 
1522 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1523 	}
1524 
1525 	// Generate vertices for 128 triangles with pseudorandom positions and depths values
1526 	for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
1527 	{
1528 		float primitiveDepth = rand.getFloat();
1529 
1530 		for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
1531 		{
1532 			float x = 2.0f * rand.getFloat() - 1.0f;
1533 			float y = 2.0f * rand.getFloat() - 1.0f;
1534 
1535 			vertexData.push_back(Vec4(x, y, primitiveDepth, 1.0f));
1536 		}
1537 	}
1538 
1539 	const size_t										singleVertexDataSize	= sizeof(Vec4);
1540 	const size_t										vertexCount				= vertexData.size();
1541 	const size_t										vertexDataSize			= vertexCount * singleVertexDataSize;
1542 	const deUint32										queueFamilyIndices		= m_context.getUniversalQueueFamilyIndex();
1543 
1544 	const VkBufferCreateInfo							vertexBufferParams		=
1545 	{
1546 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType;
1547 		DE_NULL,								//	const void*			pNext;
1548 		0u,										//	VkBufferCreateFlags	flags;
1549 		(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size;
1550 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage;
1551 		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode;
1552 		1u,										//	deUint32			queueFamilyCount;
1553 		&queueFamilyIndices,					//	const deUint32*		pQueueFamilyIndices;
1554 	};
1555 
1556 	const Unique<VkBuffer>								vertexBuffer			(createBuffer(vkd, m_context.getDevice(), &vertexBufferParams));
1557 	const de::UniquePtr<Allocation>						vertexBufferMemory		(m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vkd, m_context.getDevice(), *vertexBuffer), MemoryRequirement::HostVisible));
1558 
1559 	VK_CHECK(vkd.bindBufferMemory(m_context.getDevice(), *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
1560 
1561 	const VkDeviceSize bindingOffset = 0;
1562 	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
1563 
1564 	for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
1565 	{
1566 		if (subpassNdx > 0)
1567 		{
1568 			RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1569 			vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[subpassNdx], 0, 1, &**m_subpassDescriptorSets[subpassNdx - 1], 0, DE_NULL);
1570 		}
1571 
1572 		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[subpassNdx]);
1573 
1574 		if (subpassNdx == 0)
1575 		{
1576 			// Upload vertex data
1577 			{
1578 				void* vertexBufPtr = vertexBufferMemory->getHostPtr();
1579 				deMemcpy(vertexBufPtr, vertexData.data(), vertexDataSize);
1580 				flushAlloc(vkd, m_context.getDevice(), *vertexBufferMemory);
1581 			}
1582 
1583 			vkd.cmdDraw(*commandBuffer, (deUint32)vertexData.size(), 1u, 0u, 0u);
1584 		}
1585 		else
1586 			vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1587 	}
1588 
1589 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1590 
1591 	// Memory barrier between rendering and copy
1592 	{
1593 		const VkImageAspectFlags	imageAspectFlags		= isDepthStencilFormat(m_format)
1594 																? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1595 		const VkAccessFlags			srcAccessMask			= isDepthStencilFormat(m_format)
1596 																? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1597 		const VkImageLayout			oldLayout				= isDepthStencilFormat(m_format)
1598 																? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1599 		const VkPipelineStageFlags	srcStageMask			= isDepthStencilFormat(m_format)
1600 																? VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1601 
1602 		VkImageSubresourceRange		imageSubresourceRange	=
1603 		{
1604 			imageAspectFlags,	// VkImageAspectFlags	aspectMask
1605 			0u,					// uint32_t				baseMipLevel
1606 			1u,					// uint32_t				levelCount
1607 			0u,					// uint32_t				baseArrayLayer
1608 			1u					// uint32_t				layerCount
1609 		};
1610 
1611 		const VkImageMemoryBarrier	barrier					=
1612 		{
1613 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType
1614 			DE_NULL,								// const void*				pNext
1615 			srcAccessMask,							// VkAccessFlags			srcAccessMask
1616 			VK_ACCESS_TRANSFER_READ_BIT,			// VkAccessFlags			dstAccessMask
1617 			oldLayout,								// VkImageLayout			oldLayout
1618 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout			newLayout
1619 			VK_QUEUE_FAMILY_IGNORED,				// uint32_t					srcQueueFamilyIndex
1620 			VK_QUEUE_FAMILY_IGNORED,				// uint32_t					dstQueueFamilyIndex
1621 			**m_images[attachmentCount - 1],		// VkImage					image
1622 			imageSubresourceRange					// VkImageSubresourceRange	subresourceRange
1623 		};
1624 
1625 		vkd.cmdPipelineBarrier(*commandBuffer, srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1626 	}
1627 
1628 	// Copy image memory to buffer
1629 	{
1630 		if (isDepthStencilFormat(m_format))
1631 		{
1632 			// Copy depth
1633 			const VkImageSubresourceLayers subresourceLayersDepth	=
1634 			{
1635 				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask
1636 				0u,							// deUint32				mipLevel
1637 				0u,							// deUint32				baseArrayLayer
1638 				1u							// deUint32				layerCount
1639 			};
1640 
1641 			const VkBufferImageCopy			regionDepth				=
1642 			{
1643 				0u,							// VkDeviceSize				bufferOffset
1644 				0u,							// uint32_t					bufferRowLength
1645 				0u,							// uint32_t					bufferImageHeight
1646 				subresourceLayersDepth,		// VkImageSubresourceLayers	imageSubresource
1647 				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
1648 				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
1649 			};
1650 
1651 			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &regionDepth);
1652 
1653 			// Copy stencil
1654 			const VkImageSubresourceLayers subresourceLayersStencil	=
1655 			{
1656 				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask
1657 				0u,								// deUint32				mipLevel
1658 				0u,								// deUint32				baseArrayLayer
1659 				1u								// deUint32				layerCount
1660 			};
1661 
1662 			const VkBufferImageCopy			regionStencil			=
1663 			{
1664 				0u,							// VkDeviceSize				bufferOffset
1665 				0u,							// uint32_t					bufferRowLength
1666 				0u,							// uint32_t					bufferImageHeight
1667 				subresourceLayersStencil,	// VkImageSubresourceLayers	imageSubresource
1668 				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
1669 				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
1670 			};
1671 
1672 			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_secondaryBuffer, 1u, &regionStencil);
1673 		}
1674 		else
1675 		{
1676 			// Copy color
1677 			const VkImageSubresourceLayers imageSubresourceLayers	=
1678 			{
1679 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
1680 				0u,							// deUint32				mipLevel
1681 				0u,							// deUint32				baseArrayLayer
1682 				1u							// deUint32				layerCount
1683 			};
1684 
1685 			const VkBufferImageCopy			region					=
1686 			{
1687 				0u,							// VkDeviceSize				bufferOffset
1688 				0u,							// uint32_t					bufferRowLength
1689 				0u,							// uint32_t					bufferImageHeight
1690 				imageSubresourceLayers,		// VkImageSubresourceLayers	imageSubresource
1691 				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
1692 				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
1693 			};
1694 
1695 			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &region);
1696 		}
1697 	}
1698 
1699 	// Memory barrier between copy and host access
1700 	{
1701 		const VkBufferMemoryBarrier barrier		=
1702 		{
1703 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
1704 			DE_NULL,									// const void*		pNext
1705 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
1706 			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
1707 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
1708 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
1709 			*m_primaryBuffer,							// VkBuffer			buffer
1710 			0u,											// VkDeviceSize		offset
1711 			VK_WHOLE_SIZE								// VkDeviceSize		size
1712 		};
1713 
1714 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1715 
1716 		if (isDepthStencilFormat(m_format))
1717 		{
1718 			const VkBufferMemoryBarrier stencilBarrier =
1719 			{
1720 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
1721 				DE_NULL,									// const void*		pNext
1722 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
1723 				VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
1724 				VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
1725 				VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
1726 				*m_secondaryBuffer,							// VkBuffer			buffer
1727 				0u,											// VkDeviceSize		offset
1728 				VK_WHOLE_SIZE								// VkDeviceSize		size
1729 			};
1730 
1731 			vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &stencilBarrier, 0u, DE_NULL);
1732 		}
1733 	}
1734 
1735 	endCommandBuffer(vkd, *commandBuffer);
1736 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
1737 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_primaryBufferMemory->getMemory(), m_primaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1738 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1739 
1740 	// Verify result
1741 	{
1742 		const tcu::TextureFormat format (mapVkFormat(m_format));
1743 
1744 		if (isDepthStencilFormat(m_format))
1745 		{
1746 			const void* const					ptrDepth				(m_primaryBufferMemory->getHostPtr());
1747 			const void* const					ptrStencil				(m_secondaryBufferMemory->getHostPtr());
1748 			tcu::TextureLevel					reference				(format, m_width, m_height);
1749 			tcu::TextureLevel					colorBuffer				(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), m_width, m_height);
1750 			const tcu::ConstPixelBufferAccess	resultDepthAccess		(getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
1751 			const tcu::ConstPixelBufferAccess	resultStencilAccess		(getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
1752 			const PixelBufferAccess				referenceDepthAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
1753 			const PixelBufferAccess				referenceStencilAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
1754 
1755 			tcu::clearDepth(referenceDepthAccess, 1.0f);
1756 			tcu::clearStencil(referenceStencilAccess, 255);
1757 
1758 			// Setup and run reference renderer
1759 			{
1760 				const DepthVertShader					vertShader;
1761 				const DepthFragShader					fragShader;
1762 				const rr::Renderer						renderer;
1763 				const rr::Program						program				(&vertShader, &fragShader);
1764 				const rr::MultisamplePixelBufferAccess	depthBuffer			(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceDepthAccess));
1765 				const rr::MultisamplePixelBufferAccess	colorBufferAccess	(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(colorBuffer.getAccess()));
1766 				const rr::RenderTarget					renderTarget		(rr::MultisamplePixelBufferAccess(colorBufferAccess), depthBuffer, rr::MultisamplePixelBufferAccess());
1767 				const rr::PrimitiveType					primitiveType		(rr::PRIMITIVETYPE_TRIANGLES);
1768 				const rr::PrimitiveList					primitiveList		(rr::PrimitiveList(primitiveType, (deUint32)vertexData.size(), 0));
1769 				rr::RenderState							renderState			((rr::ViewportState(depthBuffer)), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1770 
1771 				const rr::VertexAttrib vertices			= rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertexData[0]);
1772 
1773 				renderState.fragOps.depthTestEnabled	= DE_TRUE;
1774 				renderState.fragOps.depthFunc			= rr::TESTFUNC_LEQUAL;
1775 
1776 				renderer.draw(rr::DrawCommand(renderState,
1777 											  renderTarget,
1778 											  program,
1779 											  1u,
1780 											  &vertices,
1781 											  primitiveList));
1782 			}
1783 
1784 			for (size_t subpassNdx = 0; subpassNdx < subpassCount - 1; subpassNdx++)
1785 			{
1786 				for (int y = 0; y < reference.getHeight(); y++)
1787 				for (int x = 0; x < reference.getWidth(); x++)
1788 					reference.getAccess().setPixDepth(reference.getAccess().getPixDepth(x, y) - 0.02f, x, y);
1789 			}
1790 
1791 			// Threshold size of subpass count multiplied by the minimum representable difference is allowed for depth compare
1792 			const float							depthThreshold			((float)subpassCount * (1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(
1793 																			resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x()));
1794 
1795 			if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
1796 				m_resultCollector.fail("Depth compare failed.");
1797 
1798 			if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
1799 				m_resultCollector.fail("Stencil compare failed.");
1800 		}
1801 		else
1802 			DE_FATAL("Not implemented");
1803 	}
1804 
1805 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1806 }
1807 
1808 struct SubpassSelfDependencyBackwardsTestConfig
1809 {
SubpassSelfDependencyBackwardsTestConfigvkt::__anon675baf4b0111::SubpassSelfDependencyBackwardsTestConfig1810 		SubpassSelfDependencyBackwardsTestConfig	(VkFormat		format_,
1811 													 UVec2			imageSize_,
1812 													 RenderPassType	renderPassType_)
1813 		: format			(format_)
1814 		, imageSize			(imageSize_)
1815 		, renderPassType	(renderPassType_)
1816 	{
1817 	}
1818 
1819 	VkFormat		format;
1820 	UVec2			imageSize;
1821 	RenderPassType	renderPassType;
1822 };
1823 
1824 class SubpassSelfDependencyBackwardsTestInstance : public TestInstance
1825 {
1826 public:
1827 							SubpassSelfDependencyBackwardsTestInstance	(Context&									context,
1828 																		 SubpassSelfDependencyBackwardsTestConfig	testConfig);
1829 
1830 							~SubpassSelfDependencyBackwardsTestInstance	(void);
1831 
1832 	tcu::TestStatus			iterate										(void);
1833 
1834 	template<typename RenderpassSubpass>
1835 	tcu::TestStatus			iterateInternal								(void);
1836 
1837 private:
1838 	const bool				m_extensionSupported;
1839 	const bool				m_featuresSupported;
1840 	const RenderPassType	m_renderPassType;
1841 
1842 	const deUint32			m_width;
1843 	const deUint32			m_height;
1844 	const VkFormat			m_format;
1845 	tcu::ResultCollector	m_resultCollector;
1846 };
1847 
SubpassSelfDependencyBackwardsTestInstance(Context & context,SubpassSelfDependencyBackwardsTestConfig testConfig)1848 SubpassSelfDependencyBackwardsTestInstance::SubpassSelfDependencyBackwardsTestInstance (Context& context, SubpassSelfDependencyBackwardsTestConfig testConfig)
1849 	: TestInstance			(context)
1850 	, m_extensionSupported	((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1851 	, m_featuresSupported	(context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
1852 	, m_renderPassType		(testConfig.renderPassType)
1853 	, m_width				(testConfig.imageSize.x())
1854 	, m_height				(testConfig.imageSize.y())
1855 	, m_format				(testConfig.format)
1856 {
1857 }
1858 
~SubpassSelfDependencyBackwardsTestInstance(void)1859 SubpassSelfDependencyBackwardsTestInstance::~SubpassSelfDependencyBackwardsTestInstance (void)
1860 {
1861 }
1862 
iterate(void)1863 tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterate (void)
1864 {
1865 	switch (m_renderPassType)
1866 	{
1867 		case RENDERPASS_TYPE_LEGACY:
1868 			return iterateInternal<RenderpassSubpass1>();
1869 		case RENDERPASS_TYPE_RENDERPASS2:
1870 			return iterateInternal<RenderpassSubpass2>();
1871 		default:
1872 			TCU_THROW(InternalError, "Impossible");
1873 	}
1874 }
1875 
1876 template<typename RenderpassSubpass>
iterateInternal(void)1877 tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterateInternal (void)
1878 {
1879 	de::Random											rand					(5);
1880 	const DeviceInterface&								vkd						(m_context.getDeviceInterface());
1881 	const VkDevice										device					= m_context.getDevice();
1882 	const deUint32										queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
1883 	const Unique<VkCommandPool>							commandPool				(createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
1884 	const Unique<VkCommandBuffer>						commandBuffer			(allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1885 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo		(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1886 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
1887 	vector<Vec4>										vertexData;
1888 	Move<VkImage>										outputImage;
1889 	de::MovePtr<Allocation>								outputImageAllocation;
1890 	Move<VkImageView>									outputImageView;
1891 	Move<VkPipelineLayout>								pipelineLayout;
1892 	Move<VkPipeline>									renderPipeline;
1893 	Move<VkFramebuffer>									framebuffer;
1894 	Move<VkRenderPass>									renderPass;
1895 	Move<VkBuffer>										indirectBuffer;
1896 	de::MovePtr<Allocation>								indirectBufferMemory;
1897 	Move<VkBuffer>										resultBuffer;
1898 	de::MovePtr<Allocation>								resultBufferMemory;
1899 	const VkDeviceSize									indirectBufferSize		= 4 * sizeof(deUint32);
1900 	Move<VkBuffer>										vertexBuffer;
1901 	de::MovePtr<Allocation>								vertexBufferMemory;
1902 
1903 	// Create output image.
1904 	{
1905 		const VkExtent3D		imageExtent		=
1906 		{
1907 			m_width,	// uint32_t	width
1908 			m_height,	// uint32_t	height
1909 			1u			// uint32_t	depth
1910 		};
1911 
1912 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1913 
1914 		const VkImageCreateInfo	imageCreateInfo	=
1915 		{
1916 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
1917 			DE_NULL,								// const void*				pNext
1918 			0u,										// VkImageCreateFlags		flags
1919 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
1920 			m_format,								// VkFormat					format
1921 			imageExtent,							// VkExtent3D				extent
1922 			1u,										// uint32_t					mipLevels
1923 			1u,										// uint32_t					arrayLayers
1924 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
1925 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
1926 			usage,									// VkImageUsageFlags		usage
1927 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
1928 			1u,										// uint32_t					queueFamilyIndexCount
1929 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
1930 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
1931 		};
1932 
1933 		outputImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
1934 		outputImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *outputImage), MemoryRequirement::Any);
1935 		VK_CHECK(vkd.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(), outputImageAllocation->getOffset()));
1936 	}
1937 
1938 	// Create indirect buffer and initialize.
1939 	{
1940 		const VkBufferUsageFlags	bufferUsage	(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1941 		const VkBufferCreateInfo	bufferCreateInfo	=
1942 		{
1943 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
1944 			DE_NULL,								// const void*			pNext
1945 			0u,										// VkBufferCreateFlags	flags
1946 			indirectBufferSize,						// VkDeviceSize			size
1947 			bufferUsage,							// VkBufferUsageFlags	usage
1948 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
1949 			0u,										// uint32_t				queueFamilyIndexCount
1950 			DE_NULL									// const uint32_t*		pQueueFamilyIndices
1951 		};
1952 
1953 		indirectBuffer			= createBuffer(vkd, device, &bufferCreateInfo);
1954 		indirectBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *indirectBuffer);
1955 
1956 		VkDrawIndirectCommand	drawIndirectCommand	=
1957 		{
1958 			64u,	// deUint32	vertexCount
1959 			1u,		// deUint32	instanceCount
1960 			0u,		// deUint32	firstVertex
1961 			0u,		// deUint32	firstInstance
1962 		};
1963 
1964 		deMemcpy(indirectBufferMemory->getHostPtr(), (void*)&drawIndirectCommand, sizeof(VkDrawIndirectCommand));
1965 		flushAlloc(vkd, device, *indirectBufferMemory);
1966 	}
1967 
1968 	// Create result buffer.
1969 	{
1970 		resultBuffer		= createBuffer(vkd, device, m_format, m_width, m_height);
1971 		resultBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
1972 	}
1973 
1974 	// Create descriptor set layout.
1975 	Unique<VkDescriptorSetLayout>	descriptorSetLayout	(DescriptorSetLayoutBuilder()
1976 			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
1977 			.build(vkd, device));
1978 	// Create descriptor pool.
1979 	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
1980 			.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
1981 			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1982 	// Create descriptor set.
1983 	Unique<VkDescriptorSet>			descriptorSet		(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));
1984 
1985 	// Update descriptor set information.
1986 	{
1987 		VkDescriptorBufferInfo descIndirectBuffer = makeDescriptorBufferInfo(*indirectBuffer, 0, indirectBufferSize);
1988 
1989 		DescriptorSetUpdateBuilder()
1990 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descIndirectBuffer)
1991 			.update(vkd, device);
1992 	}
1993 
1994 	// Create render pipeline layout.
1995 	{
1996 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1997 		{
1998 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
1999 			DE_NULL,										// const void*					pNext
2000 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
2001 			1u,												// deUint32						setLayoutCount
2002 			&*descriptorSetLayout,							// const VkDescriptorSetLayout*	pSetLayouts
2003 			0u,												// deUint32						pushConstantRangeCount
2004 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
2005 		};
2006 
2007 		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
2008 	}
2009 
2010 	// Create render pass.
2011 	{
2012 		vector<Attachment>			attachments;
2013 		vector<AttachmentReference>	colorAttachmentReferences;
2014 
2015 		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
2016 		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
2017 
2018 		const vector<Subpass>		subpasses	(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
2019 		vector<SubpassDependency>	deps;
2020 
2021 		deps.push_back(SubpassDependency(0u,									// deUint32				srcPass
2022 										 0u,									// deUint32				dstPass
2023 										 VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,	// VkPipelineStageFlags	srcStageMask
2024 										 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,	// VkPipelineStageFlags	dstStageMask
2025 										 VK_ACCESS_SHADER_WRITE_BIT,			// VkAccessFlags		srcAccessMask
2026 										 VK_ACCESS_INDIRECT_COMMAND_READ_BIT,	// VkAccessFlags		dstAccessMask
2027 										 0));									// VkDependencyFlags	flags
2028 
2029 		renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, deps), m_renderPassType);
2030 	}
2031 
2032 	// Create render pipeline.
2033 	{
2034 		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
2035 		const Unique<VkShaderModule>				geometryShaderModule		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("geom"), 0u));
2036 		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));
2037 
2038 		const VkVertexInputBindingDescription		vertexBinding0				=
2039 		{
2040 			0u,							// deUint32					binding;
2041 			sizeof(Vec4),				// deUint32					strideInBytes;
2042 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
2043 		};
2044 
2045 		VkVertexInputAttributeDescription			attr0						=
2046 		{
2047 			0u,								// deUint32	location;
2048 			0u,								// deUint32	binding;
2049 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
2050 			0u								// deUint32	offsetInBytes;
2051 		};
2052 
2053 		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
2054 		{
2055 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
2056 			DE_NULL,													// const void*								pNext
2057 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
2058 			1u,															// uint32_t									vertexBindingDescriptionCount
2059 			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
2060 			1u,															// uint32_t									vertexAttributeDescriptionCount
2061 			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
2062 		};
2063 
2064 		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(m_width, m_height)));
2065 		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(m_width, m_height)));
2066 
2067 		renderPipeline = makeGraphicsPipeline(vkd,	// const DeviceInterface&						vk
2068 				device,								// const VkDevice								device
2069 				*pipelineLayout,					// const VkPipelineLayout						pipelineLayout
2070 				*vertexShaderModule,				// const VkShaderModule							vertexShaderModule
2071 				DE_NULL,							// const VkShaderModule							tessellationControlShaderModule
2072 				DE_NULL,							// const VkShaderModule							tessellationEvalShaderModule
2073 				*geometryShaderModule,				// const VkShaderModule							geometryShaderModule
2074 				*fragmentShaderModule,				// const VkShaderModule							fragmentShaderModule
2075 				*renderPass,						// const VkRenderPass							renderPass
2076 				viewports,							// const std::vector<VkViewport>&				viewports
2077 				scissors,							// const std::vector<VkRect2D>&					scissors
2078 				VK_PRIMITIVE_TOPOLOGY_POINT_LIST,	// const VkPrimitiveTopology					topology
2079 				0u,									// const deUint32								subpass
2080 				0u,									// const deUint32								patchControlPoints
2081 				&vertexInputState);					// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
2082 	}
2083 
2084 	// Create framebuffer.
2085 	{
2086 		const VkImageViewCreateInfo imageViewCreateInfo =
2087 		{
2088 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
2089 			DE_NULL,									// const void*				pNext
2090 			0u,											// VkImageViewCreateFlags	flags
2091 			*outputImage,								// VkImage					image
2092 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
2093 			m_format,									// VkFormat					format
2094 			makeComponentMappingRGBA(),					// VkComponentMapping		components
2095 			{											// VkImageSubresourceRange	subresourceRange
2096 				VK_IMAGE_ASPECT_COLOR_BIT,
2097 				0u,
2098 				1u,
2099 				0u,
2100 				1u
2101 			}
2102 		};
2103 		outputImageView	= createImageView(vkd, device, &imageViewCreateInfo);
2104 
2105 		const VkFramebufferCreateInfo framebufferCreateInfo =
2106 		{
2107 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
2108 			DE_NULL,									// const void*				pNext
2109 			0u,											// VkFramebufferCreateFlags	flags
2110 			*renderPass,								// VkRenderPass				renderPass
2111 			1u,											// uint32_t					attachmentCount
2112 			&*outputImageView,							// const VkImageView*		pAttachments
2113 			m_width,									// uint32_t					width
2114 			m_height,									// uint32_t					height
2115 			1u											// uint32_t					layers
2116 		};
2117 
2118 		framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2119 	}
2120 
2121 	// Generate random point locations (pixel centered to make reference comparison easier).
2122 	for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
2123 	{
2124 		vertexData.push_back(Vec4((float)((rand.getUint32() % m_width) * 2) / (float)m_width - 1.0f,
2125 				(float)((rand.getUint32() % m_height) * 2) / (float)m_height - 1.0f,
2126 				1.0f, 1.0f));
2127 	}
2128 
2129 	// Upload vertex data.
2130 	{
2131 		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);
2132 
2133 		const VkBufferCreateInfo	vertexBufferParams	=
2134 		{
2135 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType;
2136 			DE_NULL,								//	const void*			pNext;
2137 			0u,										//	VkBufferCreateFlags	flags;
2138 			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size;
2139 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage;
2140 			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode;
2141 			1u,										//	deUint32			queueFamilyCount;
2142 			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices;
2143 		};
2144 
2145 		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2146 		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
2147 
2148 		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2149 		flushAlloc(vkd, device, *vertexBufferMemory);
2150 	}
2151 
2152 	beginCommandBuffer(vkd, *commandBuffer);
2153 	vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2154 	vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2155 
2156 	// Begin render pass.
2157 	{
2158 		VkRect2D					renderArea	=
2159 		{
2160 			{ 0u, 0u },				// VkOffset2D	offset
2161 			{ m_width, m_height }	// VkExtent2D	extent
2162 		};
2163 
2164 		VkClearValue				clearValue	= makeClearValueColor(Vec4(0.0f, 1.0f, 0.0f, 1.0f));
2165 
2166 		const VkRenderPassBeginInfo	beginInfo	=
2167 		{
2168 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
2169 			DE_NULL,									// const void*			pNext
2170 			*renderPass,								// VkRenderPass			renderPass
2171 			*framebuffer,								// VkFramebuffer		framebuffer
2172 			renderArea,									// VkRect2D				renderArea
2173 			1u,											// uint32_t				clearValueCount
2174 			&clearValue									// const VkClearValue*	pClearValues
2175 		};
2176 
2177 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2178 	}
2179 
2180 	const VkDeviceSize bindingOffset = 0;
2181 	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
2182 
2183 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2184 
2185 	// The first indirect draw: Draw the first 64 items.
2186 	vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);
2187 
2188 	// Barrier for indirect buffer.
2189 	{
2190 		const VkMemoryBarrier barrier =
2191 		{
2192 			VK_STRUCTURE_TYPE_MEMORY_BARRIER,	// VkStructureType	sType
2193 			DE_NULL,							// const void*		pNext
2194 			VK_ACCESS_SHADER_WRITE_BIT,			// VkAccessFlags	srcAccessMask
2195 			VK_ACCESS_INDIRECT_COMMAND_READ_BIT	// VkAccessFlags	dstAccessMask
2196 		};
2197 
2198 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
2199 	}
2200 
2201 	// The second indirect draw: Draw the last 64 items.
2202 	vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);
2203 
2204 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2205 
2206 	// Copy results to a buffer.
2207 	copyImageToBuffer(vkd, *commandBuffer, *outputImage, *resultBuffer, tcu::IVec2(m_width, m_height));
2208 
2209 	endCommandBuffer(vkd, *commandBuffer);
2210 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
2211 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(), resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
2212 
2213 	// Verify result.
2214 	{
2215 		const tcu::TextureFormat format (mapVkFormat(m_format));
2216 
2217 		const void* const					ptrResult		(resultBufferMemory->getHostPtr());
2218 		tcu::TextureLevel					reference		(format, m_width, m_height);
2219 		const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
2220 		const PixelBufferAccess				referenceAccess	(reference.getAccess());
2221 
2222 
2223 		// Setup and run reference renderer.
2224 		{
2225 			vector<Vec4>							triangles;
2226 			const float								offset			= 0.03f;
2227 
2228 			// Convert points into triangles to have quads similar to what GPU is producing from geometry shader.
2229 			for (size_t vtxIdx = 0; vtxIdx < vertexData.size(); vtxIdx++)
2230 			{
2231 				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, offset, 0.0f, 0.0f));
2232 				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
2233 				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));
2234 
2235 				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
2236 				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));
2237 				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, -offset, 0.0f, 0.0f));
2238 			}
2239 
2240 			const SelfDependencyBackwardsVertShader	vertShader;
2241 			const SelfDependencyBackwardsFragShader	fragShader;
2242 			const rr::Renderer						renderer;
2243 			const rr::Program						program			(&vertShader, &fragShader);
2244 			const rr::MultisamplePixelBufferAccess	msAccess		(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceAccess));
2245 			const rr::RenderTarget					renderTarget	(msAccess);
2246 			const rr::PrimitiveType					primitiveType	(rr::PRIMITIVETYPE_TRIANGLES);
2247 			const rr::PrimitiveList					primitiveList	(rr::PrimitiveList(primitiveType, (deUint32)triangles.size(), 0));
2248 			const rr::ViewportState					viewportState	(msAccess);
2249 			const rr::RenderState					renderState		(viewportState, m_context.getDeviceProperties().limits.subPixelPrecisionBits);
2250 			const rr::VertexAttrib					vertices		= rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &triangles[0]);
2251 
2252 			tcu::clear(referenceAccess, tcu::UVec4(0, 255, 0, 255));
2253 			renderer.draw(rr::DrawCommand(renderState, renderTarget, program, 1u, &vertices, primitiveList));
2254 		}
2255 
2256 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
2257 										"Color buffer",							// imageSetName
2258 										"",										// imageSetDesc
2259 										referenceAccess,						// reference
2260 										resultAccess,							// result
2261 										Vec4(0.01f),							// threshold
2262 										tcu::COMPARE_LOG_RESULT))				// logMode
2263 		{
2264 			m_resultCollector.fail("Image compare failed.");
2265 		}
2266 	}
2267 
2268 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2269 }
2270 
2271 struct SeparateChannelsTestConfig
2272 {
SeparateChannelsTestConfigvkt::__anon675baf4b0111::SeparateChannelsTestConfig2273 		SeparateChannelsTestConfig	(VkFormat		format_,
2274 									 RenderPassType	renderPassType_)
2275 		: format			(format_)
2276 		, renderPassType	(renderPassType_)
2277 	{
2278 	}
2279 
2280 	VkFormat		format;
2281 	RenderPassType	renderPassType;
2282 };
2283 
2284 class SeparateChannelsTestInstance : public TestInstance
2285 {
2286 public:
2287 							SeparateChannelsTestInstance	(Context&					context,
2288 															 SeparateChannelsTestConfig	testConfig);
2289 
2290 							~SeparateChannelsTestInstance	(void);
2291 
2292 	tcu::TestStatus			iterate							(void);
2293 
2294 	template<typename RenderpassSubpass>
2295 	tcu::TestStatus			iterateInternal					(void);
2296 
2297 private:
2298 	const bool				m_extensionSupported;
2299 	const RenderPassType	m_renderPassType;
2300 
2301 	const deUint32			m_width;
2302 	const deUint32			m_height;
2303 	const VkFormat			m_format;
2304 	tcu::ResultCollector	m_resultCollector;
2305 };
2306 
SeparateChannelsTestInstance(Context & context,SeparateChannelsTestConfig testConfig)2307 SeparateChannelsTestInstance::SeparateChannelsTestInstance (Context& context, SeparateChannelsTestConfig testConfig)
2308 	: TestInstance			(context)
2309 	, m_extensionSupported	((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
2310 	, m_renderPassType		(testConfig.renderPassType)
2311 	, m_width				(256u)
2312 	, m_height				(256u)
2313 	, m_format				(testConfig.format)
2314 {
2315 }
2316 
~SeparateChannelsTestInstance(void)2317 SeparateChannelsTestInstance::~SeparateChannelsTestInstance (void)
2318 {
2319 }
2320 
iterate(void)2321 tcu::TestStatus SeparateChannelsTestInstance::iterate (void)
2322 {
2323 	switch (m_renderPassType)
2324 	{
2325 		case RENDERPASS_TYPE_LEGACY:
2326 			return iterateInternal<RenderpassSubpass1>();
2327 		case RENDERPASS_TYPE_RENDERPASS2:
2328 			return iterateInternal<RenderpassSubpass2>();
2329 		default:
2330 			TCU_THROW(InternalError, "Impossible");
2331 	}
2332 }
2333 
2334 template<typename RenderpassSubpass>
iterateInternal(void)2335 tcu::TestStatus SeparateChannelsTestInstance::iterateInternal (void)
2336 {
2337 	const DeviceInterface&								vkd						(m_context.getDeviceInterface());
2338 	const VkDevice										device					= m_context.getDevice();
2339 	const VkQueue										queue					= m_context.getUniversalQueue();
2340 	const deUint32										queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
2341 	const Unique<VkCommandPool>							commandPool				(createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2342 	const Unique<VkCommandBuffer>						commandBuffer			(allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2343 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo		(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2344 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
2345 	const bool											isDSFormat				= isDepthStencilFormat(m_format);
2346 	const VkFormat										colorFormat				= isDSFormat ? VK_FORMAT_R8G8B8A8_UNORM : m_format;
2347 	const tcu::Vec4										colorInitValues[2]		= { tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f) };
2348 	const float											depthInitValues[2]		= { 0.3f, 0.7f };
2349 	const deUint32										stencilInitValues[2]	= { 2u, 100u };
2350 	const deUint32										stencilRefValue			= 200u;
2351 	const deUint32										tileSize				= 32u;
2352 	vector<Vec4>										vertexData;
2353 	Move<VkImage>										colorImage;
2354 	de::MovePtr<Allocation>								colorImageAllocation;
2355 	// When testing color formats the same attachment is used as input and output. This requires general layout to be used.
2356 	const VkImageLayout									colorImageLayout		= isDSFormat ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
2357 	Move<VkImage>										dsImage;
2358 	de::MovePtr<Allocation>								dsImageAllocation;
2359 	Move<VkImageView>									outputImageView;
2360 	Move<VkImageView>									inputImageView;
2361 	Move<VkImageView>									dsImageView;
2362 	Move<VkPipelineLayout>								pipelineLayout;
2363 	Move<VkPipeline>									renderPipeline;
2364 	Move<VkFramebuffer>									framebuffer;
2365 	Move<VkRenderPass>									renderPass;
2366 	Move<VkBuffer>										resultBuffer0;
2367 	de::MovePtr<Allocation>								resultBuffer0Memory;
2368 	Move<VkBuffer>										resultBuffer1;
2369 	de::MovePtr<Allocation>								resultBuffer1Memory;
2370 	Move<VkBuffer>										vertexBuffer;
2371 	de::MovePtr<Allocation>								vertexBufferMemory;
2372 
2373 	const VkExtent3D		imageExtent		=
2374 	{
2375 		m_width,	// deUint32	width
2376 		m_height,	// deUint32	height
2377 		1u			// deUint32	depth
2378 	};
2379 
2380 	// Create image used for both input and output in case of color test, and as a color output in depth/stencil test.
2381 	{
2382 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2383 
2384 		const VkImageCreateInfo	imageCreateInfo	=
2385 		{
2386 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2387 			DE_NULL,								// const void*				pNext
2388 			0u,										// VkImageCreateFlags		flags
2389 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2390 			colorFormat,							// VkFormat					format
2391 			imageExtent,							// VkExtent3D				extent
2392 			1u,										// uint32_t					mipLevels
2393 			1u,										// uint32_t					arrayLayers
2394 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2395 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2396 			usage,									// VkImageUsageFlags		usage
2397 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2398 			1u,										// uint32_t					queueFamilyIndexCount
2399 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
2400 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2401 		};
2402 
2403 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2404 
2405 		colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2406 		colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
2407 		VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
2408 	}
2409 
2410 	// Create depth/stencil image
2411 	if (isDSFormat)
2412 	{
2413 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2414 
2415 		const VkImageCreateInfo	imageCreateInfo	=
2416 		{
2417 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2418 			DE_NULL,								// const void*				pNext
2419 			0u,										// VkImageCreateFlags		flags
2420 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2421 			m_format,								// VkFormat					format
2422 			imageExtent,							// VkExtent3D				extent
2423 			1u,										// uint32_t					mipLevels
2424 			1u,										// uint32_t					arrayLayers
2425 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2426 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2427 			usage,									// VkImageUsageFlags		usage
2428 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2429 			1u,										// uint32_t					queueFamilyIndexCount
2430 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
2431 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2432 		};
2433 
2434 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2435 
2436 		dsImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2437 		dsImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *dsImage), MemoryRequirement::Any);
2438 		VK_CHECK(vkd.bindImageMemory(device, *dsImage, dsImageAllocation->getMemory(), dsImageAllocation->getOffset()));
2439 
2440 		// Initialize depth / stencil image
2441 		initDepthStencilImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *dsImage, m_format, depthInitValues[0], depthInitValues[1], stencilInitValues[0], stencilInitValues[1], m_width, m_height, tileSize, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
2442 	}
2443 
2444 	// Initialize color image
2445 	initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *colorImage, colorFormat, colorInitValues[0], colorInitValues[1], m_width, m_height, tileSize, VK_IMAGE_LAYOUT_UNDEFINED, colorImageLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
2446 
2447 	// Create color image views
2448 	{
2449 		const VkImageViewCreateInfo imageViewCreateInfo =
2450 		{
2451 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
2452 			DE_NULL,									// const void*				pNext
2453 			0u,											// VkImageViewCreateFlags	flags
2454 			*colorImage,								// VkImage					image
2455 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
2456 			colorFormat,								// VkFormat					format
2457 			makeComponentMappingRGBA(),					// VkComponentMapping		components
2458 			{											// VkImageSubresourceRange	subresourceRange
2459 				VK_IMAGE_ASPECT_COLOR_BIT,
2460 				0u,
2461 				1u,
2462 				0u,
2463 				1u
2464 			}
2465 		};
2466 
2467 		if (!isDSFormat) inputImageView	= createImageView(vkd, device, &imageViewCreateInfo);
2468 		outputImageView	= createImageView(vkd, device, &imageViewCreateInfo);
2469 	}
2470 
2471 	// Create depth/stencil image view
2472 	if (isDSFormat)
2473 	{
2474 		const VkImageViewCreateInfo imageViewCreateInfo =
2475 		{
2476 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
2477 			DE_NULL,									// const void*				pNext
2478 			0u,											// VkImageViewCreateFlags	flags
2479 			*dsImage,									// VkImage					image
2480 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
2481 			m_format,									// VkFormat					format
2482 			makeComponentMappingRGBA(),					// VkComponentMapping		components
2483 			{											// VkImageSubresourceRange	subresourceRange
2484 				VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
2485 				0u,
2486 				1u,
2487 				0u,
2488 				1u
2489 			}
2490 		};
2491 
2492 		dsImageView	= createImageView(vkd, device, &imageViewCreateInfo);
2493 	}
2494 
2495 	// Create result buffers.
2496 	{
2497 		resultBuffer0		= createBuffer(vkd, device, m_format, m_width, m_height);
2498 		resultBuffer0Memory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer0);
2499 		resultBuffer1		= createBuffer(vkd, device, m_format, m_width, m_height);
2500 		resultBuffer1Memory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer1);
2501 	}
2502 
2503 	// Create descriptor set layout.
2504 	Unique<VkDescriptorSetLayout>	descriptorSetLayout	(DescriptorSetLayoutBuilder()
2505 			.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
2506 			.build(vkd, device));
2507 	// Create descriptor pool.
2508 	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
2509 			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
2510 			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
2511 	// Create descriptor set.
2512 	Unique<VkDescriptorSet>			descriptorSet		(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));
2513 
2514 	// Update descriptor set information.
2515 	if (!isDSFormat)
2516 	{
2517 		VkDescriptorImageInfo descInputAttachment = makeDescriptorImageInfo(DE_NULL, *inputImageView, VK_IMAGE_LAYOUT_GENERAL);
2518 
2519 		DescriptorSetUpdateBuilder()
2520 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descInputAttachment)
2521 			.update(vkd, device);
2522 	}
2523 
2524 	// Create render pipeline layout.
2525 	{
2526 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
2527 		{
2528 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
2529 			DE_NULL,										// const void*					pNext
2530 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
2531 			1u,												// deUint32						setLayoutCount
2532 			&*descriptorSetLayout,							// const VkDescriptorSetLayout*	pSetLayouts
2533 			0u,												// deUint32						pushConstantRangeCount
2534 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
2535 		};
2536 
2537 		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
2538 	}
2539 
2540 	// Create render pass.
2541 	{
2542 		vector<Attachment>			attachments;
2543 		vector<AttachmentReference>	colorAttachmentReferences;
2544 		vector<AttachmentReference>	inputAttachmentReferences;
2545 		AttachmentReference			dsAttachmentReference		(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
2546 
2547 		const VkImageAspectFlags	inputAttachmentAspectMask	((m_renderPassType == RENDERPASS_TYPE_RENDERPASS2)
2548 																? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
2549 																: static_cast<VkImageAspectFlags>(0));
2550 
2551 		attachments.push_back(Attachment(colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, colorImageLayout, colorImageLayout));
2552 		colorAttachmentReferences.push_back(AttachmentReference(0u, colorImageLayout));
2553 
2554 		if (isDSFormat)
2555 		{
2556 			attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
2557 		}
2558 		else
2559 		{
2560 			attachments.push_back(Attachment(colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
2561 			inputAttachmentReferences.push_back(AttachmentReference(1u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
2562 		}
2563 
2564 		const vector<Subpass>		subpasses	(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences, colorAttachmentReferences, vector<AttachmentReference>(), isDSFormat ? dsAttachmentReference : AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
2565 
2566 		renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()), m_renderPassType);
2567 	}
2568 
2569 	// Create render pipeline.
2570 	{
2571 		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
2572 		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));
2573 
2574 		const VkVertexInputBindingDescription		vertexBinding0				=
2575 		{
2576 			0u,							// deUint32					binding
2577 			sizeof(Vec4),				// deUint32					strideInBytes
2578 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate
2579 		};
2580 
2581 		const VkVertexInputAttributeDescription		attr0						=
2582 		{
2583 			0u,								// deUint32	location
2584 			0u,								// deUint32	binding
2585 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
2586 			0u								// deUint32	offsetInBytes
2587 		};
2588 
2589 		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
2590 		{
2591 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
2592 			DE_NULL,													// const void*								pNext
2593 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
2594 			1u,															// deUint32									vertexBindingDescriptionCount
2595 			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
2596 			1u,															// deUint32									vertexAttributeDescriptionCount
2597 			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
2598 		};
2599 
2600 		// Use write mask to enable only B and A channels to prevent self dependency (reads are done for channels R and G).
2601 		const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState	=
2602 		{
2603 			VK_FALSE,					// VkBool32					blendEnable
2604 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcColorBlendFactor
2605 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstColorBlendFactor
2606 			VK_BLEND_OP_ADD,			// VkBlendOp				colorBlendOp
2607 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcAlphaBlendFactor
2608 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstAlphaBlendFactor
2609 			VK_BLEND_OP_ADD,			// VkBlendOp				alphaBlendOp
2610 			VK_COLOR_COMPONENT_B_BIT
2611 			| VK_COLOR_COMPONENT_A_BIT	// VkColorComponentFlags	colorWriteMask
2612 		};
2613 
2614 		const VkPipelineColorBlendStateCreateInfo	colorBlendState				=
2615 		{
2616 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType
2617 			DE_NULL,													// const void*									pNext
2618 			0u,															// VkPipelineColorBlendStateCreateFlags			flags
2619 			VK_FALSE,													// VkBool32										logicOpEnable
2620 			VK_LOGIC_OP_CLEAR,											// VkLogicOp									logicOp
2621 			1u,															// deUint32										attachmentCount
2622 			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments
2623 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4]
2624 		};
2625 
2626 		const VkStencilOpState						stencilOpState				=
2627 		{
2628 			VK_STENCIL_OP_REPLACE,	// VkStencilOp	failOp
2629 			VK_STENCIL_OP_REPLACE,	// VkStencilOp	passOp
2630 			VK_STENCIL_OP_ZERO,		// VkStencilOp	depthFailOp
2631 			VK_COMPARE_OP_ALWAYS,	// VkCompareOp	compareOp
2632 			0xff,					// deUint32		compareMask
2633 			0xff,					// deUint32		writeMask
2634 			stencilRefValue			// deUint32		reference
2635 		};
2636 
2637 		const VkPipelineDepthStencilStateCreateInfo	depthStencilState			=
2638 		{
2639 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType
2640 			DE_NULL,													// const void*								pNext
2641 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags
2642 			VK_TRUE,													// VkBool32									depthTestEnable
2643 			VK_FALSE,													// VkBool32									depthWriteEnable
2644 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp
2645 			VK_FALSE,													// VkBool32									depthBoundsTestEnable
2646 			VK_TRUE,													// VkBool32									stencilTestEnable
2647 			stencilOpState,												// VkStencilOpState							front
2648 			stencilOpState,												// VkStencilOpState							back
2649 			0.0f,														// float									minDepthBounds
2650 			1.0f														// float									maxDepthBounds
2651 		};
2652 
2653 		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(m_width, m_height)));
2654 		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(m_width, m_height)));
2655 
2656 		renderPipeline = makeGraphicsPipeline(vkd,			// const DeviceInterface&							vk
2657 				device,										// const VkDevice									device
2658 				*pipelineLayout,							// const VkPipelineLayout							pipelineLayout
2659 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
2660 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
2661 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
2662 				DE_NULL,									// const VkShaderModule								geometryShaderModule
2663 				*fragmentShaderModule,						// const VkShaderModule								fragmentShaderModule
2664 				*renderPass,								// const VkRenderPass								renderPass
2665 				viewports,									// const std::vector<VkViewport>&					viewports
2666 				scissors,									// const std::vector<VkRect2D>&						scissors
2667 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
2668 				0u,											// const deUint32									subpass
2669 				0u,											// const deUint32									patchControlPoints
2670 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
2671 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
2672 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
2673 				isDSFormat ? &depthStencilState : DE_NULL,	// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
2674 				isDSFormat ? DE_NULL : &colorBlendState);	// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
2675 	}
2676 
2677 	// Create framebuffer.
2678 	{
2679 		const VkImageView				attachments[]			=
2680 		{
2681 			*outputImageView,
2682 			isDSFormat ? *dsImageView : *inputImageView
2683 		};
2684 
2685 		const VkFramebufferCreateInfo	framebufferCreateInfo	=
2686 		{
2687 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
2688 			DE_NULL,									// const void*				pNext
2689 			0u,											// VkFramebufferCreateFlags	flags
2690 			*renderPass,								// VkRenderPass				renderPass
2691 			2u,											// uint32_t					attachmentCount
2692 			attachments,								// const VkImageView*		pAttachments
2693 			m_width,									// uint32_t					width
2694 			m_height,									// uint32_t					height
2695 			1u											// uint32_t					layers
2696 		};
2697 
2698 		framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2699 	}
2700 
2701 	// Generate quad vertices
2702 	{
2703 		const tcu::Vec4	lowerLeftVertex		(-1.0f, -1.0f, 0.5f, 1.0f);
2704 		const tcu::Vec4	lowerRightVertex	(1.0f, -1.0f, 0.5f, 1.0f);
2705 		const tcu::Vec4	upperLeftVertex		(-1.0f, 1.0f, 0.5f, 1.0f);
2706 		const tcu::Vec4	upperRightVertex	(1.0f, 1.0f, 0.5f, 1.0f);
2707 
2708 		vertexData.push_back(lowerLeftVertex);
2709 		vertexData.push_back(upperLeftVertex);
2710 		vertexData.push_back(lowerRightVertex);
2711 		vertexData.push_back(upperRightVertex);
2712 	}
2713 
2714 	// Upload vertex data.
2715 	{
2716 		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);
2717 
2718 		const VkBufferCreateInfo	vertexBufferParams	=
2719 		{
2720 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType
2721 			DE_NULL,								//	const void*			pNext
2722 			0u,										//	VkBufferCreateFlags	flags
2723 			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size
2724 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage
2725 			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode
2726 			1u,										//	deUint32			queueFamilyCount
2727 			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices
2728 		};
2729 
2730 		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2731 		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
2732 
2733 		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2734 		flushAlloc(vkd, device, *vertexBufferMemory);
2735 	}
2736 
2737 	beginCommandBuffer(vkd, *commandBuffer);
2738 	vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2739 
2740 	if (!isDSFormat)
2741 		vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2742 
2743 	// Begin render pass.
2744 	{
2745 		VkRect2D					renderArea	=
2746 		{
2747 			{ 0u, 0u },				// VkOffset2D	offset
2748 			{ m_width, m_height }	// VkExtent2D	extent
2749 		};
2750 
2751 		const VkRenderPassBeginInfo	beginInfo	=
2752 		{
2753 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
2754 			DE_NULL,									// const void*			pNext
2755 			*renderPass,								// VkRenderPass			renderPass
2756 			*framebuffer,								// VkFramebuffer		framebuffer
2757 			renderArea,									// VkRect2D				renderArea
2758 			0u,											// uint32_t				clearValueCount
2759 			DE_NULL										// const VkClearValue*	pClearValues
2760 		};
2761 
2762 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2763 	}
2764 
2765 	const VkDeviceSize bindingOffset = 0;
2766 
2767 	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
2768 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2769 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
2770 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2771 
2772 	// Copy results to a buffer.
2773 	if (isDSFormat)
2774 	{
2775 		copyDepthStencilImageToBuffers(vkd, *commandBuffer, *dsImage, *resultBuffer0, *resultBuffer1, tcu::IVec2(m_width, m_height), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
2776 	}
2777 	else
2778 	{
2779 		copyImageToBuffer(vkd, *commandBuffer, *colorImage, *resultBuffer0, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
2780 	}
2781 
2782 	endCommandBuffer(vkd, *commandBuffer);
2783 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
2784 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer0Memory->getMemory(), resultBuffer0Memory->getOffset(), VK_WHOLE_SIZE);
2785 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer1Memory->getMemory(), resultBuffer1Memory->getOffset(), VK_WHOLE_SIZE);
2786 
2787 	// Verify result.
2788 	{
2789 		const tcu::TextureFormat	format		(mapVkFormat(m_format));
2790 		tcu::TextureLevel			reference	(format, m_width, m_height);
2791 
2792 		if (isDSFormat)
2793 		{
2794 			const void* const					ptrDepth				(resultBuffer0Memory->getHostPtr());
2795 			const void* const					ptrStencil				(resultBuffer1Memory->getHostPtr());
2796 			const tcu::ConstPixelBufferAccess	resultDepthAccess		(getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
2797 			const tcu::ConstPixelBufferAccess	resultStencilAccess		(getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
2798 			const PixelBufferAccess				referenceDepthAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
2799 			const PixelBufferAccess				referenceStencilAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
2800 			const float							depthThreshold			(1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x());
2801 
2802 			for (deUint32 x = 0; x < m_width; x++)
2803 				for (deUint32 y = 0; y < m_height; y++)
2804 				{
2805 					float depthValue = ((x / tileSize) % 2 != (y / tileSize) % 2) ? depthInitValues[0] : depthInitValues[1];
2806 					referenceDepthAccess.setPixDepth(depthValue, x, y, 0);
2807 					referenceStencilAccess.setPixel(tcu::IVec4(0.5f < depthValue ? stencilRefValue : 0), x, y, 0);
2808 				}
2809 
2810 			if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
2811 				m_resultCollector.fail("Depth compare failed.");
2812 
2813 			if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
2814 				m_resultCollector.fail("Stencil compare failed.");
2815 		}
2816 		else
2817 		{
2818 			const void* const					ptrResult		(resultBuffer0Memory->getHostPtr());
2819 			const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
2820 			const PixelBufferAccess				referenceAccess	(reference.getAccess());
2821 
2822 			for (deUint32 x = 0; x < m_width; x++)
2823 				for (deUint32 y = 0; y < m_height; y++)
2824 				{
2825 					const tcu::Vec4	initValue	= ((x / tileSize) % 2 != (y / tileSize) % 2) ? colorInitValues[0] : colorInitValues[1];
2826 					const tcu::Vec4	refValue	= tcu::Vec4(initValue.x(), initValue.y(), initValue.x() + initValue.y(), 1.0f);
2827 
2828 					referenceAccess.setPixel(refValue, x, y, 0);
2829 				}
2830 
2831 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
2832 											"Rendered result",						// imageSetName
2833 											"",										// imageSetDesc
2834 											referenceAccess,						// reference
2835 											resultAccess,							// result
2836 											Vec4(0.01f),							// threshold
2837 											tcu::COMPARE_LOG_RESULT))				// logMode
2838 			{
2839 				m_resultCollector.fail("Image compare failed.");
2840 			}
2841 		}
2842 
2843 	}
2844 
2845 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2846 }
2847 
2848 struct SingleAttachmentTestConfig
2849 {
SingleAttachmentTestConfigvkt::__anon675baf4b0111::SingleAttachmentTestConfig2850 		SingleAttachmentTestConfig	(VkFormat		format_,
2851 									 RenderPassType	renderPassType_)
2852 		: format			(format_)
2853 		, renderPassType	(renderPassType_)
2854 	{
2855 	}
2856 
2857 	VkFormat		format;
2858 	RenderPassType	renderPassType;
2859 };
2860 
2861 class SingleAttachmentTestInstance : public TestInstance
2862 {
2863 public:
2864 							SingleAttachmentTestInstance	(Context&					context,
2865 															 SingleAttachmentTestConfig	testConfig);
2866 
2867 							~SingleAttachmentTestInstance	(void);
2868 
2869 	tcu::TestStatus			iterate							(void);
2870 
2871 	template<typename RenderpassSubpass>
2872 	tcu::TestStatus			iterateInternal					(void);
2873 
2874 private:
2875 	const bool				m_extensionSupported;
2876 	const RenderPassType	m_renderPassType;
2877 
2878 	const deUint32			m_width;
2879 	const deUint32			m_height;
2880 	const VkFormat			m_format;
2881 	tcu::ResultCollector	m_resultCollector;
2882 };
2883 
SingleAttachmentTestInstance(Context & context,SingleAttachmentTestConfig testConfig)2884 SingleAttachmentTestInstance::SingleAttachmentTestInstance (Context& context, SingleAttachmentTestConfig testConfig)
2885 	: TestInstance			(context)
2886 	, m_extensionSupported	((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
2887 	, m_renderPassType		(testConfig.renderPassType)
2888 	, m_width				(256u)
2889 	, m_height				(256u)
2890 	, m_format				(testConfig.format)
2891 {
2892 }
2893 
~SingleAttachmentTestInstance(void)2894 SingleAttachmentTestInstance::~SingleAttachmentTestInstance (void)
2895 {
2896 }
2897 
iterate(void)2898 tcu::TestStatus SingleAttachmentTestInstance::iterate (void)
2899 {
2900 	switch (m_renderPassType)
2901 	{
2902 		case RENDERPASS_TYPE_LEGACY:
2903 			return iterateInternal<RenderpassSubpass1>();
2904 		case RENDERPASS_TYPE_RENDERPASS2:
2905 			return iterateInternal<RenderpassSubpass2>();
2906 		default:
2907 			TCU_THROW(InternalError, "Impossible");
2908 	}
2909 }
2910 
2911 template<typename RenderpassSubpass>
iterateInternal(void)2912 tcu::TestStatus SingleAttachmentTestInstance::iterateInternal (void)
2913 {
2914 	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
2915 	const VkDevice										device				= m_context.getDevice();
2916 	const VkQueue										queue				= m_context.getUniversalQueue();
2917 	const deUint32										queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
2918 	const Unique<VkCommandPool>							commandPool			(createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2919 	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2920 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2921 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
2922 	const tcu::Vec4										colorInitValues[2]	= { tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f) };
2923 	const VkExtent3D									imageExtent			= { m_width, m_height, 1u };
2924 	vector<Vec4>										vertexData;
2925 	Move<VkImage>										colorImage;
2926 	Move<VkImage>										resultImage;
2927 	de::MovePtr<Allocation>								colorImageAllocation;
2928 	de::MovePtr<Allocation>								resultImageAllocation;
2929 	Move<VkImageView>									imageViewInput;
2930 	Move<VkImageView>									imageViewResult;
2931 	Move<VkPipelineLayout>								pipelineLayoutInput;
2932 	Move<VkPipelineLayout>								pipelineLayoutImageSampler;
2933 	Move<VkPipeline>									pipelineSolidColor;
2934 	Move<VkPipeline>									pipelineInputAtt;
2935 	Move<VkPipeline>									pipelineImageSampler;
2936 	Move<VkFramebuffer>									framebuffer1;
2937 	Move<VkFramebuffer>									framebuffer0;
2938 	Move<VkRenderPass>									renderPass0;
2939 	Move<VkRenderPass>									renderPass1;
2940 	Move<VkBuffer>										resultBuffer;
2941 	de::MovePtr<Allocation>								resultBufferMemory;
2942 	Move<VkBuffer>										vertexBuffer;
2943 	de::MovePtr<Allocation>								vertexBufferMemory;
2944 	Move<VkSampler>										sampler;
2945 
2946 	// Create image used for both input and output.
2947 	{
2948 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
2949 												  | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
2950 												  | VK_IMAGE_USAGE_SAMPLED_BIT;
2951 
2952 		const VkImageCreateInfo	imageCreateInfo	=
2953 		{
2954 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2955 			DE_NULL,								// const void*				pNext
2956 			0u,										// VkImageCreateFlags		flags
2957 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2958 			m_format,								// VkFormat					format
2959 			imageExtent,							// VkExtent3D				extent
2960 			1u,										// uint32_t					mipLevels
2961 			1u,										// uint32_t					arrayLayers
2962 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2963 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2964 			usage,									// VkImageUsageFlags		usage
2965 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2966 			1u,										// uint32_t					queueFamilyIndexCount
2967 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
2968 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2969 		};
2970 
2971 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2972 
2973 		colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2974 		colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
2975 		VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
2976 	}
2977 
2978 	// Create image used for final result.
2979 	{
2980 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2981 
2982 		const VkImageCreateInfo	imageCreateInfo	=
2983 		{
2984 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2985 			DE_NULL,								// const void*				pNext
2986 			0u,										// VkImageCreateFlags		flags
2987 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2988 			m_format,								// VkFormat					format
2989 			imageExtent,							// VkExtent3D				extent
2990 			1u,										// uint32_t					mipLevels
2991 			1u,										// uint32_t					arrayLayers
2992 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2993 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2994 			usage,									// VkImageUsageFlags		usage
2995 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2996 			1u,										// uint32_t					queueFamilyIndexCount
2997 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
2998 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2999 		};
3000 
3001 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
3002 
3003 		resultImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
3004 		resultImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *resultImage), MemoryRequirement::Any);
3005 		VK_CHECK(vkd.bindImageMemory(device, *resultImage, resultImageAllocation->getMemory(), resultImageAllocation->getOffset()));
3006 	}
3007 
3008 	// Initialize color image. This is expected to be cleared later.
3009 	initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *colorImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height, 32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3010 	// Initialize result image. This will be overwritten later.
3011 	initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *resultImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height, 32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3012 
3013 	// Create image views.
3014 	{
3015 		const VkImageViewCreateInfo imageViewCreateInfo =
3016 		{
3017 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
3018 			DE_NULL,									// const void*				pNext
3019 			0u,											// VkImageViewCreateFlags	flags
3020 			*colorImage,								// VkImage					image
3021 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
3022 			m_format,									// VkFormat					format
3023 			makeComponentMappingRGBA(),					// VkComponentMapping		components
3024 			{											// VkImageSubresourceRange	subresourceRange
3025 				VK_IMAGE_ASPECT_COLOR_BIT,
3026 				0u,
3027 				1u,
3028 				0u,
3029 				1u
3030 			}
3031 		};
3032 
3033 		imageViewInput = createImageView(vkd, device, &imageViewCreateInfo);
3034 	}
3035 
3036 	{
3037 		const VkImageViewCreateInfo imageViewCreateInfo =
3038 		{
3039 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
3040 			DE_NULL,									// const void*				pNext
3041 			0u,											// VkImageViewCreateFlags	flags
3042 			*resultImage,								// VkImage					image
3043 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
3044 			m_format,									// VkFormat					format
3045 			makeComponentMappingRGBA(),					// VkComponentMapping		components
3046 			{											// VkImageSubresourceRange	subresourceRange
3047 				VK_IMAGE_ASPECT_COLOR_BIT,
3048 				0u,
3049 				1u,
3050 				0u,
3051 				1u
3052 			}
3053 		};
3054 
3055 		imageViewResult = createImageView(vkd, device, &imageViewCreateInfo);
3056 	}
3057 
3058 	// Create result buffer.
3059 	{
3060 		resultBuffer		= createBuffer(vkd, device, m_format, m_width, m_height);
3061 		resultBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
3062 	}
3063 
3064 	// Create sampler.
3065 	{
3066 		const VkSamplerCreateInfo samplerInfo =
3067 		{
3068 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType
3069 			DE_NULL,									// const void*				pNext
3070 			0u,											// VkSamplerCreateFlags		flags
3071 			VK_FILTER_NEAREST,							// VkFilter					magFilter
3072 			VK_FILTER_NEAREST,							// VkFilter					minFilter
3073 			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode
3074 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU
3075 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV
3076 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW
3077 			0.0f,										// float					mipLodBias
3078 			VK_FALSE,									// VkBool32					anisotropyEnable
3079 			1.0f,										// float					maxAnisotropy
3080 			VK_FALSE,									// VkBool32					compareEnable
3081 			VK_COMPARE_OP_ALWAYS,						// VkCompareOp				compareOp
3082 			0.0f,										// float					minLod
3083 			0.0f,										// float					maxLod
3084 			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor
3085 			VK_FALSE,									// VkBool32					unnormalizedCoordinates
3086 		};
3087 
3088 		sampler = createSampler(vkd, device, &samplerInfo);
3089 	}
3090 
3091 	// Create descriptor set layouts.
3092 	Unique<VkDescriptorSetLayout>	descriptorSetLayoutInput	(DescriptorSetLayoutBuilder()
3093 			.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
3094 			.build(vkd, device));
3095 
3096 	Unique<VkDescriptorSetLayout>	descriptorSetLayoutImageSampler	(DescriptorSetLayoutBuilder()
3097 			.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
3098 			.build(vkd, device));
3099 
3100 	// Create descriptor pool.
3101 	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
3102 			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
3103 			.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
3104 			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u));
3105 
3106 	// Create desriptor sets.
3107 	Unique<VkDescriptorSet>			descriptorSetInput	(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutInput));
3108 	Unique<VkDescriptorSet>			descriptorSetImageSampler	(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutImageSampler));
3109 
3110 	// Update descriptor set information.
3111 	VkDescriptorImageInfo			descIOAttachment	= makeDescriptorImageInfo(DE_NULL, *imageViewInput, VK_IMAGE_LAYOUT_GENERAL);
3112 	VkDescriptorImageInfo			descImageSampler	= makeDescriptorImageInfo(*sampler, *imageViewInput, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3113 
3114 	DescriptorSetUpdateBuilder()
3115 		.writeSingle(*descriptorSetInput, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descIOAttachment)
3116 		.update(vkd, device);
3117 
3118 	DescriptorSetUpdateBuilder()
3119 		.writeSingle(*descriptorSetImageSampler, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descImageSampler)
3120 		.update(vkd, device);
3121 
3122 	// Create pipeline layouts.
3123 	{
3124 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3125 		{
3126 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
3127 			DE_NULL,										// const void*					pNext
3128 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
3129 			1u,												// deUint32						setLayoutCount
3130 			&descriptorSetLayoutInput.get(),				// const VkDescriptorSetLayout*	pSetLayouts
3131 			0u,												// deUint32						pushConstantRangeCount
3132 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
3133 		};
3134 
3135 		pipelineLayoutInput = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3136 	}
3137 	{
3138 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3139 		{
3140 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
3141 			DE_NULL,										// const void*					pNext
3142 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
3143 			1u,												// deUint32						setLayoutCount
3144 			&descriptorSetLayoutImageSampler.get(),			// const VkDescriptorSetLayout*	pSetLayouts
3145 			0u,												// deUint32						pushConstantRangeCount
3146 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
3147 		};
3148 
3149 		pipelineLayoutImageSampler = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3150 	}
3151 
3152 	// Create render passes.
3153 	{
3154 		vector<Attachment>			attachments;
3155 		vector<AttachmentReference>	colorAttachmentReferences;
3156 
3157 		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
3158 										 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
3159 										 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
3160 
3161 		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
3162 
3163 		const vector<Subpass>			subpasses	(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
3164 													 colorAttachmentReferences, vector<AttachmentReference>(),
3165 													 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
3166 
3167 		renderPass1 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()), m_renderPassType);
3168 	}
3169 	{
3170 		vector<Attachment>			attachments;
3171 		vector<AttachmentReference>	colorAttachmentReferences;
3172 		vector<AttachmentReference>	inputAttachmentReferences;
3173 
3174 		const VkImageAspectFlags	inputAttachmentAspectMask	((m_renderPassType == RENDERPASS_TYPE_RENDERPASS2)
3175 																? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
3176 																: static_cast<VkImageAspectFlags>(0));
3177 
3178 		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
3179 										 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
3180 
3181 		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL));
3182 		inputAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
3183 
3184 		const vector<Subpass>			subpasses		(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
3185 														 colorAttachmentReferences, vector<AttachmentReference>(),
3186 														 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
3187 
3188 		const vector<SubpassDependency>	dependencies	(1, SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3189 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3190 														 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
3191 
3192 		renderPass0 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, dependencies), m_renderPassType);
3193 	}
3194 
3195 	// Create pipelines.
3196 	{
3197 		const Unique<VkShaderModule>				vertexShaderModule				(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
3198 		const Unique<VkShaderModule>				fragmentShaderModuleInputAtt	(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_input_attachment"), 0u));
3199 		const Unique<VkShaderModule>				fragmentShaderModuleSolidColor	(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_solid_color"), 0u));
3200 		const Unique<VkShaderModule>				fragmentShaderModuleSampler		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_combined_image_sampler"), 0u));
3201 
3202 		const VkVertexInputBindingDescription		vertexBinding0					=
3203 		{
3204 			0u,							// deUint32					binding
3205 			sizeof(Vec4),				// deUint32					strideInBytes
3206 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate
3207 		};
3208 
3209 		const VkVertexInputAttributeDescription		attr0							=
3210 		{
3211 			0u,								// deUint32	location
3212 			0u,								// deUint32	binding
3213 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
3214 			0u								// deUint32	offsetInBytes
3215 		};
3216 
3217 		const VkPipelineVertexInputStateCreateInfo	vertexInputState				=
3218 		{
3219 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
3220 			DE_NULL,													// const void*								pNext
3221 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
3222 			1u,															// deUint32									vertexBindingDescriptionCount
3223 			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
3224 			1u,															// deUint32									vertexAttributeDescriptionCount
3225 			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
3226 		};
3227 
3228 		const std::vector<VkViewport>				viewports						(1, makeViewport(tcu::UVec2(m_width, m_height)));
3229 		const std::vector<VkRect2D>					scissors						(1, makeRect2D(tcu::UVec2(m_width, m_height)));
3230 
3231 		const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState	=
3232 		{
3233 			VK_TRUE,								// VkBool32					blendEnable
3234 			VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcColorBlendFactor
3235 			VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstColorBlendFactor
3236 			VK_BLEND_OP_ADD,						// VkBlendOp				colorBlendOp
3237 			VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcAlphaBlendFactor
3238 			VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstAlphaBlendFactor
3239 			VK_BLEND_OP_ADD,						// VkBlendOp				alphaBlendOp
3240 			VK_COLOR_COMPONENT_R_BIT				// VkColorComponentFlags	colorWriteMask
3241 				| VK_COLOR_COMPONENT_G_BIT
3242 				| VK_COLOR_COMPONENT_B_BIT
3243 				| VK_COLOR_COMPONENT_A_BIT
3244 		};
3245 
3246 		const VkPipelineColorBlendStateCreateInfo		colorBlendState				=
3247 		{
3248 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType
3249 			DE_NULL,													// const void*									pNext
3250 			0u,															// VkPipelineColorBlendStateCreateFlags			flags
3251 			VK_FALSE,													// VkBool32										logicOpEnable
3252 			VK_LOGIC_OP_CLEAR,											// VkLogicOp									logicOp
3253 			1u,															// deUint32										attachmentCount
3254 			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments
3255 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4]
3256 		};
3257 
3258 		pipelineSolidColor = makeGraphicsPipeline(vkd,		// const DeviceInterface&							vk
3259 				device,										// const VkDevice									device
3260 				*pipelineLayoutInput,						// const VkPipelineLayout							pipelineLayout
3261 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
3262 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
3263 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
3264 				DE_NULL,									// const VkShaderModule								geometryShaderModule
3265 				*fragmentShaderModuleSolidColor,			// const VkShaderModule								fragmentShaderModule
3266 				*renderPass0,								// const VkRenderPass								renderPass
3267 				viewports,									// const std::vector<VkViewport>&					viewports
3268 				scissors,									// const std::vector<VkRect2D>&						scissors
3269 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
3270 				0u,											// const deUint32									subpass
3271 				0u,											// const deUint32									patchControlPoints
3272 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
3273 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
3274 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
3275 				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
3276 				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
3277 
3278 		pipelineInputAtt = makeGraphicsPipeline(vkd,		// const DeviceInterface&							vk
3279 				device,										// const VkDevice									device
3280 				*pipelineLayoutInput,						// const VkPipelineLayout							pipelineLayout
3281 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
3282 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
3283 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
3284 				DE_NULL,									// const VkShaderModule								geometryShaderModule
3285 				*fragmentShaderModuleInputAtt,				// const VkShaderModule								fragmentShaderModule
3286 				*renderPass0,								// const VkRenderPass								renderPass
3287 				viewports,									// const std::vector<VkViewport>&					viewports
3288 				scissors,									// const std::vector<VkRect2D>&						scissors
3289 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
3290 				0u,											// const deUint32									subpass
3291 				0u,											// const deUint32									patchControlPoints
3292 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
3293 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
3294 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
3295 				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
3296 				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
3297 
3298 		pipelineImageSampler = makeGraphicsPipeline(vkd,	// const DeviceInterface&							vk
3299 				device,										// const VkDevice									device
3300 				*pipelineLayoutImageSampler,				// const VkPipelineLayout							pipelineLayout
3301 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
3302 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
3303 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
3304 				DE_NULL,									// const VkShaderModule								geometryShaderModule
3305 				*fragmentShaderModuleSampler,				// const VkShaderModule								fragmentShaderModule
3306 				*renderPass1,								// const VkRenderPass								renderPass
3307 				viewports,									// const std::vector<VkViewport>&					viewports
3308 				scissors,									// const std::vector<VkRect2D>&						scissors
3309 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
3310 				0u,											// const deUint32									subpass
3311 				0u,											// const deUint32									patchControlPoints
3312 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
3313 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
3314 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
3315 				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
3316 				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
3317 	}
3318 
3319 	// Create framebuffers.
3320 	{
3321 		const VkFramebufferCreateInfo	framebufferCreateInfo	=
3322 		{
3323 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
3324 			DE_NULL,									// const void*				pNext
3325 			0u,											// VkFramebufferCreateFlags	flags
3326 			*renderPass0,								// VkRenderPass				renderPass
3327 			1u,											// uint32_t					attachmentCount
3328 			&imageViewInput.get(),						// const VkImageView*		pAttachments
3329 			256u,										// uint32_t					width
3330 			256u,										// uint32_t					height
3331 			1u											// uint32_t					layers
3332 		};
3333 
3334 		framebuffer0 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3335 	}
3336 	{
3337 		const VkFramebufferCreateInfo	framebufferCreateInfo	=
3338 		{
3339 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
3340 			DE_NULL,									// const void*				pNext
3341 			0u,											// VkFramebufferCreateFlags	flags
3342 			*renderPass1,								// VkRenderPass				renderPass
3343 			1u,											// uint32_t					attachmentCount
3344 			&imageViewResult.get(),						// const VkImageView*		pAttachments
3345 			m_width,									// uint32_t					width
3346 			m_height,									// uint32_t					height
3347 			1u											// uint32_t					layers
3348 		};
3349 
3350 		framebuffer1 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3351 	}
3352 
3353 	// Generate quad vertices.
3354 	{
3355 		const tcu::Vec4	lowerLeftVertex		(-1.0f, -1.0f, 0.5f, 1.0f);
3356 		const tcu::Vec4	lowerRightVertex	(1.0f, -1.0f, 0.5f, 1.0f);
3357 		const tcu::Vec4	upperLeftVertex		(-1.0f, 1.0f, 0.5f, 1.0f);
3358 		const tcu::Vec4	upperRightVertex	(1.0f, 1.0f, 0.5f, 1.0f);
3359 
3360 		vertexData.push_back(lowerLeftVertex);
3361 		vertexData.push_back(upperLeftVertex);
3362 		vertexData.push_back(lowerRightVertex);
3363 		vertexData.push_back(upperRightVertex);
3364 	}
3365 
3366 	// Upload vertex data.
3367 	{
3368 		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);
3369 
3370 		const VkBufferCreateInfo	vertexBufferParams	=
3371 		{
3372 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType
3373 			DE_NULL,								//	const void*			pNext
3374 			0u,										//	VkBufferCreateFlags	flags
3375 			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size
3376 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage
3377 			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode
3378 			1u,										//	deUint32			queueFamilyCount
3379 			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices
3380 		};
3381 
3382 		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
3383 		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
3384 
3385 		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
3386 		flushAlloc(vkd, device, *vertexBufferMemory);
3387 	}
3388 
3389 	beginCommandBuffer(vkd, *commandBuffer);
3390 
3391 	// Begin render pass.
3392 	{
3393 		const VkRect2D				renderArea	=
3394 		{
3395 			{ 0u, 0u },				// VkOffset2D	offset
3396 			{ m_width, m_height }	// VkExtent2D	extent
3397 		};
3398 
3399 		const VkClearValue			clearValue	= makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3400 
3401 		const VkRenderPassBeginInfo	beginInfo	=
3402 		{
3403 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
3404 			DE_NULL,									// const void*			pNext
3405 			*renderPass0,								// VkRenderPass			renderPass
3406 			*framebuffer0,								// VkFramebuffer		framebuffer
3407 			renderArea,									// VkRect2D				renderArea
3408 			1u,											// uint32_t				clearValueCount
3409 			&clearValue									// const VkClearValue*	pClearValues
3410 		};
3411 
3412 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3413 	}
3414 
3415 	// Bind pipeline.
3416 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineSolidColor);
3417 
3418 	// Bind vertex buffer.
3419 	const VkDeviceSize bindingOffset = 0;
3420 	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3421 
3422 	// Bind descriptor set.
3423 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);
3424 
3425 	// Draw solid color.
3426 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3427 
3428 	// Bind pipeline.
3429 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineInputAtt);
3430 
3431 	// Bind descriptor set.
3432 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);
3433 
3434 	// Pipeline barrier to handle self dependency.
3435 	{
3436 		const VkImageMemoryBarrier imageBarrier =
3437 		{
3438 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
3439 			DE_NULL,										// const void*				pNext
3440 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
3441 			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// VkAccessFlags			dstAccessMask
3442 			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			oldLayout
3443 			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			newLayout
3444 			VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
3445 			VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
3446 			*colorImage,									// VkImage					image
3447 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
3448 		};
3449 
3450 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
3451 	}
3452 
3453 	// Draw. Adds (0.1, 0.2, 0.0, 0.0) to the previous result.
3454 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3455 
3456 	// End render pass.
3457 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3458 
3459 	// Pipeline barrier.
3460 	{
3461 		const VkImageMemoryBarrier imageBarriers[] =
3462 		{
3463 			{
3464 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
3465 				DE_NULL,										// const void*				pNext
3466 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
3467 				| VK_ACCESS_TRANSFER_WRITE_BIT
3468 				| VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags			srcAccessMask
3469 				VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask
3470 				VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			oldLayout
3471 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// VkImageLayout			newLayout
3472 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
3473 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
3474 				*colorImage,									// VkImage					image
3475 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
3476 			},
3477 			{
3478 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
3479 				DE_NULL,										// const void*				pNext
3480 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
3481 				VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
3482 				| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask
3483 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			oldLayout
3484 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout
3485 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
3486 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
3487 				*resultImage,									// VkImage					image
3488 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
3489 			}
3490 		};
3491 
3492 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
3493 	}
3494 
3495 	// Begin render pass.
3496 	{
3497 		const VkRect2D				renderArea	=
3498 		{
3499 			{ 0, 0 },	            // VkOffset2D	offset
3500 			{ m_width, m_height }	// VkExtent2D	extent
3501 		};
3502 
3503 		const VkRenderPassBeginInfo	beginInfo	=
3504 		{
3505 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
3506 			DE_NULL,									// const void*			pNext
3507 			*renderPass1,								// VkRenderPass			renderPass
3508 			*framebuffer1,								// VkFramebuffer		framebuffer
3509 			renderArea,									// VkRect2D				renderArea
3510 			0u,											// uint32_t				clearValueCount
3511 			DE_NULL										// const VkClearValue*	pClearValues
3512 		};
3513 
3514 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3515 	}
3516 
3517 	// Bind pipeline.
3518 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineImageSampler);
3519 
3520 	// Bind descriptor set.
3521 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutImageSampler, 0u, 1u, &*descriptorSetImageSampler, 0u, DE_NULL);
3522 
3523 	// Draw. Samples the previous results and adds (0.1, 0.2, 0.0, 0.0).
3524 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3525 
3526 	// End render pass.
3527 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3528 
3529 	// Copy results to a buffer.
3530 	copyImageToBuffer(vkd, *commandBuffer, *resultImage, *resultBuffer, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3531 
3532 	endCommandBuffer(vkd, *commandBuffer);
3533 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
3534 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(), resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
3535 
3536 	// Verify results.
3537 	{
3538 		const tcu::TextureFormat			format			(mapVkFormat(m_format));
3539 		tcu::TextureLevel					reference		(format, m_width, m_height);
3540 		const void* const					ptrResult		(resultBufferMemory->getHostPtr());
3541 		const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
3542 		const PixelBufferAccess				referenceAccess	(reference.getAccess());
3543 
3544 		for (deUint32 x = 0; x < m_width; x++)
3545 			for (deUint32 y = 0; y < m_height; y++)
3546 			{
3547 				referenceAccess.setPixel(tcu::Vec4(0.3f, 0.6f, 0.0f, 1.0f), x, y, 0);
3548 			}
3549 
3550 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
3551 										"Rendered result",						// imageSetName
3552 										"",										// imageSetDesc
3553 										referenceAccess,						// reference
3554 										resultAccess,							// result
3555 										Vec4(0.05f),							// threshold
3556 										tcu::COMPARE_LOG_RESULT))				// logMode
3557 		{
3558 			m_resultCollector.fail("Image compare failed.");
3559 		}
3560 	}
3561 
3562 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
3563 }
3564 
3565 // Shader programs for testing dependencies between render pass instances
3566 struct ExternalPrograms
3567 {
initvkt::__anon675baf4b0111::ExternalPrograms3568 	void init (vk::SourceCollections& dst, ExternalTestConfig testConfig) const
3569 	{
3570 		for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
3571 		{
3572 			dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
3573 				"#version 450\n"
3574 				"layout(location = 0) out highp vec2 vtxTexCoords;\n"
3575 				"highp float;\n"
3576 				"void main (void)\n"
3577 				"{\n"
3578 				"    vec4 position;"
3579 				"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3580 				"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3581 				"    gl_Position = position;\n"
3582 				"	vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
3583 				"}\n");
3584 
3585 			// First pass renders four quads of different color
3586 			if (renderPassNdx == 0)
3587 			{
3588 				dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3589 					"#version 450\n"
3590 					"layout(location = 0) in highp vec2 vtxTexCoords;\n"
3591 					"layout(location = 0) out highp vec4 o_color;\n"
3592 					"void main (void)\n"
3593 					"{\n"
3594 					"    if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3595 					"        o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
3596 					"    else if (gl_FragCoord.x > " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3597 					"        o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3598 					"    else if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3599 					"        o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
3600 					"    else\n"
3601 					"        o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
3602 					""
3603 					"}\n");
3604 			}
3605 			else
3606 			{
3607 				if (renderPassNdx % 2 == 0)
3608 				{
3609 					// Blur previous pass horizontally
3610 					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3611 						"#version 450\n"
3612 						"layout(binding = 0) uniform sampler2D previousPass;\n"
3613 						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
3614 						"layout(location = 0) out highp vec4 o_color;\n"
3615 						"void main (void)\n"
3616 						"{\n"
3617 						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
3618 						"    vec2 minCoord = vec2(0.0, 0.0);\n"
3619 						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
3620 						"    vec4 blurColor = vec4(0.0);\n"
3621 						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
3622 						"    {\n"
3623 						"        vec2 sampleCoord = vec2((vtxTexCoords.x - " + de::toString(testConfig.blurKernel / 2) + " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
3624 						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3625 						"    }\n"
3626 						"    o_color = blurColor;\n"
3627 						"}\n");
3628 				}
3629 				else
3630 				{
3631 					// Blur previous pass vertically
3632 					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3633 						"#version 450\n"
3634 						"layout(binding = 0) uniform highp sampler2D previousPass;\n"
3635 						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
3636 						"layout(location = 0) out highp vec4 o_color;\n"
3637 						"void main (void)\n"
3638 						"{\n"
3639 						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
3640 						"    vec2 minCoord = vec2(0.0, 0.0);\n"
3641 						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
3642 						"    vec4 blurColor = vec4(0.0);\n"
3643 						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
3644 						"    {\n"
3645 						"        vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " + de::toString(testConfig.blurKernel / 2) + " * step.y) + step.y * sampleNdx);\n"
3646 						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3647 						"    }\n"
3648 						"    o_color = blurColor;\n"
3649 						"}\n");
3650 				}
3651 			}
3652 		}
3653 	}
3654 };
3655 
3656 // Shader programs for testing dependencies between subpasses
3657 struct SubpassPrograms
3658 {
initvkt::__anon675baf4b0111::SubpassPrograms3659 	void init (vk::SourceCollections& dst, SubpassTestConfig testConfig) const
3660 	{
3661 		size_t subpassCount = testConfig.renderPass.getSubpasses().size();
3662 
3663 		for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
3664 		{
3665 			if (subpassNdx == 0)
3666 			{
3667 				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3668 				"#version 450\n"
3669 				"highp float;\n"
3670 				"layout(location = 0) in highp vec4 position;\n"
3671 				"void main (void)\n"
3672 				"{\n"
3673 				"    gl_Position = position;\n"
3674 				"}\n");
3675 			}
3676 			else
3677 			{
3678 				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3679 					"#version 450\n"
3680 					"highp float;\n"
3681 					"void main (void)\n"
3682 					"{\n"
3683 					"    vec4 position;"
3684 					"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3685 					"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3686 					"    gl_Position = position;\n"
3687 					"}\n");
3688 			}
3689 
3690 			if (isDepthStencilFormat(testConfig.format))
3691 			{
3692 				if (subpassNdx == 0)
3693 				{
3694 					// Empty fragment shader: Fragment depth unmodified.
3695 					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
3696 						"#version 450\n"
3697 						"void main (void)\n"
3698 						"{\n"
3699 						"}\n");
3700 				}
3701 				else
3702 				{
3703 					// Use fragment depth from previous depth rendering result.
3704 					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
3705 						"#version 450\n"
3706 						"layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
3707 						"void main (void)\n"
3708 						"{\n"
3709 						"    float inputDepth = subpassLoad(depthStencil).x;\n"
3710 						"    gl_FragDepth = inputDepth - 0.02;\n"
3711 						"}\n");
3712 				}
3713 			}
3714 			else
3715 				DE_FATAL("Unimplemented");
3716 		}
3717 	}
3718 };
3719 
3720 // Shader programs for testing backwards subpass self dependency from geometry stage to indirect draw
3721 struct SubpassSelfDependencyBackwardsPrograms
3722 {
initvkt::__anon675baf4b0111::SubpassSelfDependencyBackwardsPrograms3723 	void init (vk::SourceCollections& dst, SubpassSelfDependencyBackwardsTestConfig testConfig) const
3724 	{
3725 		DE_UNREF(testConfig);
3726 
3727 		dst.glslSources.add("vert") << glu::VertexSource(
3728 				"#version 450\n"
3729 				"layout(location = 0) in highp vec4 position;\n"
3730 				"out gl_PerVertex {\n"
3731 				"    vec4 gl_Position;\n"
3732 				"};\n"
3733 				"void main (void)\n"
3734 				"{\n"
3735 				"    gl_Position = position;\n"
3736 				"}\n");
3737 
3738 		dst.glslSources.add("geom") << glu::GeometrySource(
3739 				"#version 450\n"
3740 				"layout(points) in;\n"
3741 				"layout(triangle_strip, max_vertices = 4) out;\n"
3742 				"\n"
3743 				"in gl_PerVertex {\n"
3744 				"    vec4 gl_Position;\n"
3745 				"} gl_in[];\n"
3746 				"\n"
3747 				"out gl_PerVertex {\n"
3748 				"    vec4 gl_Position;\n"
3749 				"};\n"
3750 				"layout (binding = 0) buffer IndirectBuffer\n"
3751 				"{\n"
3752 				"    uint vertexCount;\n"
3753 				"    uint instanceCount;\n"
3754 				"    uint firstVertex;\n"
3755 				"    uint firstInstance;\n"
3756 				"} indirectBuffer;\n"
3757 				"\n"
3758 				"void main (void) {\n"
3759 				"    vec4 p = gl_in[0].gl_Position;\n"
3760 				"    float offset = 0.03f;\n"
3761 				"    gl_Position = p + vec4(-offset, offset, 0, 0);\n"
3762 				"    EmitVertex();\n"
3763 				"    gl_Position = p + vec4(-offset, -offset, 0, 0);\n"
3764 				"    EmitVertex();\n"
3765 				"    gl_Position = p + vec4(offset, offset, 0, 0);\n"
3766 				"    EmitVertex();\n"
3767 				"    gl_Position = p + vec4(offset, -offset, 0, 0);\n"
3768 				"    EmitVertex();\n"
3769 				"    EndPrimitive();\n"
3770 				"    indirectBuffer.vertexCount = 64;\n"
3771 				"    indirectBuffer.instanceCount = 1;\n"
3772 				"    indirectBuffer.firstVertex = 64;\n"
3773 				"    indirectBuffer.firstInstance = 0;\n"
3774 				"}\n");
3775 
3776 		dst.glslSources.add("frag") << glu::FragmentSource(
3777 				"#version 450\n"
3778 				"layout(location = 0) out highp vec4 fragColor;\n"
3779 				"void main (void)\n"
3780 				"{\n"
3781 				"    fragColor = vec4(1, 0, 0, 1);\n"
3782 				"}\n");
3783 	}
3784 };
3785 
3786 struct SeparateChannelsPrograms
3787 {
initvkt::__anon675baf4b0111::SeparateChannelsPrograms3788 	void init (vk::SourceCollections& dst, SeparateChannelsTestConfig testConfig) const
3789 	{
3790 		dst.glslSources.add("vert") << glu::VertexSource(
3791 				"#version 450\n"
3792 				"layout(location = 0) in highp vec4 position;\n"
3793 				"void main (void)\n"
3794 				"{\n"
3795 				"    gl_Position = position;\n"
3796 				"}\n");
3797 
3798 		if (isDepthStencilFormat(testConfig.format))
3799 		{
3800 			dst.glslSources.add("frag") << glu::FragmentSource(
3801 					"#version 450\n"
3802 					"layout(location = 0) out highp vec4 fragColor;\n"
3803 					"void main (void)\n"
3804 					"{\n"
3805 					"    fragColor = vec4(1);\n"
3806 					"}\n");
3807 		}
3808 		else
3809 		{
3810 			dst.glslSources.add("frag") << glu::FragmentSource(
3811 					"#version 450\n"
3812 					"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
3813 					"layout(location = 0) out highp vec4 fragColor;\n"
3814 					"void main (void)\n"
3815 					"{\n"
3816 					"    vec4 inputColor = subpassLoad(inputAtt);\n"
3817 					"    fragColor = vec4(1, 1, inputColor.r + inputColor.g, 1);\n"
3818 					"}\n");
3819 		}
3820 	}
3821 };
3822 
3823 struct SingleAttachmentPrograms
3824 {
initvkt::__anon675baf4b0111::SingleAttachmentPrograms3825 	void init (vk::SourceCollections& dst, SingleAttachmentTestConfig testConfig) const
3826 	{
3827 		DE_UNREF(testConfig);
3828 
3829 		dst.glslSources.add("vert") << glu::VertexSource(
3830 				"#version 450\n"
3831 				"layout(location = 0) in highp vec4 position;\n"
3832 				"void main (void)\n"
3833 				"{\n"
3834 				"    gl_Position = position;\n"
3835 				"}\n");
3836 
3837 		dst.glslSources.add("frag_solid_color") << glu::FragmentSource(
3838 				"#version 450\n"
3839 				"layout(location = 0) out highp vec4 fragColor;\n"
3840 				"void main (void)\n"
3841 				"{\n"
3842 				"    fragColor = vec4(0.1, 0.2, 0.0, 1.0);\n"
3843 				"}\n");
3844 
3845 		dst.glslSources.add("frag_input_attachment") << glu::FragmentSource(
3846 				"#version 450\n"
3847 				"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
3848 				"layout(location = 0) out highp vec4 fragColor;\n"
3849 				"void main (void)\n"
3850 				"{\n"
3851 				"    vec4 inputColor = subpassLoad(inputAtt);\n"
3852 				"    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
3853 				"}\n");
3854 
3855 		dst.glslSources.add("frag_combined_image_sampler") << glu::FragmentSource(
3856 				"#version 450\n"
3857 				"layout(set = 0, binding = 0) uniform highp sampler2D tex;\n"
3858 				"layout(location = 0) out highp vec4 fragColor;\n"
3859 				"void main (void)\n"
3860 				"{\n"
3861 				"    vec2 uv = vec2(gl_FragCoord) / 255.0;\n"
3862 				"    vec4 inputColor = texture(tex, uv);\n"
3863 				"    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
3864 				"}\n");
3865 	}
3866 };
3867 
formatToName(VkFormat format)3868 std::string formatToName (VkFormat format)
3869 {
3870 	const std::string	formatStr	= de::toString(format);
3871 	const std::string	prefix		= "VK_FORMAT_";
3872 
3873 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
3874 
3875 	return de::toLower(formatStr.substr(prefix.length()));
3876 }
3877 
initTests(tcu::TestCaseGroup * group,const RenderPassType renderPassType)3878 void initTests (tcu::TestCaseGroup* group, const RenderPassType renderPassType)
3879 {
3880 	tcu::TestContext& testCtx(group->getTestContext());
3881 
3882 	// Test external subpass dependencies
3883 	{
3884 		const deUint32	renderPassCounts[]	= { 2u, 3u, 5u};
3885 
3886 		const UVec2		renderSizes[]		=
3887 		{
3888 			UVec2(64, 64),
3889 			UVec2(128, 128),
3890 			UVec2(512, 512)
3891 		};
3892 
3893 		de::MovePtr<tcu::TestCaseGroup>	externalGroup	(new tcu::TestCaseGroup(testCtx, "external_subpass", "external_subpass"));
3894 
3895 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
3896 		{
3897 			string groupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
3898 			de::MovePtr<tcu::TestCaseGroup> renderSizeGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
3899 
3900 			for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
3901 			{
3902 				vector<RenderPass>	renderPasses;
3903 
3904 				for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
3905 				{
3906 					vector<Attachment>			attachments;
3907 					vector<AttachmentReference>	colorAttachmentReferences;
3908 
3909 					const VkFormat				format				(VK_FORMAT_R8G8B8A8_UNORM);
3910 					const VkSampleCountFlagBits	sampleCount			(VK_SAMPLE_COUNT_1_BIT);
3911 					const VkAttachmentLoadOp	loadOp				(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3912 					const VkAttachmentStoreOp	storeOp				(VK_ATTACHMENT_STORE_OP_STORE);
3913 					const VkAttachmentLoadOp	stencilLoadOp		(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3914 					const VkAttachmentStoreOp	stencilStoreOp		(VK_ATTACHMENT_STORE_OP_DONT_CARE);
3915 					const VkImageLayout			initialLayout		(VK_IMAGE_LAYOUT_UNDEFINED);
3916 					const VkImageLayout			finalLayout			(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3917 					const VkImageLayout			subpassLayout		(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3918 
3919 					attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
3920 					colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
3921 
3922 					const VkImageLayout			depthStencilLayout	(VK_IMAGE_LAYOUT_GENERAL);
3923 					const vector<Subpass>		subpasses			(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(),
3924 																		AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
3925 					vector<SubpassDependency>	deps;
3926 
3927 					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
3928 													 0,															// deUint32				dstPass
3929 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	srcStageMask
3930 													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags	dstStageMask
3931 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		srcAccessMask
3932 													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		dstAccessMask
3933 													 0));														// VkDependencyFlags	flags
3934 
3935 					deps.push_back(SubpassDependency(0,															// deUint32				srcPass
3936 													 VK_SUBPASS_EXTERNAL,										// deUint32				dstPass
3937 													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags	srcStageMask
3938 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	dstStageMask
3939 													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		srcAccessMask
3940 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		dstAccessMask
3941 													 0));														// VkDependencyFlags	flags
3942 
3943 					RenderPass					renderPass			(attachments, subpasses, deps);
3944 
3945 					renderPasses.push_back(renderPass);
3946 				}
3947 
3948 				const deUint32		blurKernel	(12u);
3949 				string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
3950 				ExternalTestConfig	testConfig
3951 				{
3952 					VK_FORMAT_R8G8B8A8_UNORM,
3953 					renderSizes[renderSizeNdx],
3954 					renderPasses,
3955 					renderPassType,
3956 					SYNCHRONIZATION_TYPE_LEGACY,
3957 					blurKernel
3958 				};
3959 
3960 				renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
3961 				if (renderPassType == RENDERPASS_TYPE_RENDERPASS2)
3962 				{
3963 					testName += "_sync_2";
3964 					testConfig.synchronizationType = SYNCHRONIZATION_TYPE_SYNCHRONIZATION2;
3965 					renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
3966 				}
3967 			}
3968 
3969 			externalGroup->addChild(renderSizeGroup.release());
3970 		}
3971 
3972 		group->addChild(externalGroup.release());
3973 	}
3974 
3975 	// Test implicit subpass dependencies
3976 	{
3977 		const deUint32					renderPassCounts[]		= { 2u, 3u, 5u };
3978 
3979 		de::MovePtr<tcu::TestCaseGroup>	implicitGroup			(new tcu::TestCaseGroup(testCtx, "implicit_dependencies", "implicit_dependencies"));
3980 
3981 		for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
3982 		{
3983 			vector<RenderPass> renderPasses;
3984 
3985 			for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
3986 			{
3987 				vector<Attachment>			attachments;
3988 				vector<AttachmentReference>	colorAttachmentReferences;
3989 
3990 				const VkFormat				format					(VK_FORMAT_R8G8B8A8_UNORM);
3991 				const VkSampleCountFlagBits	sampleCount				(VK_SAMPLE_COUNT_1_BIT);
3992 				const VkAttachmentLoadOp	loadOp					(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3993 				const VkAttachmentStoreOp	storeOp					(VK_ATTACHMENT_STORE_OP_STORE);
3994 				const VkAttachmentLoadOp	stencilLoadOp			(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3995 				const VkAttachmentStoreOp	stencilStoreOp			(VK_ATTACHMENT_STORE_OP_DONT_CARE);
3996 				const VkImageLayout			initialLayout			(VK_IMAGE_LAYOUT_UNDEFINED);
3997 				const VkImageLayout			finalLayout				(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3998 				const VkImageLayout			subpassLayout			(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3999 
4000 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
4001 				colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
4002 
4003 				const VkImageLayout			depthStencilLayout		(VK_IMAGE_LAYOUT_GENERAL);
4004 				const vector<Subpass>		subpasses				(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
4005 				vector<SubpassDependency>	deps;
4006 
4007 				// The first render pass lets the implementation add all subpass dependencies implicitly.
4008 				// On the following passes only the dependency from external to first subpass is defined as
4009 				// we need to make sure we have the image ready from previous render pass. In this case
4010 				// the dependency from subpass 0 to external is added implicitly by the implementation.
4011 				if (renderPassNdx > 0)
4012 				{
4013 					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
4014 													 0,															// deUint32				dstPass
4015 													 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,				// VkPipelineStageFlags	srcStageMask
4016 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,						// VkPipelineStageFlags	dstStageMask
4017 													 0,						// VkAccessFlags		srcAccessMask
4018 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,	// VkAccessFlags		dstAccessMask
4019 													 0));														// VkDependencyFlags	flags
4020 				}
4021 
4022 				RenderPass					renderPass				(attachments, subpasses, deps);
4023 
4024 				renderPasses.push_back(renderPass);
4025 			}
4026 
4027 			const deUint32				blurKernel	(12u);
4028 			const ExternalTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, renderPassType, SYNCHRONIZATION_TYPE_LEGACY, blurKernel);
4029 			const string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
4030 
4031 			implicitGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
4032 		}
4033 
4034 		group->addChild(implicitGroup.release());
4035 	}
4036 
4037 	// Test late fragment operations using depth_stencil attachments in multipass rendering
4038 	{
4039 		const UVec2		renderSizes[]		=
4040 		{
4041 			UVec2(32, 32),
4042 			UVec2(64, 64),
4043 			UVec2(128, 128)
4044 		};
4045 
4046 		const deUint32	subpassCounts[]		= { 2u, 3u, 5u };
4047 
4048 		// Implementations must support at least one of the following formats
4049 		// for depth_stencil attachments
4050 		const VkFormat formats[]			=
4051 		{
4052 			VK_FORMAT_D24_UNORM_S8_UINT,
4053 			VK_FORMAT_D32_SFLOAT_S8_UINT
4054 		};
4055 
4056 		de::MovePtr<tcu::TestCaseGroup>	lateFragmentTestsGroup (new tcu::TestCaseGroup(testCtx, "late_fragment_tests", "wait for late fragment tests"));
4057 
4058 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4059 		{
4060 			string							renderSizeGroupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
4061 			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup		(new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str(), renderSizeGroupName.c_str()));
4062 
4063 			for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
4064 			{
4065 				string							subpassGroupName	("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
4066 				de::MovePtr<tcu::TestCaseGroup>	subpassCountGroup	(new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str(), subpassGroupName.c_str()));
4067 
4068 				for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
4069 				{
4070 					const deUint32				subpassCount	(subpassCounts[subpassCountNdx]);
4071 					const deUint32				attachmentCount	(subpassCount);
4072 					vector<Subpass>				subpasses;
4073 					vector<Attachment>			attachments;
4074 					vector<SubpassDependency>	deps;
4075 
4076 					// Attachments
4077 					for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4078 					{
4079 						const VkFormat				format						(formats[formatNdx]);
4080 						const VkSampleCountFlagBits	sampleCount					(VK_SAMPLE_COUNT_1_BIT);
4081 						const VkAttachmentLoadOp	loadOp						(VK_ATTACHMENT_LOAD_OP_CLEAR);
4082 						const VkAttachmentStoreOp	storeOp						((attachmentNdx == attachmentCount - 1)
4083 																					? VK_ATTACHMENT_STORE_OP_STORE
4084 																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
4085 						const VkAttachmentLoadOp	stencilLoadOp				(VK_ATTACHMENT_LOAD_OP_CLEAR);
4086 						const VkAttachmentStoreOp	stencilStoreOp				((attachmentNdx == attachmentCount - 1)
4087 																					? VK_ATTACHMENT_STORE_OP_STORE
4088 																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
4089 						const VkImageLayout			initialLayout				(VK_IMAGE_LAYOUT_UNDEFINED);
4090 						const VkImageLayout			finalLayout					(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
4091 
4092 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
4093 					}
4094 
4095 					// Subpasses
4096 					for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
4097 					{
4098 						vector<AttachmentReference>	inputAttachmentReferences;
4099 						const VkImageAspectFlags	inputAttachmentAspectMask	((renderPassType == RENDERPASS_TYPE_RENDERPASS2)
4100 																					? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)
4101 																					: static_cast<VkImageAspectFlags>(0));
4102 
4103 						// Input attachment references
4104 						if (subpassNdx > 0)
4105 							inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask));
4106 
4107 						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences, vector<AttachmentReference>(), vector<AttachmentReference>(), AttachmentReference((deUint32)subpassNdx, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<deUint32>()));
4108 
4109 						// Subpass dependencies from current subpass to previous subpass.
4110 						// Subpasses will wait for the late fragment operations before reading the contents
4111 						// of previous subpass.
4112 						if (subpassNdx > 0)
4113 						{
4114 							deps.push_back(SubpassDependency((deUint32)subpassNdx - 1,							// deUint32				srcPass
4115 															 (deUint32)subpassNdx,								// deUint32				dstPass
4116 															 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags	srcStageMask
4117 															 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4118 																| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,	// VkPipelineStageFlags	dstStageMask
4119 															 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags		srcAccessMask
4120 															 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags		dstAccessMask
4121 															 VK_DEPENDENCY_BY_REGION_BIT));						// VkDependencyFlags	flags
4122 						}
4123 					}
4124 					deps.push_back(SubpassDependency((deUint32)subpassCount - 1,								// deUint32				srcPass
4125 													 VK_SUBPASS_EXTERNAL,										// deUint32				dstPass
4126 													 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,					// VkPipelineStageFlags	srcStageMask
4127 													 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,					// VkPipelineStageFlags	dstStageMask
4128 													 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,				// VkAccessFlags		srcAccessMask
4129 													 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags		dstAccessMask
4130 													 VK_DEPENDENCY_BY_REGION_BIT));								// VkDependencyFlags	flags
4131 
4132 					const RenderPass		renderPass	(attachments, subpasses, deps);
4133 					const SubpassTestConfig	testConfig	(formats[formatNdx], renderSizes[renderSizeNdx], renderPass, renderPassType);
4134 					const string			format		(formatToName(formats[formatNdx]).c_str());
4135 
4136 					subpassCountGroup->addChild(new InstanceFactory1<SubpassDependencyTestInstance, SubpassTestConfig, SubpassPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, format, format, testConfig));
4137 				}
4138 
4139 				renderSizeGroup->addChild(subpassCountGroup.release());
4140 			}
4141 
4142 			lateFragmentTestsGroup->addChild(renderSizeGroup.release());
4143 		}
4144 
4145 		group->addChild(lateFragmentTestsGroup.release());
4146 	}
4147 
4148 	// Test subpass self dependency
4149 	{
4150 		const UVec2		renderSizes[]		=
4151 		{
4152 			UVec2(64, 64),
4153 			UVec2(128, 128),
4154 			UVec2(512, 512)
4155 		};
4156 
4157 		de::MovePtr<tcu::TestCaseGroup>	selfDependencyGroup	(new tcu::TestCaseGroup(testCtx, "self_dependency", "self_dependency"));
4158 
4159 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4160 		{
4161 			string groupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
4162 			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
4163 
4164 			const SubpassSelfDependencyBackwardsTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], renderPassType);
4165 			renderSizeGroup->addChild(new InstanceFactory1<SubpassSelfDependencyBackwardsTestInstance, SubpassSelfDependencyBackwardsTestConfig, SubpassSelfDependencyBackwardsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "geometry_to_indirectdraw", "", testConfig));
4166 
4167 			selfDependencyGroup->addChild(renderSizeGroup.release());
4168 		}
4169 
4170 		group->addChild(selfDependencyGroup.release());
4171 	}
4172 
4173 	// Test using a single attachment with reads and writes using separate channels. This should work without subpass self-dependency.
4174 	{
4175 		de::MovePtr<tcu::TestCaseGroup>	separateChannelsGroup	(new tcu::TestCaseGroup(testCtx, "separate_channels", "separate_channels"));
4176 
4177 		struct TestConfig
4178 		{
4179 			string		name;
4180 			VkFormat	format;
4181 		} configs[] =
4182 		{
4183 			{	"r8g8b8a8_unorm",		VK_FORMAT_R8G8B8A8_UNORM		},
4184 			{	"r16g16b16a16_sfloat",	VK_FORMAT_R16G16B16A16_SFLOAT	},
4185 			{	"d24_unorm_s8_uint",	VK_FORMAT_D24_UNORM_S8_UINT		},
4186 			{	"d32_sfloat_s8_uint",	VK_FORMAT_D32_SFLOAT_S8_UINT	}
4187 		};
4188 
4189 		for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4190 		{
4191 			const SeparateChannelsTestConfig testConfig(configs[configIdx].format, renderPassType);
4192 
4193 			separateChannelsGroup->addChild(new InstanceFactory1<SeparateChannelsTestInstance, SeparateChannelsTestConfig, SeparateChannelsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
4194 		}
4195 
4196 		group->addChild(separateChannelsGroup.release());
4197 	}
4198 
4199 	// Test using a single attachment for input and output.
4200 	{
4201 		de::MovePtr<tcu::TestCaseGroup>	singleAttachmentGroup	(new tcu::TestCaseGroup(testCtx, "single_attachment", "single_attachment"));
4202 
4203 		struct TestConfig
4204 		{
4205 			string		name;
4206 			VkFormat	format;
4207 		} configs[] =
4208 		{
4209 			{	"r8g8b8a8_unorm",			VK_FORMAT_R8G8B8A8_UNORM		},
4210 			{	"b8g8r8a8_unorm",			VK_FORMAT_B8G8R8A8_UNORM		},
4211 			{	"r16g16b16a16_sfloat",		VK_FORMAT_R16G16B16A16_SFLOAT	},
4212 			{	"r5g6b5_unorm_pack16",		VK_FORMAT_R5G6B5_UNORM_PACK16	},
4213 			{	"a1r5g5b5_unorm_pack16",	VK_FORMAT_A1R5G5B5_UNORM_PACK16	}
4214 		};
4215 
4216 		for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4217 		{
4218 			const SingleAttachmentTestConfig testConfig(configs[configIdx].format, renderPassType);
4219 
4220 			singleAttachmentGroup->addChild(new InstanceFactory1<SingleAttachmentTestInstance, SingleAttachmentTestConfig, SingleAttachmentPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
4221 		}
4222 
4223 		group->addChild(singleAttachmentGroup.release());
4224 	}
4225 }
4226 } // anonymous
4227 
createRenderPassSubpassDependencyTests(tcu::TestContext & testCtx)4228 tcu::TestCaseGroup* createRenderPassSubpassDependencyTests (tcu::TestContext& testCtx)
4229 {
4230 	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_LEGACY);
4231 }
4232 
createRenderPass2SubpassDependencyTests(tcu::TestContext & testCtx)4233 tcu::TestCaseGroup* createRenderPass2SubpassDependencyTests (tcu::TestContext& testCtx)
4234 {
4235 	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
4236 }
4237 } // vkt
4238